Search code examples
openglglsltessellation

OpenGL tessellation and GLSL for the Tessellation Control Shaders clarification


I'm studying the graphics pipeline and I have some questions about the tessellation phase. My basic reading material is "OpenGL SuperBible Sixth Edition: Comprehensive Tutorial and Reference".

Question #1: In the SuperBible I read that the vertex shader runs once per patch vertex (or control point in a tessellation context) "feeding" the Tessellation Control Shader one vertex at a time. The TCS, in turn, runs on groups of vertices. In this link though

http://web.engr.oregonstate.edu/~mjb/cs519/Handouts/tessellation.1pp.pdf

it says that the TCS runs once per "output vertex" (which I assume are the vertices being output by the VS). Which of the two is true? Did I get the whole thing wrong or is one of them wrong?

Question #2: This one is about the GLSL. The following shaders are from a SuperBible example.

Vertex Shader

#version 410 core
void main(void)
{                                                                                  
    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),                   
                                   vec4(-0.25, -0.25, 0.5, 1.0),                   
                                   vec4( 0.25,  0.25, 0.5, 1.0));                  

    gl_Position = vertices[gl_VertexID];                                           
}

Tessellation Contron Shader

#version 410 core                                                                      
layout (vertices = 3) out;                                                         

void main(void)                                                                    
{                                                                                  
    if (gl_InvocationID == 0)                                                     
    {                                                                              
        gl_TessLevelInner[0] = 5.0;                                                
        gl_TessLevelOuter[0] = 5.0;                                                
        gl_TessLevelOuter[1] = 5.0;                                                
        gl_TessLevelOuter[2] = 5.0;                                                
    }                                                                              
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;      
}

a) What do the tokens gl_VertexID (on the vertex shader) and gl_InvocationID (on the TCS) mean? They confuse me because they are not explicitly declared anywhere in the programs.

b) I understand that in the TCS the gl_Position variable takes its data from the vertex shader but nowhere in the vertex shader is it explicitly declared that gl_Position should be the output (e.g. with the out keyword before the main program). I thought that to pass data through the various shaders and pipeline phases, one must explicitly declare inputs and outputs with the same name, so what's happening in this case?


Solution

  • Here is what I can recall and show some not so precise definition, for the detail definition, it's better to access opengl.org, check the GLSL spec, the latest version should be GLSL 4.5.

    First Question, these two are both right, ;) Until Geometry shader, each shader will run once for the input vertices, but the confuse thing is Vertex shader will handle the 'patch vertex', TCS will also handle the 'patch vertex', TES will handle the real vertex, which is generated by Tessellator [this is a hardware unit, make your GPU different with DX10/GL3.x cap devices]. The difference between VS [Vertex shader, the same as following short name] and TCS is TCS will also configure the prope parameter which will needed by Tessellator. Basically, VS and TCS handle the same vertices.

    Second Question #a, gl_VertexID means the id of your input vertices, gl_InvocationID means how many times has been run on your shader, you should check some tutorial or doc for GS, which use gl_InvocationID sometime. Actually, gl_InvocationID == 0 make the follow if-{-} stagement be like the 'Constant Hull Shader' in D3D

    Second Question #b, gl_Position is the build-in variable for vertices' position, of course you can use 'out' keyword to define what ever you like, but OGL SB is a long history book~

    Hope this helps, ;)