Handwritten HLSL shader SPR Compatible and DOTS_INSTANCING_ON error

Hello dear Unity Developers,

I have this shader which is SPR batcher compatible.

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

        Pass
        {
            HLSLPROGRAM
            // Required to compile gles 2.0 with standard srp library
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            // Will make life easier to have at least URP core.hlsl
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            #pragma vertex vert
            #pragma fragment frag

            // For SRP Batcher to work you need to put things in the right Cbuffer
            CBUFFER_START(UnityPerMaterial)
            half4 _Color;
            CBUFFER_END

            float4 vert(float4 positionOS : POSITION) : SV_POSITION
            {
                // This struct contains commonly used transformations such as Clip, World, etc
                VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS.xyz);
                return vertexInput.positionCS;
            }

            half4 frag() : SV_Target
            {
                return _Color;
            }
            ENDHLSL
        }
    }
}

I want to use this shader on Entities. But when I generate my entities, they are all pink and I get this error:

A BatchDrawCommand is using the pass “<Unnamed Pass 0>” from the shader “UnlitColor” which does not define a DOTS_INSTANCING_ON variant.
This is not supported when rendering with a BatchRendererGroup (or Entities Graphics). MaterialID (0x4) MeshID (0x1) BatchID (0x1)

So I tried a DOTS_INSTANCING_ON pattern using some rare exemples I have found…

Shader "UnlitColor"
{
    Properties
    {
        _Color ("Color", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #include "UnityCG.cginc"

            #pragma target 4.5
            #pragma instancing_options renderinglayer
            #pragma multi_compile _ DOTS_INSTANCING_ON

            struct appdata
            {
                float4 vertex : POSITION;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                UNITY_VERTEX_INPUT_INSTANCE_ID // use this to access instanced properties in the fragment shader.
            };


            // For SRP Batcher to work you need to put things in the right Cbuffer
            // CBUFFER_START(UnityPerMaterial)
            // half4 _Color;
            // CBUFFER_END

            UNITY_INSTANCING_BUFFER_START(Props)
            UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
            UNITY_INSTANCING_BUFFER_END(Props)

            v2f vert(appdata v)
            {
                v2f o;

                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_TRANSFER_INSTANCE_ID(v, o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(i);
                return UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
            }
            ENDCG
        }
    }
}

But now my shader is no longer SRP Batcher compatible. And so I get this error:

A BatchDrawCommand is using a pass from the shader “UnlitColor” that is not SRP Batcher compatible. Reason: “Material property is found in another cbuffer than “UnityPerMaterial”” (_Color)
This is not supported when rendering with a BatchRendererGroup (or Entities Graphics). MaterialID (0x4) MeshID (0x1) BatchID (0x1)

Of course it will be easier to use Shader Graph and I will get no error at all, but my end goal is to add new geometry (it’s for a grass shader) and that’s can not be done with Shader Graph.

I’m on Unity 2022.2.0b16 with Entities Graphics 1.0.0-exp.14

How can I fix this shader?

Any help, advise, resource link or hint will be more than welcome. Thank you all!

It looks like you need to remove the CBUFFER_START block from comments so you will have a constant named Color to match your Shader property named Color. This should make the shader SRP Batcher compatible again. Then you also need to switch from UNITY_INSTANCING macros to UNITY_DOTS_INSTANCING macros.

1 Like

Thank you very much my problem is solved!

1 Like