What is Geometry Shader
The GS exists between the Vertext shader and the fixed function vertex post-processing stage, which is optional and not necessary.
The GS input is a single primitive, and the output may be 0 or more primitive.
The role of GS
The main function of GS is to generate new primitive from existing primitive, which can generate new vertices "out of nothing".
OpenGL official online mentions two kinds of usage:
Layered rendering: For a primitive, do not change rendertarget render multiple pictures
Transform Feedback: Compute task to perform GPU (Pre-compute shader)
Is an example, the GS input a triangle, GS output 4 triangles
Layered Rendering
As mentioned above, a big use of GS embodied in Layerd rendering, that is, multi-layer rendering.
Imagine that for multilayer textures, the texture coordinates of each layer are actually the same. How do you specify the layer number? While it is possible to give the third dimension value of the texture coordinates when the VBO is established, this does not allow OpenGL to draw on the layer you want to draw: the process of fragment is the process of pixelated the vertex, and this process is two-dimensional ... Finally, the two-dimensional image must have no depth, the number of layers is impossible to talk about.
But geometry has a key built-in output variable: out int gl_Layer
It is the ability to specify the number of layers to draw. We might as well write out the contents of the geometry shader, and note that the graphics card must support at least OpenGL 4.0, #version
which is at least 400:
1#version the2Layout (triangles, invocations =2)inch;//input triangle, 2 calls3Layout (Triangle_strip, max_vertices =3) out;//Output triangle4 inchVEC2 gtexcoord[];//texture coordinates passed from vertex.5 outVEC2 Ftexcoord;//To fragment texture coordinates6 out intGl_layer;//number of layers marked7 void Main ()8 {9Forintk=0;k<gl_in.length (); k++)//For each vertex of the triangleTen { OneGl_layer = Gl_invocationid;//Mark layer number with call number AFtexcoord = Gtexcoord[k];//Texture coordinate transfer -Gl_position = Gl_in[k].gl_position;//Vertex coordinate transfer -Emitvertex ();//Start passing vertex information, call once for each vertex the } -Endprimitive ();//End a primitive, one primitive call at a time -}
It is important to note that triangles
your drawing instructions in OpenGL must be GL_TRIANGLE
, GL_TRIANGLE_STRIP
or GL_TRIANGLE_FAN
. Other correspondence can be found on the wiki. The triangle has 3 vertices, this group of 3 vertices will enter the geometry simultaneously, so in geometry can get a gl_in[] of the built-in array, the size of the array should be drawn with a set of vertices of the same number, the triangle is 3. And here I don't need to add vertices, so the output is still 3 vertices. At the same time, the texture coordinates become an array of course. Therefore, a loop is required to operate on each vertex of the triangle.
There is no need to change the vertex and texture coordinates here, so it is passed directly. The point is to gl_layer this sentence. gl_Layer
this built-in variable is used to indicate the currently drawn layer number, which will affect which layer the pixel is drawn to after pixelated. OpenGL requires that a set of vertices (here is a triangle) inside the gl_layer must be consistent. This assignment is then passed to fragment as a sign.
The key step is the second line invocations = 2
and gl_InvocationID
the built-in variable. invocations=n
instructs Geometry to do n operations on each set of vertices, gl_InvocationID
marking the ordinal of each operation. We can send this serial number gl_Layer
as the value of the layer number! In this way geometry will send this group of vertices repeatedly two times, and these two times are sent to different layers, so as to achieve the different layers of drawing!
The next step is to get this gl_layer in the fragment, layered as needed to handle it.
Geometry Shader Summary