Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: gl_PrimitiveID in fragment shader with tessellation enabled

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5

    gl_PrimitiveID in fragment shader with tessellation enabled

    Hello,

    I am trying to visualize my tessellations by using a lookup-table inside fragment shader which is indexed using a gl_PrimitiveID like this:

    Code :
    precision mediump float;
    layout(location = 0) out vec4 color;
     
    // Color Look-up table of 8 entries
    vec3 color_lut[8] = vec3[]( vec3( 0.0, 0.0, 0.0 ),
    vec3( 0.5, 0.5, 0.5 ),
    vec3( 1.0, 0.5, 0.5 ),
    vec3( 0.5, 1.0, 0.5 ),
    vec3( 0.5, 0.5, 1.0 ),
    vec3( 0.5, 1.0, 1.0 ),
    vec3( 1.0, 0.5, 1.0 ),
    vec3( 1.0, 1.0, 0.5 ) );
     
    void main() {
    int prim_color_index = gl_PrimitiveID % 8;
        color = vec4(color_lut[prim_color_index], 1.0f);
    }

    But I am not seeing the result as expected and only see a single color over my original untessellated triangle patch. I then checked if gl_PrimitiveID varies for each tessellated triangle and that wasn't the case. I am getting a 0 for all of them. I was under the impression that gl_PrimitiveID would be unique for each tessellated triangle. I then checked the OpenGL Wiki and it says that gl_PrimitiveID is supposed to be unique for each primitive: https://www.khronos.org/opengl/wiki/..._shader_inputs

    gl_PrimitiveID : This value is the index of the current primitive being rendered by this drawing command. This includes any Tessellation applied to the mesh, so each individual primitive will have a unique index. However, if a Geometry Shader is active, then the gl_PrimitiveID is exactly and only what the GS provided as output. Normally, gl_PrimitiveID is guaranteed to be unique, so if two FS invocations have the same primitive ID, they come from the same primitive. But if a GS is active and outputs non-unique values, then different fragment shader invocations for different primitives will get the same value. If the GS did not output a value for gl_PrimitiveID, then the fragment shader gets an undefined value.
    So it looks like my GPU isn't following the OpenGL spec well?

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    Quote Originally Posted by Orbb256 View Post
    I then checked if gl_PrimitiveID varies for each tessellated triangle and that wasn't the case. I am getting a 0 for all of them. I was under the impression that gl_PrimitiveID would be unique for each tessellated triangle. I then checked the OpenGL Wiki and it says that gl_PrimitiveID is supposed to be unique for each primitive: https://www.khronos.org/opengl/wiki/..._shader_inputs

    So it looks like my GPU isn't following the OpenGL spec well?
    It isn't following what's on the wiki, but the specification says nothing about tessellation.

    It does say that
    For polygons drawn in point or line mode, the primitive ID counter is incremented only once, even though multiple points or lines may be drawn.
    Which implies that it's related to the primitives generated by the drawing command rather than to what gets rasterised. On the other hand, it also says:
    The first primitive generated by a drawing command is numbered zero, and the primitive ID counter is incremented after every individual point, line, or polygon primitive is processed.
    Note that it doesn't say "patches". In spite of the fact that tessellation control and evaluation shaders get passed gl_PrimitiveID as an input. Bear in mind that tessellation control shaders are invoked a fixed number of times per patch, and tessellation evaluation shaders are invoked for each generated vertex, so its unclear what gl_PrimitiveID should refer to in that context.

    If you want unique IDs for primitives resulting from tessellation, I think you're going to need to use a geometry shader.

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5
    Quote Originally Posted by GClements View Post
    Which implies that it's related to the primitives generated by the drawing command rather than to what gets rasterised.
    That seemed to be the case but the spec specifically says that gl_PrimitiveID should contain the number of primitives processed by the rasterizer. I'm looking at OpenGL ES 3.2 spec Chapter 14, Section 14.2.2 Page 374 :

    "If a geometry shader is active, the built-in variable gl_PrimitiveID contains the ID value emitted by the geometry shader for the provoking vertex. If no geometry shader is active, gl_PrimitiveID contains the number of primitives processed by the rasterizer since the last drawing command was called. The first primitive generated by a drawing command is numbered zero, and the primitive ID counter is incremented after every individual point, line, or polygon primitive is processed."

    Since HW Rasterizers typically only deal with simple geometries like points, lines and triangles; this seems to suggest that the primitive ID should be unique for all primitives which come out of the rasterizer and into the fragment shader.
    Last edited by Orbb256; 02-08-2019 at 01:38 PM.

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    I know what it says. My point is that the specification is fairly vague in this area, and where it's clear it seems to contradict itself. E.g. if it intends "primitive" to mean the entities processed by the "rasterization" part of the specification (14.4-14.6 in the 4.6 spec), then the language regarding "polygons drawn in point or line mode" wouldn't be there (each edge or vertex would get a distinct gl_PrimitiveID value). And reading the specifications for the extension on which tessellation is based doesn't add anything.

    To the extent that the specification contradicts the observed behaviour: if this is eventually addressed, it's entirely likely that this will end up being viewed as a bug in the specification, with the specification changing to match the observed behaviour. So if you need gl_PrimitiveID to have different values for different triangles generated by tessellation, I'd look into using a geometry shader to set it. I wouldn't hold your breath waiting for the implementation to change.

  5. #5
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5
    Quote Originally Posted by GClements View Post
    I know what it says. My point is that the specification is fairly vague in this area, and where it's clear it seems to contradict itself. E.g. if it intends "primitive" to mean the entities processed by the "rasterization" part of the specification (14.4-14.6 in the 4.6 spec), then the language regarding "polygons drawn in point or line mode" wouldn't be there (each edge or vertex would get a distinct gl_PrimitiveID value). And reading the specifications for the extension on which tessellation is based doesn't add anything.

    To the extent that the specification contradicts the observed behaviour: if this is eventually addressed, it's entirely likely that this will end up being viewed as a bug in the specification, with the specification changing to match the observed behaviour. So if you need gl_PrimitiveID to have different values for different triangles generated by tessellation, I'd look into using a geometry shader to set it. I wouldn't hold your breath waiting for the implementation to change.
    Thanks for your answer. Let me file this issue on Khronos bugzilla and see what happens. Your opinion gives me confidence that I wasn't reading the spec wrong

    I wouldn't hold my breath either for implementations to change any time soon but atleast the spec should be more consistent in what it means.

  6. #6
    Administrator Regular Contributor khronos's Avatar
    Join Date
    Feb 2000
    Location
    Montreal
    Posts
    349
    Bugzilla is gone, best to post on Github under the Khronos Organization https://github.com/KhronosGroup/

  7. #7
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674
    Specifically, API bugs go in this repo. GLSL bugs go in this repo.

  8. #8
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5
    Just found this by accident by browsing through an email regarding the issues to be discussed in the next Khronos meeting. [link removed]

    I just added a comment to that summarizing the discussions in this thread.
    Last edited by khronos; 02-15-2019 at 05:36 PM. Reason: Khronos member only information posted

  9. #9
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674
    Apparently, you need some form of membership to reach that area. Khronos's GitHub issue trackers are public.

  10. #10
    Junior Member Newbie
    Join Date
    Feb 2019
    Posts
    5
    That one has more issues and seems to be more active than the github one. I don't know if there's a way to connect them or it's supposed to be that way.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean