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

unity_InstanceID always 0 in URP?

Discussion in 'Universal Render Pipeline' started by pakfront, Oct 6, 2019.

  1. pakfront

    pakfront

    Joined:
    Oct 6, 2010
    Posts:
    551
    I'm probably doing something wrong, but I'm using the
    DrawMeshInstancedIndirect with MonoBehaviour example verbatim from the docs:
    https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html
    with this shader:
    Code (CSharp):
    1. Shader "Unlit/InstancedTest"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType"="Opaque" }
    6.         LOD 100
    7.  
    8.         Pass
    9.         {
    10.             CGPROGRAM
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.             #pragma multi_compile_instancing
    14.             #pragma instancing_options procedural:setup
    15.             #pragma target 4.5
    16.  
    17.             #include "UnityCG.cginc"
    18.  
    19.             struct appdata
    20.             {
    21.                 float4 vertex : POSITION;
    22.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    23.             };
    24.  
    25.             struct v2f
    26.             {
    27.                 float4 vertex : SV_POSITION;
    28.                 fixed4 color : COLOR;          
    29.             };
    30.  
    31.             v2f vert (appdata v)
    32.             {
    33.                 v2f o;
    34.                 o.vertex = v.vertex;
    35.                 o.color = fixed4(0,1,0,1);;
    36.  
    37. #if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
    38.                 o.vertex += float4(-unity_InstanceID.xxx, 0);
    39.                 o.color = fixed4(1,0,unity_InstanceID*0.25,1);
    40. #endif
    41.                 o.vertex = UnityObjectToClipPos(o.vertex);
    42.                 return o;
    43.             }
    44.  
    45.             fixed4 frag (v2f i) : SV_Target
    46.             {
    47.                 fixed4 col = i.color;
    48.                 return col;
    49.             }
    50.             ENDCG
    51.         }
    52.     }
    53. }
    What I would expect to see is my instanced mesh ( a sphere) offset in space and color for each instance. Instead, all I see is 1 red sphere. It's red, which means that
    UNITY_PROCEDURAL_INSTANCING_ENABLED is defined, otherwise it would be green. I'm guessing
    - all the instances have id 0 are drawing on top of each other
    - or there is only one instance being drawn.
    Any thoughts on what I'm missing or if this won't work in URP?

    edit:
    since UNITY_VERTEX_INPUT_INSTANCE_ID I also tried this, but same result, single red mesh

    #if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
    o.vertex += float4(-v.instanceID.xxx, 0);
    o.color = fixed4(1,0,v.instanceID*0.25,1);
    #endif
     
    Last edited: Oct 6, 2019
    Flannelot and ChristopherKerr like this.
  2. pakfront

    pakfront

    Joined:
    Oct 6, 2010
    Posts:
    551
    I've been able to reproduce in Classic renderer as well. However, using explicit SV_InstanceID does work for Classic and URP.
    Code (CSharp):
    1. Shader "Unlit/InstancedTest"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType"="Opaque" }
    6.         LOD 100
    7.  
    8.         Pass
    9.         {
    10.             CGPROGRAM
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.  
    14.             struct appdata
    15.             {
    16.                 float4 vertex : POSITION;
    17.                 uint instanceID : SV_InstanceID;
    18.             };
    19.  
    20.             struct v2f
    21.             {
    22.                 float4 vertex : SV_POSITION;
    23.                 fixed4 color : COLOR;        
    24.             };
    25.  
    26.             v2f vert (appdata v)
    27.             {
    28.                 float3 worldPosition = v.vertex.xyz + float4(v.instanceID.xxx, 0);
    29.                 fixed4 color =  fixed4(1,0,v.instanceID*0.01,1);
    30.  
    31.                 v2f o;
    32.                 o.vertex = mul(UNITY_MATRIX_VP, float4(worldPosition, 1.0f));
    33.                 o.color = color;
    34.                 return o;
    35.             }
    36.  
    37.             fixed4 frag (v2f i) : SV_Target
    38.             {
    39.                 fixed4 col = i.color;
    40.                 return col;
    41.             }
    42.             ENDCG
    43.         }
    44.     }
    45. }
     
    Last edited: Oct 7, 2019
    Flannelot, Krishx007 and bajja like this.
  3. thebarryman

    thebarryman

    Joined:
    Nov 22, 2012
    Posts:
    122
    Wow, I've been trying to find a solution for this problem for hours. This is the one post I found that actually gets me access to the instance ID and all I had to do was include it in the appdata struct ... crazy ...
     
    ChristopherKerr and Krishx007 like this.
  4. tomkail_betterup

    tomkail_betterup

    Joined:
    Nov 17, 2021
    Posts:
    100
    Hi! This remains broken. The docs occasionally mention the existence of unity_InstanceID but never show how it's used. Can this be fixed, or the docs improved?