Geometry Shader & UnityObjectToClipPos Issue

I’m seeing some unexpected behavior with a geometry shader; & was able to boil it down to the extremely simple example below. On my platform, calling UnityObjectToClipPos in the vert program and passing through to geo then frag works as expected. But, if i remove the clip space conversion & add it to the geo program, the object ‘disappears’, seemingly moved outside of clip space.

Not a shader expert here by any means, but everything I’ve read about geometry shaders tells me I should be able to do the conversion in the geo shader without issue. Wondering if it’s something silly like using SV_POSITION incorrectly, or if it’s a platform-specific bug (I’m on win7).

Any help would be appreciated, thanks!

Shader Code (:

Shader "GEOIsh"
{
SubShader
{
Tags { "RenderType" = "Opaque" }

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom

#include "UnityCG.cginc"
//

//Vert Input Struct
struct appdata {
float4 vertex : POSITION;
float4 color : COLOR;
};

//Vert Output / Geom Input Struct
struct v2g {
float4 pos : SV_POSITION;
float4 color: COLOR;
};

//Vert Function
v2g vert(appdata v) {
v2g o;
o.pos = UnityObjectToClipPos(v.vertex);//Works
//o.pos = v.vertex;//Wut?
o.color = v.color;
return o;
}

//Geom Output / Frag Input
struct g2f {
float4 pos : SV_POSITION;
float4 color : COLOR;
};
//Geom Function
[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> stream) {
g2f o;
for (int i = 0; i < 3; i++)
{
o.pos = IN*.pos;//Works*
_//o.pos = UnityObjectToClipPos(IN*.pos);//Wut?*_
<em>_o.color = IN*.color;*_</em>
<em>_*stream.Append(o);*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*//Frag Function*_</em>
<em><em>*fixed4 frag(g2f i) : SV_Target {*</em></em>
<em>_*return i.color;*_</em>
<em>_*}*_</em>
<em>_*ENDCG*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*}*_</em>
<em>_*```*_</em>

Using o.pos = v.vertex; in the vertex and o.pos = UnityObjectToClipPos(IN*.pos); in the geometry shader works fine for me. Win 10, Nvidia RTX 2080 Super. Using SV_Position as the output from the vertex shader and input to the geometry shader is how I’ve seen every example shader work, including Microsoft’s official example shaders.*
This works perfectly fine for me:
```
*Shader “GEOIsh”
{
SubShader
{
Tags { “RenderType” = “Opaque” }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma geometry geom

        #include "UnityCG.cginc"

        //Vert Input Struct
        struct appdata {
            float4 vertex : POSITION;
            float4 color : COLOR;
        };

        //Vert Output / Geom Input Struct
        struct v2g {
            float4 pos : POSITION;
            float4 color: COLOR;
        };

        //Vert Function
        v2g vert(appdata v) {
            v2g o;

            o.pos = v.vertex;
            o.color = v.color;

            return o;
        }

        //Geom Output / Frag Input
        struct g2f {
            float4 pos : SV_POSITION;
            float4 color : COLOR;
        };

        //Geom Function
        [maxvertexcount(3)]
        void geom(triangle v2g IN[3], inout TriangleStream<g2f> stream) {
            g2f o;

            for (int i = 0; i < 3; i++)
            {
                o.pos = UnityObjectToClipPos(IN[i].pos);
                o.color = IN[i].color;
                stream.Append(o);
            }
        }

        //Frag Function
        fixed4 frag(g2f i) : SV_Target {
            return i.color;
        }

        ENDCG
    }
}

}*
```

1 Like

Hi bgolus, thanks for taking the time to check this out. I dug around some more and found the problem. . . it’s URP. When I switched back to default, no problem.

Hi Mogram, I get the same issue in URP. But I don’t why TransformObjectToHClip() function is wrong in geometry shader.Is there something wrong with GetObjectToWorldMatrix() in geometry shader? I’d appreciate it if you could reply.