Instancing not rendering with custom shader

How can I set up a shader for instancing through either Graphics.DrawMeshInstancedProcedural or Graphics.RenderMeshPrimitives. Both of them work when I use the default URP Lit shader but when I use my custom shader it just disappears. So how can I make it work with my own shaders?

Shader:

Shader "Custom/GrassDebugShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass 
        {
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #pragma target 4.5

            #include "HLSLSupport.cginc"
            #include "UnityCG.cginc"

            CBUFFER_START(UnityPerMaterial)
            float4 _Color;    
            CBUFFER_END

            struct Attributes
            {
                float3 positionOS : POSITION;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
            };

            Varyings vert(Attributes IN, uint instanceID : SV_InstanceID, uint vertexID : SV_VertexID)
            {
                Varyings OUT;

                float3 worldPosition = IN.positionOS;

                OUT.positionCS = mul(UNITY_MATRIX_MVP, float4(worldPosition, 1));


                return OUT;
            }

            fixed4 frag(Varyings IN) : SV_Target
            {
                return fixed4(_Color);
            }

            ENDHLSL
        }
    }
    FallBack "Diffuse"
}

C#:

using UnityEngine;

public class GrassInstancingDebugger : MonoBehaviour
{
    public Material material;
    public Mesh mesh;
    public int instanceCount = 10000;
    private RenderParams renderParams;

    private void Start()
    {
        renderParams = new RenderParams(material);
        renderParams.worldBounds = new Bounds(Vector3.zero, Vector3.one * 1000);
    }

    private void Update()
    {
        //Graphics.RenderMeshPrimitives(renderParams, mesh, 0, instanceCount);
        Graphics.DrawMeshInstancedProcedural(mesh, 0, material, renderParams.worldBounds, instanceCount);
    }

i don’t know if this is causing your problem, but to support instancing i believe you need to add this line
UNITY_SETUP_INSTANCE_ID(IN);
right above where you initialize varyings in the vertex shader.

this is required in my shaders in 2019.4, not sure about unity 6, but i don’t see why it would change.

Tried it with different versions of setup_instance_id and transfer_instance_id but nothing really changed

I think you’re missing the render pipeline tag.

Still not working sadly…

Shader "Custom/GrassDebugShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
        }

        Pass 
        {
            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #pragma target 4.5

            #include "HLSLSupport.cginc"
            #include "UnityCG.cginc"

            CBUFFER_START(UnityPerMaterial)
            float4 _Color;    
            CBUFFER_END

            struct Attributes
            {
                float3 positionOS : POSITION;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
            };

            Varyings vert(Attributes IN, uint instanceID : SV_InstanceID, uint vertexID : SV_VertexID)
            {
                Varyings OUT;

                float3 worldPosition = IN.positionOS;

                OUT.positionCS = mul(UNITY_MATRIX_VP, float4(worldPosition, 1));


                return OUT;
            }

            fixed4 frag(Varyings IN) : SV_Target
            {
                return fixed4(_Color);
            }

            ENDHLSL
        }
    }
    FallBack "Diffuse"
}

Does your shader work without instanced rendering?

No, even when I just create a cube and assign the material with the shader it doesn’t work

Well, I suppose you should fix that first and then check instanced rendering :slight_smile:

well, how though? I really dont know what i’m doing wrong

I’m pretty sure there are plenty of topics around on how to create a basic shader for e.g. URP.

These were the tags that fixed it if anyone is interested:

"RenderPipeline" = "UniversalPipeline"
"Queue"="AlphaTest+51"
1 Like