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. Dismiss Notice

Resolved How to get the instance ID while using custom SRP?

Discussion in 'Shaders' started by vanger1, Jul 28, 2023.

  1. vanger1

    vanger1

    Joined:
    Aug 10, 2020
    Posts:
    10
    That's probably a stupid question, but how can I get the instance ID when I render meshes using Graphics.RenderMeshPrimitives while using custom SRP? Documentation (https://docs.unity3d.com/Manual/gpu-instancing-shader.html) says that I should declare a structure with UNITY_VERTEX_INPUT_INSTANCE_ID, pass it in my shader function and there I can get instance ID by vertexInput.instanceID if there was #ifdef INSTANCING_ON.

    But I get invalid subscript 'instanceID' compile error. Here's the minimal code illustrating the situation.

    Code (CSharp):
    1. StructuredBuffer<float4x4> _Matrices;
    2.  
    3. struct Varyings
    4. {
    5.   float4 positionCS : SV_POSITION;
    6.   UNITY_VERTEX_INPUT_INSTANCE_ID
    7. };
    8.  
    9. Varyings UnlitPassVertex(Attributes input)
    10. {
    11.   Varyings output;
    12.   UNITY_SETUP_INSTANCE_ID(input);
    13.   #ifdef INSTANCING_ON
    14.   float4x4 m = _Matrices[input.instanceID];
    15.   #else
    16.   float4x4 m = 1.0;
    17.   #endif
    18.   float4 w = mul(m, float4(input.positionOS, 1.0));
    19.   float4 c = mul(unity_MatrixVP, w);
    20.   output.positionCS = c;
    21.   return output;
    22. }

    The fact that to get the error I must write manually #define INSTANCING_ON makes me think that I'm doing something wrong. Despite that problem instancing workd just fine. Pipeline is duplicating one from Catlike Coding tutorial (https://catlikecoding.com/unity/tutorials/custom-srp/draw-calls/).
     
  2. Saniell

    Saniell

    Joined:
    Oct 24, 2015
    Posts:
    164
    Have you included required files to your shader? Not familiar with SRP, but generally you would need to include "UnityInstancing.cginc"

    Also, UNITY_VERTEX_INPUT_INSTANCE_ID basically just unfolds to `uint instanceID : SV_InstanceID`.
     
    vanger1 likes this.
  3. vanger1

    vanger1

    Joined:
    Aug 10, 2020
    Posts:
    10
    I think so. Cause all other stuff like UNITY_VERTEX_INPUT_INSTANCE_ID, UNITY_SETUP_INSTANCE_ID, UNITY_ACCESS_INSTANCED_PROP is working as expected. I used
    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"

    though, according to that tutorial.

    Great! Such replacement gave the correct behavior. But apparently in my case UNITY_VERTEX_INPUT_INSTANCE_ID unfolds to something else. I tried to read UnityInstancing.hlsl, but didn't succeed.
     
  4. vanger1

    vanger1

    Joined:
    Aug 10, 2020
    Posts:
    10
    Moreover, even such thing compiles:

    struct Attributes
    {
    float3 positionOS : POSITION;
    UNITY_VERTEX_INPUT_INSTANCE_ID
    uint instanceID : SV_InstanceID;
    };
     
  5. Saniell

    Saniell

    Joined:
    Oct 24, 2015
    Posts:
    164
    I don't think it can unfold to anything else, see source code for SRP: https://github.com/needle-mirror/co...master/ShaderLibrary/UnityInstancing.hlsl#L83
    It only compiles to something else if SHADER_API_PSSL is defined and I have no idea what that is


    This can only happen if you include UnityInstancing.hlsl after defining your struct or if you didn't add instancing multi_compile
     
  6. vanger1

    vanger1

    Joined:
    Aug 10, 2020
    Posts:
    10
    You're absolutely right. I was confused with some bug in Unity, I think.

    When I use UNITY_VERTEX_INPUT_INSTANCE_ID in my vertex attributes, and then access instance ID by input.instanceID I get the error message invalid subscript 'instanceID'. But when I hit Play it disappears and everything work fine.

    Unity version used is 2022.3.5f1. 2023.1.6f1 -- the same.
     
    Last edited: Jul 28, 2023