GPU Instancing in URP

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:

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"

TEXTURE2D_ARRAY(_AnimTextures);
SAMPLER(sampler_AnimTextures);
UNITY_INSTANCING_BUFFER_START(Props)
    UNITY_DEFINE_INSTANCED_PROP(float4, _AnimTextureOffset)
    UNITY_DEFINE_INSTANCED_PROP(float4, _AnimScaler)
UNITY_INSTANCING_BUFFER_END(Props)

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.

Shader error in 'AnimationInstancing/[GpuInstancing] Simple Lit': undeclared identifier '_AnimTextureOffset' at Assets/Scripts/AnimationInstancing/EntitiesAnimator/ShaderMeshAnimator/Shaders/GpuInstancing/AnimationInstancing.hlsl(72) (on metal)
Compiling Vertex program with INSTANCING_ON
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
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

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!

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:
#if (SHADER_TARGET < 30 || SHADER_API_GLES)
    uniform float4 _AnimTextureOffset;
    uniform float4 _AnimScaler;
#else
UNITY_INSTANCING_BUFFER_START(Props)
    UNITY_DEFINE_INSTANCED_PROP(float4, _AnimTextureOffset)
    #define _AnimTextureOffset_arr Props
    UNITY_DEFINE_INSTANCED_PROP(float4, _AnimScaler)
    #define _AnimScaler_arr Props
UNITY_INSTANCING_BUFFER_END(Props)
#endif
  1. Assign the parameters before you use them in a function:
#if (SHADER_TARGET < 30 || SHADER_API_GLES)
    float4 animTextureOffset = _AnimTextureOffset;
    float4 animScaler = _AnimScaler;
#else
    float4 animTextureOffset = UNITY_ACCESS_INSTANCED_PROP(_AnimTextureOffset_arr, _AnimTextureOffset);
    float4 animScaler = UNITY_ACCESS_INSTANCED_PROP(_AnimScaler_arr, _AnimScaler);
#endif

No need to include the UnityInstancing.hlsl file I mentioned before.