Geometry shaders (GL)

Hi folks)
Earlier I wrote GS-shaders support on GL renderer but I have some strange bug then I try to edit these GS shaders in liveEdit manner. I got an double linkage error.
But today, I found what my bug with GS-shaders are gone somewhere )
so I decided to share this, GS shaders seems quite working
just an example:

Techniques: DiffGS.xml

<technique vs="UnlitGS" ps="UnlitGS" gs="UnlitGS" psdefines="DIFFMAP">
    <pass name="base" />
Shader: UnlitGS.glsl

That was in my wishlist. Awesome work!

Simply awesome :stuck_out_tongue:
Many thanks for sharing.

thanks guys )
now I add “primitive mode” selection in material for properly input GS layout work:
I mean this GS input layouts:

layout (points) in;
layout (lines) in;
layout (triangles) in;

test with GS shades : UnlitGSPointsToQuads.glsl

1 Like

Nice job :slight_smile: Can we expect this for DX11 ? :slight_smile:

I would like also to see a similar on dx11, but I do not know much dx11( so maybe someone who knows someday implement similar stuff.
Also, why you do not do this yourself ? :slight_smile:

nice one! :slight_smile:

Thanks for sharing. Really interesting.

Thanks for sharing. Really interesting.
No problems) I hope sometime urho3D will be fully support GS shaders on both gapi DX11/GL )

few new additions:

  • Add oriented billboards example shader, it can rotates around eye axis by uniform “angle” and change size of billboards by “offset” uniform
  • Add wireframe shader example (no needed second geometry passes draw with lines) We add new attributes for vertexes in GS shader to calc wireframe lines in PS.

Great update codingmonkey! I like the wireframe shader, is it easy to add other textures other than diffuse? :slight_smile:

Im trying to implement it for DX11 right now :slight_smile:

If i need any help i will ask it here. With your great work CodingMonkey it’s time to add geometry shaders support in Urho3D !

Im trying to implement it for DX11 right now
good news) it will be awesome to have similar stuff on dx11 also

is it easy to add other textures other than diffuse?
Did you mean LitSolid shader and all variants of it? Probably yes, it possible.
But first of all, we need began use structs in shaders, for solve one interface block issue with passing through VS<->GS (vec4 vShadowPos[NUMCASCADES]:wink:
See this topic for clarify: … ing-arrays (post #4 from Alfonse Reinheart)
I try to create std LitSolid shader (without GS part) with using structs (IN/OUT) but it’s not working properly.


Model(Jack) - is fully black colored. I do not know why. Probably I create an Issue for figure out with this.

I have spotted an issue in shaderprecache.cpp in your branch. at line 142:

ShaderVariation* gs = graphics->GetShader(GS, shader.GetAttribute(“gs”), psDefines);

“psDefines” should be “gsDefines” i think ? :slight_smile:

oh, yes. thanks, i’m fix this)

I have made my DX11 geometry shader branch based on CodingMoney work. Im still working on this (make an HLSL shader and testing it) … tryShaders

Feel free to take a look and spot my eventual mistakes.

Please note that the code tabs formating issue will be of course fixed.

[quote]// TODO: Change this
1021 1049 Pair<ShaderVariation*, ShaderVariation*> key = MakePair(vertexShader_, pixelShader_); [/quote]

I guess you need also create second level of pair for this :
like so
Pair<ShaderVariation*, ShaderVariation*> baseCombination(vs, ps);
Pair<ShaderVariation*, Pair<ShaderVariation*, ShaderVariation*>> combination(gs, baseCombination);

Yes thank you for your advice :slight_smile:

I have also spotted that if i am right you do not check “gs” pointer validity in this function ShaderPrecache::StoreShaders()

ok, now look at this

void ShaderPrecache::StoreShaders(ShaderVariation* vs, ShaderVariation* ps, ShaderVariation* gs)
    if (!vs || !ps)

    // Check for duplicate using pointers first (fast)
    Pair<ShaderVariation*, ShaderVariation*> shaderPair = MakePair(vs, ps);
    Pair<ShaderVariation*, Pair<ShaderVariation*, ShaderVariation*>> shaderCombination = MakePair(gs, shaderPair);
    if (usedPtrCombinations_.Contains(shaderCombination))

    String vsName = vs->GetName();
    String psName = ps->GetName();
    String gsName = gs != 0 ? gs->GetName() : "";
    const String& vsDefines = vs->GetDefines();
    const String& psDefines = ps->GetDefines();
    const String& gsDefines = gs != 0 ? gs->GetDefines() : "";
    // Check for duplicate using strings (needed for combinations loaded from existing file)
    String newCombination = "";
    if (!gsName.Empty())
        newCombination = vsName + " " + vsDefines + " " + psName + " " + psDefines + " " + gsName + " " + gsDefines;
        newCombination = vsName + " " + vsDefines + " " + psName + " " + psDefines;

    if (usedCombinations_.Contains(newCombination))

    XMLElement shaderElem = xmlFile_.GetRoot().CreateChild("shader");
    shaderElem.SetAttribute("vs", vsName);
    shaderElem.SetAttribute("vsdefines", vsDefines);
    shaderElem.SetAttribute("ps", psName);
    shaderElem.SetAttribute("psdefines", psDefines);
    if (!gsName.Empty()) 
        shaderElem.SetAttribute("gs", gsName);
        shaderElem.SetAttribute("gsdefines", gsDefines);

GS is optional part of shader that’s why we do not need check it similar as - if (!vs || !ps) return.

well, with my trying to bring litSolid shader on GS-rails gives some results
but i found what GS shader also need copy all VSdefinitions to pass all varyings(output variables) through GS shader into PS properly.
the problem with passing vShadowPos[NUMCASCADES]; through GS shader into PS i try to solve with mat4 without using structs in shaders (actually structs also working well), to avoid additional index in data.
VS write in mat4:

#ifdef PERPIXEL #ifdef SHADOW out mat4 vShadowPos; #endif

        #ifdef SHADOW
            // Shadow projection: transform from world space to shadow space
            for (int i=0; i < NUMCASCADES; i++) 
                vShadowPos[i] = GetShadowPos(i, projWorldPos);

in GS we have 3 matrixes input, by one for each vertex output

    #ifdef SHADOW
        in mat4 vShadowPos[3];

and one for output into PS

    #ifdef SHADOW
        out mat4 gsShadowPos;

GS emit shadow mat4 for vertex

        #ifdef PERPIXEL
            #ifdef SHADOW
                gsShadowPos = vShadowPos[i];

after all PS gets one matrix and parse it

#ifdef PERPIXEL #ifdef SHADOW in mat4 gsShadowPos; #endif

        #ifdef SHADOW
            vec4 vShadowPos[NUMCASCADES];
            for (int i=0; i < NUMCASCADES; i++)
                vShadowPos[i] = gsShadowPos[i];
            diff *= GetShadow(vShadowPos, gsWorldPos.w);

but still i have some visual bugs with shading of model.

I’am restore my brunch with GS with current master
now actual repo:

Known bugs:
bug1: [solved (with adding “gsi” to same place with vsi, psi )]forward renderer material based on DiffNormal+Packed tech some light problems (dark objects), DS work fine in this case.
bug2: CustomGeometry bug glitch of mesh (for example editor grid)

Hi, what is the status of this work? Are you planing to do a PR?