Search Unity

Resolved Texture Array Shader Missing DOTS_INSTANCING_ON Variant

Discussion in 'Graphics for ECS' started by Wompscepter, Feb 14, 2023.

  1. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    I'm not very familiar with shaders in general, but I'm trying to add a Texture Array to render different textures on my voxel terrain and that requires writing a shader to handle it. I followed the example shown here in the docs:
    https://docs.unity3d.com/2018.3/Documentation/Manual/SL-TextureArrays.html but I'm running into the following DOTS error:

    upload_2023-2-13_21-35-38.png

    My meshes are generated on the fly, so I don't get any benefit from instancing (similar to how chunks are rendered in Minecraft).

    I mostly just want to get a simple shader set up for using a texture array. Like I said, I'm not very familiar with shading and there aren't too many resources yet on creating shaders that are DOTS/SRP/URP compatible, so I'm just looking for extra guidance on how to get this simple shader up and running.

    Any help will be greatly appreciated!
     
  2. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    For the sake of showing what I've tried, I tried adding the following #pragma:

    #pragma multi_compile _ DOTS_INSTANCING_ON

    But then I get the following error:
    upload_2023-2-13_21-47-13.png

    Which makes even less sense than the previous error. I've looked into the CBUFFER_START(UnityPerMaterial) and the UNITY_DOTS_INSTANCED_PROP instructions here: https://docs.unity3d.com/2022.1/Documentation/Manual/dots-instancing-shaders.html but it didn't help with getting rid of the errors (or understanding what the errors mean).
     
  3. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The error message happens if Unity doesn't find the constant buffers that are required to render with BatchRendererGroup. The shader should define at least one block of DOTS instanced properties similar to this example from the manual (and include the UnityInstancing.hlsl file in order to be able to do it).
    Code (CSharp):
    1. UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    2.     UNITY_DOTS_INSTANCED_PROP(float4, Color)
    3. UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    4.  
    Of course, it doesn't need to be a color, it could also be e.g. a transform matrix.

    Typical Unity shaders and Shader Graphs always have at least one already, because the built-in matrices for DOTS_INSTANCING_ON are defined as a built-in DOTS instanced property block, but if you are writing a completely custom shader then you need to define at least one.
     
    Wompscepter likes this.
  4. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    Thank you for the help. I'm now running into an issue where the shader doesn't know what UNITY_DOTS_INSTANCING_START is, even though I believe I'm using all the right #pragmas:
    upload_2023-2-14_7-59-36.png
    Code (CSharp):
    1. Shader "GridColonies/SectorShader"
    2. {
    3.     Properties
    4.     {
    5.         _MyArr ("Tex", 2DArray) = "" {}
    6.         _Color ("Base Colour", Color) = (1, 1, 1, 1)
    7.     }
    8.     SubShader
    9.     {
    10.         Pass
    11.         {
    12.             CGPROGRAM
    13.             #pragma target 4.5
    14.             #pragma vertex vert
    15.             #pragma fragment frag
    16.             // texture arrays are not available everywhere,
    17.             // only compile shader on platforms where they are
    18.             #pragma require 2darray
    19.             #pragma multi_compile _ DOTS_INSTANCING_ON
    20.            
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct v2f
    24.             {
    25.                 float3 uv : TEXCOORD0;
    26.                 float4 vertex : SV_POSITION;
    27.             };
    28.  
    29.             UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) // Error on line 29
    30.                 UNITY_DOTS_INSTANCED_PROP(float4, _Color)
    31.             UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    32.  
    33.             v2f vert (float4 vertex : POSITION)
    34.             {
    35.                 v2f o;
    36.                 o.vertex = UnityObjectToClipPos(vertex);
    37.                 o.uv.xy = (vertex.xy + 0.5);
    38.                 o.uv.z = (vertex.z + 0.5);
    39.                 return o;
    40.             }
    41.            
    42.             UNITY_DECLARE_TEX2DARRAY(_MyArr);
    43.  
    44.             half4 frag (v2f i) : SV_Target
    45.             {
    46.                 return UNITY_SAMPLE_TEX2DARRAY(_MyArr, i.uv);
    47.             }
    48.             ENDCG
    49.         }
    50.     }
    51. }
    Maybe I'm still missing something? I tried adding the CBUFFER_START and end again, but still had the same error with UNITY_DOTS_INSTANCING_START.
     
  5. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    That sounds like you're missing the right include, which should be
    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
     
    Wompscepter likes this.
  6. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    Unfortunately still getting the same error...
    upload_2023-2-14_8-30-40.png
     
  7. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    I think the UNITY_DOTS_INSTANCING_START block needs to be wrapped in
    #ifdef DOTS_INSTANCING_ON
    so it doesn't cause compile errors when the keyword is disabled.
     
    Wompscepter likes this.
  8. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    I'm getting a new error now, which is exciting!

    This looks to be an error inside of Unity's code? It's pointing to UnityDOTSInstancing.hlsl (line 185)
    upload_2023-2-14_9-47-4.png

    Not sure what a real4 is. Is there anything else I'm missing in terms of compatibility?

    upload_2023-2-14_9-45-19.png

    Shader error in 'GridColonies/SectorShader': unrecognized identifier 'real4' at /###/###/###/Library/PackageCache/com.unity.render-pipelines.core@14.0.3/ShaderLibrary/UnityDOTSInstancing.hlsl(185) (on d3d11)
    Compiling Subshader: 0, Pass: <Unnamed Pass 0>, Vertex program with DOTS_INSTANCING_ON
    Platform defines: SHADER_API_DESKTOP UNITY_ENABLE_DETAIL_NORMALMAP UNITY_ENABLE_REFLECTION_BUFFERS UNITY_LIGHTMAP_FULL_HDR UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BLENDING UNITY_SPECCUBE_BOX_PROJECTION UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS
    Disabled keywords: SHADER_API_GLES30 UNITY_ASTC_NORMALMAP_ENCODING UNITY_COLORSPACE_GAMMA UNITY_FRAMEBUFFER_FETCH_AVAILABLE UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_LIGHTMAP_DLDR_ENCODING UNITY_LIGHTMAP_RGBM_ENCODING UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_DXT5nm UNITY_NO_FULL_STANDARD_SHADER UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 UNITY_PBS_USE_BRDF3 UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_UNIFIED_SHADER_PRECISION_MODEL UNITY_VIRTUAL_TEXTURING
     
  9. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    real4 is a compatibility typedef for values that could potentially be compiled to 16-bit arithmetic types on some platforms (as opposed to float4 which will always be a full 32-bit float).

    If you're getting an error about that, then you're probably missing more includes. If you're working with URP, you could try this include:
    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    2.  
    And if you're not working with URP, then perhaps try this:
    Code (CSharp):
    1. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    2. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
    3. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
    4.  
     
    Wompscepter likes this.
  10. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    Found out some more information based on your help:

    1. The URP way of using Texture Arrays is to use the new texture array macros
    2. I needed to remove the #include UnityCG.cginc due to duplicate definitions (Redefinition of "_Time" for example)

    TEXTURE2D_ARRAY() instead of UNITY_DECLARE_TEX2DARRAY()
    SAMPLE_TEXTURE2D_ARRAY() instead of UNITY_SAMPLE_TEX2DARRAY()

    Which results in this modification of the original code:
    Code (CSharp):
    1. TEXTURE2D_ARRAY(_MyArr);
    2. SAMPLER(sampler_MyArr);
    3.  
    4. half4 frag (v2f i) : SV_Target
    5. {
    6.     return SAMPLE_TEXTURE2D_ARRAY(_MyArr, sampler_MyArr, i.uv.xy, i.uv.z);
    7. }


    At this point I only have one remaining issue it seems. I couldn't find any information on this elsewhere, but I'm getting this error now:
    upload_2023-2-15_17-43-20.png

    Here is the full code I have so far with your help:
    Code (CSharp):
    1. Shader "GridColonies/SectorShader"
    2. {
    3.     Properties
    4.     {
    5.         _MyArr ("Tex", 2DArray) = "" {}
    6.         _Color ("Base Colour", Color) = (1, 1, 1, 1)
    7.     }
    8.     SubShader
    9.     {
    10.         Pass
    11.         {
    12.             HLSLPROGRAM
    13.             #pragma target 4.5
    14.             #pragma vertex vert
    15.             #pragma fragment frag
    16.             // texture arrays are not available everywhere,
    17.             // only compile shader on platforms where they are
    18.             #pragma require 2darray
    19.             #pragma multi_compile _ DOTS_INSTANCING_ON
    20.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    21.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
    22.  
    23.             struct v2f
    24.             {
    25.                 float3 uv : TEXCOORD0;
    26.                 float4 vertex : SV_POSITION;
    27.             };
    28.  
    29.             #ifdef DOTS_INSTANCING_ON
    30.                 UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    31.                     UNITY_DOTS_INSTANCED_PROP(float4, _Color)
    32.                 UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    33.                 #define _Color UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, _Color)
    34.             #endif
    35.  
    36.             v2f vert (float4 vertex : POSITION)
    37.             {
    38.                 v2f o;
    39.                 o.vertex = mul(UNITY_MATRIX_MVP, vertex);
    40.                 o.uv.xy = (vertex.xy + 0.5);
    41.                 o.uv.z = (vertex.z + 0.5);
    42.                 return o;
    43.             }
    44.          
    45.             TEXTURE2D_ARRAY(_MyArr);
    46.             SAMPLER(sampler_MyArr);
    47.  
    48.             half4 frag (v2f i) : SV_Target
    49.             {
    50.                 return SAMPLE_TEXTURE2D_ARRAY(_MyArr, sampler_MyArr, i.uv.xy, i.uv.z);
    51.             }
    52.             ENDHLSL
    53.         }
    54.     }
    55. }
     

    Attached Files:

  11. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    I investigated this for a bit. The reason why your shader didn't work is that it didn't set up the instance ID correctly, and as a result the shader compiler removed the DOTS instancing code as unused. This is why Unity thought that there is no DOTS instancing in the shader.

    The version below should work:
    Code (CSharp):
    1.             struct VertexInput
    2.             {
    3.                 float4 pos : POSITION0;
    4.                 #if UNITY_ANY_INSTANCING_ENABLED
    5.                 uint instanceID : INSTANCEID_SEMANTIC;
    6.                 #endif
    7.             };
    8.  
    9.             struct v2f
    10.             {
    11.                 float3 uv : TEXCOORD0;
    12.                 float4 vertex : SV_POSITION;
    13.                 #if UNITY_ANY_INSTANCING_ENABLED
    14.                 uint instanceID : CUSTOM_INSTANCE_ID;
    15.                 #endif
    16.             };
    17.  
    18.             #ifdef DOTS_INSTANCING_ON
    19.                 UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    20.                     UNITY_DOTS_INSTANCED_PROP(float4, _Color)
    21.                 UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    22.                 #define _Color UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, _Color)
    23.             #endif
    24.  
    25.             v2f vert(VertexInput v)
    26.             {
    27.                 v2f o;
    28.  
    29.                 UNITY_SETUP_INSTANCE_ID(v);
    30.                 UNITY_TRANSFER_INSTANCE_ID(v, o);
    31.                 float4 vertex = v.pos;
    32.                 o.vertex = mul(UNITY_MATRIX_MVP, vertex);
    33.                 o.uv.xy = (vertex.xy + 0.5);
    34.                 o.uv.z = (vertex.z + 0.5);
    35.                 return o;
    36.             }
    37.  
    38.             TEXTURE2D_ARRAY (_MyArr);
    39.             SAMPLER (sampler_MyArr);
    40.  
    41.             half4 frag(v2f i) : SV_Target
    42.             {
    43.                 UNITY_SETUP_INSTANCE_ID(i);
    44.  
    45.                 return SAMPLE_TEXTURE2D_ARRAY(_MyArr, sampler_MyArr, i.uv.xy, i.uv.z);
    46.             }
    47.  
     
    Wompscepter likes this.
  12. Wompscepter

    Wompscepter

    Joined:
    Feb 7, 2020
    Posts:
    10
    That worked perfectly! Thank you so much for your help with this JussiKnuuttila, you've been fantastic.

    Here's the resulting product after configuring the shader:
    upload_2023-2-17_23-43-53.png

    And the source code in case anyone else is interested:
    Code (CSharp):
    1. Shader "GridColonies/SectorShader"
    2. {
    3.     Properties
    4.     {
    5.         _MyArr ("Tex", 2DArray) = "" {}
    6.         _Color ("Base Colour", Color) = (1, 1, 1, 1)
    7.     }
    8.     SubShader
    9.     {
    10.         Pass
    11.         {
    12.             HLSLPROGRAM
    13.             #pragma target 4.5
    14.             #pragma vertex vert
    15.             #pragma fragment frag
    16.             // texture arrays are not available everywhere,
    17.             // only compile shader on platforms where they are
    18.             #pragma require 2darray
    19.             #pragma multi_compile _ DOTS_INSTANCING_ON
    20.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    21.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
    22.  
    23.             struct VertexInput
    24.             {
    25.                 float4 pos : POSITION0;
    26.                 float4 tex : TEXCOORD0;
    27.                 #if UNITY_ANY_INSTANCING_ENABLED
    28.                 uint instanceID : INSTANCEID_SEMANTIC;
    29.                 #endif
    30.             };
    31.  
    32.             struct v2f
    33.             {
    34.                 float3 uv : TEXCOORD0;
    35.                 float4 vertex : SV_POSITION;
    36.                 #if UNITY_ANY_INSTANCING_ENABLED
    37.                 uint instanceID : CUSTOM_INSTANCE_ID;
    38.                 #endif
    39.             };
    40.  
    41.             #ifdef DOTS_INSTANCING_ON
    42.                 UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
    43.                     UNITY_DOTS_INSTANCED_PROP(float4, _Color)
    44.                 UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
    45.                 #define _Color UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, _Color)
    46.             #endif
    47.  
    48.             v2f vert (VertexInput v)
    49.             {
    50.                 v2f o;
    51.  
    52.                 UNITY_SETUP_INSTANCE_ID(v);
    53.                 UNITY_TRANSFER_INSTANCE_ID(v, o);
    54.  
    55.                 o.vertex = mul(UNITY_MATRIX_MVP, v.pos);
    56.                
    57.                 // Texture uvs
    58.                 o.uv.xy = v.tex.xy;
    59.  
    60.                 // Texture array index
    61.                 o.uv.z = v.tex.z;
    62.  
    63.                 // Height for tiling the texture
    64.                 o.uv.y *= v.tex.w;
    65.  
    66.                 return o;
    67.             }
    68.            
    69.             TEXTURE2D_ARRAY(_MyArr);
    70.             SAMPLER(sampler_MyArr);
    71.  
    72.             half4 frag (v2f i) : SV_Target
    73.             {
    74.                 UNITY_SETUP_INSTANCE_ID(i);
    75.  
    76.                 return SAMPLE_TEXTURE2D_ARRAY(_MyArr, sampler_MyArr, i.uv.xy, i.uv.z);
    77.             }
    78.             ENDHLSL
    79.         }
    80.     }
    81. }
     
    JussiKnuuttila likes this.