Search Unity

Resolved Handwritten HLSL shader SPR Compatible and DOTS_INSTANCING_ON error

Discussion in 'Graphics for ECS' started by Chmyke, Nov 30, 2022.

  1. Chmyke

    Chmyke

    Joined:
    Aug 1, 2012
    Posts:
    34
    Hello dear Unity Developers,

    I have this shader which is SPR batcher compatible.
    Code (CSharp):
    1. Shader "UnlitColor"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,1)
    6.     }
    7.     SubShader
    8.     {
    9.         Tags
    10.         {
    11.             "RenderType"="Opaque"
    12.         }
    13.  
    14.         Pass
    15.         {
    16.             HLSLPROGRAM
    17.             // Required to compile gles 2.0 with standard srp library
    18.             #pragma prefer_hlslcc gles
    19.             #pragma exclude_renderers d3d11_9x
    20.             // Will make life easier to have at least URP core.hlsl
    21.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    22.  
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.  
    26.             // For SRP Batcher to work you need to put things in the right Cbuffer
    27.             CBUFFER_START(UnityPerMaterial)
    28.             half4 _Color;
    29.             CBUFFER_END
    30.  
    31.             float4 vert(float4 positionOS : POSITION) : SV_POSITION
    32.             {
    33.                 // This struct contains commonly used transformations such as Clip, World, etc
    34.                 VertexPositionInputs vertexInput = GetVertexPositionInputs(positionOS.xyz);
    35.                 return vertexInput.positionCS;
    36.             }
    37.  
    38.             half4 frag() : SV_Target
    39.             {
    40.                 return _Color;
    41.             }
    42.             ENDHLSL
    43.         }
    44.     }
    45. }

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

    Code (CSharp):
    1. Shader "UnlitColor"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1, 1, 1, 1)
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags
    11.         {
    12.             "RenderType"="Opaque"
    13.         }
    14.         LOD 100
    15.  
    16.         Pass
    17.         {
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #pragma multi_compile_instancing
    22.             #include "UnityCG.cginc"
    23.  
    24.             #pragma target 4.5
    25.             #pragma instancing_options renderinglayer
    26.             #pragma multi_compile _ DOTS_INSTANCING_ON
    27.  
    28.             struct appdata
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    32.             };
    33.  
    34.             struct v2f
    35.             {
    36.                 float4 vertex : SV_POSITION;
    37.                 UNITY_VERTEX_INPUT_INSTANCE_ID // use this to access instanced properties in the fragment shader.
    38.             };
    39.  
    40.  
    41.             // For SRP Batcher to work you need to put things in the right Cbuffer
    42.             // CBUFFER_START(UnityPerMaterial)
    43.             // half4 _Color;
    44.             // CBUFFER_END
    45.  
    46.             UNITY_INSTANCING_BUFFER_START(Props)
    47.             UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
    48.             UNITY_INSTANCING_BUFFER_END(Props)
    49.  
    50.             v2f vert(appdata v)
    51.             {
    52.                 v2f o;
    53.  
    54.                 UNITY_SETUP_INSTANCE_ID(v);
    55.                 UNITY_TRANSFER_INSTANCE_ID(v, o);
    56.                 o.vertex = UnityObjectToClipPos(v.vertex);
    57.                 return o;
    58.             }
    59.  
    60.             fixed4 frag(v2f i) : SV_Target
    61.             {
    62.                 UNITY_SETUP_INSTANCE_ID(i);
    63.                 return UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
    64.             }
    65.             ENDCG
    66.         }
    67.     }
    68. }
    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!
     
  2. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    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.
     
    Chmyke likes this.
  3. Chmyke

    Chmyke

    Joined:
    Aug 1, 2012
    Posts:
    34
    Thank you very much my problem is solved!
     
    JussiKnuuttila likes this.