- Home /
Call different geometry shader functions, for different primitive type: How?
Hello,
I have a geometry shader that needs to work a bit differently depending on if the primitives are provided via GL.Begin(GL.lines) or GL.Begin(GL.quads).
I tried defining two version of the function in my shader, with the same name, but different parameters. Alas, this does not seem to be working properly. Perhaps I’m using the wrong primate type for GL.quads? I’ve tried both “triangle” and “lineadj”, but neither version ever gets called (unless I rename the "line" version as a sanity check).
My shader currently has both of the following function definitions, but only the second one is ever called, regardless of whether unity is drawing GL.lines or GL.quads
#pragma geometry GS_Main
…(vertex shader, struct definition, tags, etc)…
[maxvertexcount(4)]
void GS_Main(lineadj v2g p[4], inout TriangleStream<g2f> pStream) //note the "lineadj" in first param. Tried "triangle v2g p[3]" to, same result, never called.
{…}
[maxvertexcount(28)]
void GS_Main(line v2g p[2], inout TriangleStream<g2f> pStream) //note the "line" in first param
{…}
I don’t even know if I’m allowed to override the geometry shader, GS_Main, function like that, but it’s not giving my any compile errors.
Primary Question: How can I get the correct version of the geometry shader functions to run depending on weather Unity is using GL.lines vs Gl.quads? Or is it REQUIRED that each shader handle only one type of primitive (in which case I'm open to suggestions).
Answer by tanoshimi · May 19, 2016 at 03:21 PM
I don't know for sure but, based on the comments in http://gamedev.stackexchange.com/questions/38874/geometry-shader-for-multiple-primitives , I don't think it's possible to overload a geometry shader to handle multiple primitive types (not in GLSL, anyway, but I suspect the same is true for Cg/HLSL)
Yeah, I had come to the same conclusion, but didn't want to believe it. So it sounds like I'll have to swap out materials, in unity, depending on what type of primitive I'm drawing.
OH! Talking about swapping out the material made me realize I DO call this function, just before I draw GL.lines line$$anonymous$$aterial.SetPass(0);
Hmm, perhaps I can specify a different SetPass paramater for quads, and get it to use the other geometry shader function, in that way? (I've only done single pass shaders so far...)
Yes - that could work. Another idea might be to create explicit subshaders for each geometry type with different LODs, and then use shader.maximumLOD to "switch" between them?
Interesting..I've not worked with LODs before. How/where would I specify that lines use LOD x, and quads use LOD y? The disadvantage to using SetPass() is that, the functionality difference, between quads and lines, is no longer transparent. It also limits the ability to swap the same drawing code to a material that uses a different shader, one with only ONE pass available. Would using LOD ins$$anonymous$$d, help with those issues?