3.1.1 Drawing Contour with the help of graphics card GPU

3.1.1 Drawing Contour with the help of graphics card GPU

How to draw a scalar field? We often draw Contour graphics (contours) such as the commercial software Tecplot, or the contour in the Python-based open source software package matplotlib. Here introduces the use of graphics card GPU to draw Contour, the use of flash's stage3D technology, currently flash is out of date, but its reference significance is still there.

What is a graphics card? The author is superficial. 1. I simply think that a graphics card is good at drawing triangles, coloring and rendering triangles, plus effects such as lighting and fog. In fact, triangles are the basis of all graphics. The world we see can also be seen as a seamless splicing of several triangles (it looks like we are drawing a finite element triangle mesh, but it’s almost the same), and the vertices of each triangle have different colors. , The color inside the triangle is a linear interpolation of the vertex color (familiar? It is similar to the shape function in the finite element, indeed); it can also be regarded as taking a picture of the scene in front of you and hiding the picture in front of you. This is another display of the GPU. One way of working: stickers, not discussed here. So how do we manipulate the GPU to draw the contour map? Divide the discrete area into a finite number of seamlessly connected small triangles, and then use the GPU to draw each triangle to obtain an iso map of the entire domain. Here is a demo of the vertex shader (Vertex Shader) plagiarized from the Internet (http://www.adobe.com/devnet/flashplayer/articles/hello-triangle.html), using GPU to draw a triangle:

1. package
2. {
3. import com.adobe.utils.AGALMiniAssembler;
4.  
5. import flash.display.Sprite;
6. import flash.display3D.Context3D;
7. import flash.display3D.Context3DProgramType;
8. import flash.display3D.Context3DVertexBufferFormat;
9. import flash.display3D.IndexBuffer3D;
10. import flash.display3D.Program3D;
11. import flash.display3D.VertexBuffer3D;
12. import flash.events.Event;
13. import flash.geom.Matrix3D;
14. import flash.geom.Rectangle;
15. import flash.geom.Vector3D;
16. import flash.utils.getTimer;
17.  
18. [SWF(width="800", height="600",frameRate="60",backgroundColor="#FFFFFF")]
19. public classHelloTriangleColored extends Sprite
20. {
21. protected varcontext3D:Context3D;
22. protected varprogram:Program3D;
23. protected varvertexbuffer:VertexBuffer3D;
24. protected varindexbuffer:IndexBuffer3D;
25.  
26. public functionHelloTriangleColored()
27. {
28. stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, initMolehill );
29. stage.stage3Ds[0].requestContext3D();
30.  
31. addEventListener(Event.ENTER_FRAME, onRender);
32.  
33.}
34.  
35. protected functioninitMolehill(e:Event):void
36. {
37. context3D= stage.stage3Ds[0].context3D; 
38. context3D.configureBackBuffer(800,600, 1, true);
39.  
40. var vertices:Vector.<Number> = Vector.<Number>([
41. -0.3,-0.3,0,1, 0, 0,//x, y, z, r, g, b
42. -0.3,0.3, 0, 0, 1, 0,
43. 0.3, 0.3, 0, 0, 0, 1]);
44.  
45.//Create VertexBuffer3D. 3 vertices, of 6 Numbers each
46. ​​vertexbuffer = context3D.createVertexBuffer(3, 6);
47.//Upload VertexBuffer3D to GPU. Offset 0, 3 vertices
48. vertexbuffer.uploadFromVector(vertices,0, 3); 
49.  
50. var indices:Vector.<uint> = Vector.<uint>([0, 1, 2]);
51.  
52.//Create IndexBuffer3D. Total of 3 indices. 1 triangle of3 vertices
53. indexbuffer = context3D.createIndexBuffer(3); 
54.//Upload IndexBuffer3D to GPU. Offset 0, count 3
55. indexbuffer.uploadFromVector(indices, 0, 3); 
56.  
57. var vertexShaderAssembler: AGALMiniAssembler = new AGALMiniAssembler();
58. vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
59. "m44 op, va0, vc0\n" +//pos to clipspace
60. "mov v0, va1"//copy color
61. );
62.  
63. var fragmentShaderAssembler: AGALMiniAssembler = new AGALMiniAssembler();
64. fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
65.  
66. "mov oc, v0"
67. );
68.  
69. program = context3D.createProgram();
70. program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
71.}
72.  
73.  
74. protected functiononRender(e:Event):void
75. {
76. if (!context3D) 
77. return;
78.  
79. context3D.clear( 1, 1, 1, 1 );
80.  
81.//vertex position to attribute register 0
82. context3D.setVertexBufferAt(0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
83.//color to attribute register 1
84. context3D.setVertexBufferAt(1,vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
85.//assign shader program
86. context3D.setProgram(program);
87.  
88. var m:Matrix3D = new Matrix3D();
89. m.appendRotation(getTimer()/40, Vector3D.Z_AXIS);
90. context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0, m, true);
91.  
92. context3D.drawTriangles(indexbuffer);
93.  
94. context3D.present();
95.  
96.}
97.  
98.}
99.}

