Archive 17/01/2023.

Geometry shaders (GL)

codingmonkey

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" />
</technique>
Shader: UnlitGS.glsl

https://pastebin.com/pyHtvanq

sabotage3d

That was in my wishlist. Awesome work!

Mike

Simply awesome :stuck_out_tongue:
Many thanks for sharing.

codingmonkey

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

franck22000

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

codingmonkey

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:

rasteron

nice one! :slight_smile:

weitjong

Thanks for sharing. Really interesting.

codingmonkey

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.
rasteron

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

franck22000

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 !

codingmonkey

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: opengl.org/discussion_board … 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.

[pastebin]q6mXQ3X7[/pastebin]

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

franck22000

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:

codingmonkey

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

franck22000

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

github.com/OldSnake22/Urho3D/tr … 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.

codingmonkey

[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);

franck22000

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()

codingmonkey

ok, now look at this

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

    // 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))
        return;
    usedPtrCombinations_.Insert(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;
    else
        newCombination = vsName + " " + vsDefines + " " + psName + " " + psDefines;

    if (usedCombinations_.Contains(newCombination))
        return;
    usedCombinations_.Insert(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.

codingmonkey

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);
            
        #endif

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

#ifdef PERPIXEL
    #ifdef SHADOW
        in mat4 vShadowPos[3];

and one for output into PS

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

GS emit shadow mat4 for vertex

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

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);
        #endif

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

Edit:
I’am restore my brunch with GS with current master
now actual repo: github.com/MonkeyFirst/Urho3D/tree/gs-shader-gl

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)

Bananaft

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

codingmonkey

Hi, currently it frozen. Also I guess render has a lot new changes and i’m not familiar with this new changes yet.
Maybe later I start new work for rewrite old GS-brunch for new gl-renderer and mb also for PR.

cadaver

Right now I’ve a branch going where I unify all graphics APIs to use the same header files (API-specific details should be hidden inside unions or pimpl when necessary), and put API-independent parts of the graphics classes (e.g. calculating vertex element offsets) in their own files. This probably affects your work too, but hopefully will make writing for multiple APIs less tedious in the future. This should be ready in a week or so.

codingmonkey

ok, I will be waiting for PR, and then try to figure out with new changes in renderer, and how I may inject my previous gs-brunch into it.

najak3d

We really would like to have geometry shaders for Urho. We want to use it for smooth line drawing (so that we can translate a simple array of Line Points into a 3D line with thickness and smoothed edges). So the geometry would preserve the mid-line, and also create two outlines – and then the pixel shader would do a transparency falloff as it neared the edges. This would create the smoothing effect desired. (This is one implementation.)

Without Geometry shaders, we’ll have to generate 4 triangles per line segment manually. We can do this too, but I think it’s more appropriate (and efficient) to instead just feed in a simple array of points.

What is the difficulty of getting Geometry shaders implemented in Urho? We could supply some funding for it, if the cost is reasonable, and it helps get the job done.