Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

GPU Instancing in URP

Discussion in 'Shaders' started by nikk98, May 17, 2022.

  1. nikk98

    nikk98

    Joined:
    Mar 8, 2021
    Posts:
    43
    I'm sorry for the double posting, I posted this in the URP forum as well, but maybe here is more appropriate.

    Hello,
    I'm trying to change the Simple Lit shader to use GPU instancing for two variables. The hlsl file I include looks something like this:

    Code (CSharp):
    1.  
    2. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"
    3.  
    4. TEXTURE2D_ARRAY(_AnimTextures);
    5. SAMPLER(sampler_AnimTextures);
    6. UNITY_INSTANCING_BUFFER_START(Props)
    7.     UNITY_DEFINE_INSTANCED_PROP(float4, _AnimTextureOffset)
    8.     UNITY_DEFINE_INSTANCED_PROP(float4, _AnimScaler)
    9. UNITY_INSTANCING_BUFFER_END(Props)
    10.  
    Also
    #pragma multi_compile_instancing

    is included in the main shader file.

    The shader fails to compile because it doesn't find the two variables declared.

    Code (CSharp):
    1.  
    2. Shader error in 'AnimationInstancing/[GpuInstancing] Simple Lit': undeclared identifier '_AnimTextureOffset' at Assets/Scripts/AnimationInstancing/EntitiesAnimator/ShaderMeshAnimator/Shaders/GpuInstancing/AnimationInstancing.hlsl(72) (on metal)
    3. Compiling Vertex program with INSTANCING_ON
    4. Platform defines: UNITY_COLORSPACE_GAMMA UNITY_ENABLE_REFLECTION_BUFFERS UNITY_LIGHTMAP_DLDR_ENCODING UNITY_NO_CUBEMAP_ARRAY UNITY_NO_DXT5nm UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2
    5. Disabled keywords: DIRLIGHTMAP_COMBINED DOTS_INSTANCING_ON FOG_EXP FOG_EXP2 FOG_LINEAR LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADER_API_GLES30 SHADOWS_SHADOWMASK UNITY_ASTC_NORMALMAP_ENCODING UNITY_ENABLE_DETAIL_NORMALMAP UNITY_ENABLE_NATIVE_SHADOW_LOOKUPS UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS UNITY_HARDWARE_TIER1 UNITY_HARDWARE_TIER2 UNITY_HARDWARE_TIER3 UNITY_LIGHTMAP_FULL_HDR UNITY_LIGHTMAP_RGBM_ENCODING UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_METAL_SHADOWS_USE_POINT_FILTERING UNITY_NO_FULL_STANDARD_SHADER UNITY_PBS_USE_BRDF1 UNITY_PBS_USE_BRDF3 UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION UNITY_SPECCUBE_BLENDING UNITY_SPECCUBE_BOX_PROJECTION UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_VIRTUAL_TEXTURING _ADDITIONAL_LIGHTS _ADDITIONAL_LIGHTS_VERTEX _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _NORMALMAP _RECEIVE_SHADOWS_OFF
    6.  
    I have a similar shader working in the default pipeline (there including the macros with
    "#include <UnityInstancing.cginc>")
    That one works fine.

    I think I'm missing the right declarations for hlsl.

    I know about the SRP Batcher but my benchmarking shows that while is much better in new, expensive phones like the pixel 6, GPU Instancing performs much better in older phones - at least when comparing URP/SRPBatcher with Default/GPUInstancing.


    Any help will be highly appreciated!
     
  2. nikk98

    nikk98

    Joined:
    Mar 8, 2021
    Posts:
    43
    I found the solution.

    The way unity magic instancing macros work in HLSL is as follows:

    1. Declare the parameters, e.g. after the Varyings declaration like so:

    Code (CSharp):
    1.  
    2. #if (SHADER_TARGET < 30 || SHADER_API_GLES)
    3.     uniform float4 _AnimTextureOffset;
    4.     uniform float4 _AnimScaler;
    5. #else
    6. UNITY_INSTANCING_BUFFER_START(Props)
    7.     UNITY_DEFINE_INSTANCED_PROP(float4, _AnimTextureOffset)
    8.     #define _AnimTextureOffset_arr Props
    9.     UNITY_DEFINE_INSTANCED_PROP(float4, _AnimScaler)
    10.     #define _AnimScaler_arr Props
    11. UNITY_INSTANCING_BUFFER_END(Props)
    12. #endif
    13.  
    2. Assign the parameters before you use them in a function:
    Code (CSharp):
    1.  
    2. #if (SHADER_TARGET < 30 || SHADER_API_GLES)
    3.     float4 animTextureOffset = _AnimTextureOffset;
    4.     float4 animScaler = _AnimScaler;
    5. #else
    6.     float4 animTextureOffset = UNITY_ACCESS_INSTANCED_PROP(_AnimTextureOffset_arr, _AnimTextureOffset);
    7.     float4 animScaler = UNITY_ACCESS_INSTANCED_PROP(_AnimScaler_arr, _AnimScaler);
    8. #endif
    9.  
    No need to include the UnityInstancing.hlsl file I mentioned before.