Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Geometry Shader & UnityObjectToClipPos Issue

Discussion in 'Shaders' started by Mogram, Apr 2, 2021.

  1. Mogram

    Mogram

    Joined:
    May 10, 2018
    Posts:
    2
    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[i].pos;//Works
    //o.pos = UnityObjectToClipPos(IN[i].pos);//Wut?
    o.color = IN[i].color;
    stream.Append(o);
    }
    }
    //Frag Function
    fixed4 frag(g2f i) : SV_Target {
    return i.color;
    }
    ENDCG
    }
    }
    }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,243
    Using
    o.pos = v.vertex;
    in the vertex and
    o.pos = UnityObjectToClipPos(IN[i].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:
    Code (csharp):
    1. Shader "GEOIsh"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType" = "Opaque" }
    6.         Pass
    7.         {
    8.             CGPROGRAM
    9.             #pragma vertex vert
    10.             #pragma fragment frag
    11.             #pragma geometry geom
    12.  
    13.             #include "UnityCG.cginc"
    14.  
    15.             //Vert Input Struct
    16.             struct appdata {
    17.                 float4 vertex : POSITION;
    18.                 float4 color : COLOR;
    19.             };
    20.  
    21.             //Vert Output / Geom Input Struct
    22.             struct v2g {
    23.                 float4 pos : POSITION;
    24.                 float4 color: COLOR;
    25.             };
    26.  
    27.             //Vert Function
    28.             v2g vert(appdata v) {
    29.                 v2g o;
    30.  
    31.                 o.pos = v.vertex;
    32.                 o.color = v.color;
    33.  
    34.                 return o;
    35.             }
    36.  
    37.             //Geom Output / Frag Input
    38.             struct g2f {
    39.                 float4 pos : SV_POSITION;
    40.                 float4 color : COLOR;
    41.             };
    42.  
    43.             //Geom Function
    44.             [maxvertexcount(3)]
    45.             void geom(triangle v2g IN[3], inout TriangleStream<g2f> stream) {
    46.                 g2f o;
    47.  
    48.                 for (int i = 0; i < 3; i++)
    49.                 {
    50.                     o.pos = UnityObjectToClipPos(IN[i].pos);
    51.                     o.color = IN[i].color;
    52.                     stream.Append(o);
    53.                 }
    54.             }
    55.  
    56.             //Frag Function
    57.             fixed4 frag(g2f i) : SV_Target {
    58.                 return i.color;
    59.             }
    60.  
    61.             ENDCG
    62.         }
    63.     }
    64. }
     
    Mogram likes this.
  3. Mogram

    Mogram

    Joined:
    May 10, 2018
    Posts:
    2
    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.