Geometry Shader instancing after tessellation

Viewed 70

In a Geometry Shader, I need the index of the current triangle within the patch being currently tessellated by the Tessellation Control Shader.

Since gl_PrimitiveIDIn is called per-primitive, and reading here :"The GS can also be instanced ... This causes the GS to execute multiple times for the same input primitive. Each invocation of the GS for a particular input primitive will get a different gl_InvocationID value."

knowing that a patch is always being tessellated into n triangles, I am finding the index of the current triangle within a patch as index = gl_PrimitiveIDIn * n + gl_InvocationID;

It works. But I am not comfortable beacuse the same link also states:

"To use instancing, there must be an input layout qualifier: layout(invocations = num_instances​) in;"

which is not my case, because I have no layout qualifier like this. Yet the Geometry Shader is invoked multiple times on the same primitive in case of a tessellation, at least in my case, and gl_InvocationID is updated accordingly.

Can I safely assume that a Geometry Shader following a Tessellation Control Shader will be instanced multiple times?

1 Answers

Can I safely assume that a Geometry Shader following a Tessellation Control Shader will be instanced multiple times?

No. Indeed, you can assume that GS instancing will only be used if you ask for it. Because that's how the feature works.

It isn't clear why index = gl_PrimitiveIDIn * n + gl_InvocationID; "works," but it certainly does not make index produce a per-tessellated-primitive index. Maybe n is 1 for some reason. gl_InvocationID will be zero.

GS instancing reuses the same input primitive for all of the instances. The only difference between invocations of the GS for instances will be the value of gl_InvocationID. This includes the input primitive; they will all be the same vertices for all instances. GS instancing does not care about tessellation.

You seem to want a counter that starts at zero at the beginning of the tessellation of a patch, and increments for each primitive output by the tessellation primitive generator. That is not actually possible to compute.

The GS lacks any knowledge of which primitives come from which patches. gl_PrimitiveIDIn counts all primitives within the draw call, so if you're rendering more than one patch, it has no idea how to handle that. If all of the patches are being subdivided into the same number of primitives, then you could do gl_PrimitiveIDIn % n to get the index within a patch. But that's about it.

The only code that might be able to produce such a counter is the TES. However, even if it could, it lacks the ability to output per-primitive information. It can output per-vertex information, but it cannot know which vertices are the provoking vertex for a particular output primitive (indeed, a provoking vertex might be shared between multiple primitives). So it cannot deliver an index value.

Related