I don’t understand it, it’s normal. It’s normal to get in touch with Flash 3D programming for the first time. I don’t understand it. You will find it simple after you read his introduction. Please search for Molehill Flash. We can now migrate this technology to HTML5 webGL to implement HTML5 Contour drawing. This tutorial only provides reference ideas at present.

In this way, we can draw the contour map. The following is the result of the operation.

Wait, what are the disadvantages? Legend, this beautiful thing has bothered me for a long time. In the fall of 2010, I went to Xuanhua to do a project. Several foreigners were debugging programs on site and watching the tunnel. I have to say that the user experience is indeed in place, using 3D technology to display industrial measurement and control values. Seeing that their Legend is actually made up of several segments, I suddenly realized that the original Legend is made up of several sets of colors. The following is an algorithm that I once wrote based on the Flex SDK finite element pre-processing and post-processing package (), the function getGradualColor can get a set of continuous color distributions, the program does not explain, it is understandable, unspeakable:

1. packageFEModel.util.visual
2. {
3. public class ColorUtil
4. {
5. public static function combineRGB(r:uint,g:uint,b:uint):uint
6. {
7. if(r<0) r=0
8. if(r>255) r=255;
9.  
10. if(g<0) g=0
11. if(g>255) g=255;
12.  
13. if(b<0) b=0
14. if(b>255) b=255;
15.  
16. var RGB:uint=(r<<16)|(g<<8)|b;
17. return RGB;
18.}
19.  
20. public static function getGradualColor(cnt:uint=10):Vector.<uint>
21. {
22. var colorList:Vector.<uint>=new Vector.<uint>(cnt+1,true);
23.  
24. for(var i:uint=0;i<cnt+1;i++)
25. {
26. var ratio:Number=i/cnt;
27. if(ratio<=0.25)
28. colorList[i]=colorInR1(ratio);
29. else if(ratio<=0.5)
30. colorList[i]=colorInR2(ratio);
31. else if(ratio<=0.75)
32. colorList[i]=colorInR3(ratio);
33. else
34. colorList[i]=colorInR4(ratio);
35.}
36. return colorList.reverse();
37.}
38.  
39. public static function colorInR1(ratio:Number):uint
40. {
41. ratio/=0.25;
42. return combineRGB(255,ratio*255,0);
43.}
44.  
45. public static function colorInR2(ratio:Number):uint
46. ​​{
47. ratio=(ratio-0.25)/0.25;
48. return combineRGB((1-ratio)*255,255,0);
49.}
50.  
51. public static function colorInR3(ratio:Number):uint
52. {
53. ratio=(ratio-0.5)/0.25;
54. return combineRGB(0,255,ratio*255);
55.}
56.  
57. public static function colorInR4(ratio:Number):uint
58. {
59. ratio=(ratio-0.75)/0.25;
60. return combineRGB(0,(1-ratio)*255,255);
61.}
62.}
63.}

Give Legend's drawing result:

Conclusion: This article briefly introduced GPU-based Contour drawing. Here, interested students are encouraged to use HTML5 webGL to implement Contour drawing.

Reference: https://cloud.tencent.com/developer/article/1180603 3.1.1 Drawing Contour with the help of graphics card GPU-Cloud + Community-Tencent Cloud