I have a test project started in 2021.3.2, which I upgraded to 2022.1.5, and now GPU instancing with instanced properties is broken.
Specifically, I have a test project that spawns 20k objects, and a shader graph shader that uses instance properties to modulate their emissive intensity on a per-object basis. The property is defined in the shader blackboard as “shader declaration = hybrid per instance”. The material is set to enable GPU instancing.
This worked correctly in 2021.3, all the instances got GPU instanced, and drawn in a few dozen passes, like so:
However, after upgrade to 2022.1, this is broken, and each individual building gets drawn in its own draw call:
The frame debugger message “Non-instanced properties set for instanced shader” is extra confusing, as the instance property is set in the shader graph editor as “hybrid per instance”.
Looking at compiled shader, it looks like the main difference between 2021 and 2022 is that in the old correct version, the instance property got correctly declared using UNITY_DEFINE_INSTANCED_PROP:
// Injected Instanced Properties (must be included before UnityInstancing.hlsl)
#if defined(UNITY_HYBRID_V1_INSTANCING_ENABLED)
#define HYBRID_V1_CUSTOM_ADDITIONAL_MATERIAL_VARS \
UNITY_DEFINE_INSTANCED_PROP(float, _Emission_Multiplier)
#define UNITY_ACCESS_HYBRID_INSTANCED_PROP(var, type) UNITY_ACCESS_INSTANCED_PROP(unity_Builtins0, var)
#else
#define UNITY_ACCESS_HYBRID_INSTANCED_PROP(var, type) var
#endif
// -- Graph Properties
CBUFFER_START(UnityPerMaterial)
...
#ifdef UNITY_HYBRID_V1_INSTANCING_ENABLED
float _Emission_Multiplier_dummy;
#else
float _Emission_Multiplier;
#endif
CBUFFER_END
Meanwhile in 2022 it gets added to CBUFFER instead, which is clearly incorrect
// -- Graph Properties
CBUFFER_START(UnityPerMaterial)
...
// Hybrid instanced properties
float _Emission_Multiplier;
CBUFFER_END
#if defined(UNITY_DOTS_INSTANCING_ENABLED)
// DOTS instancing definitions
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float, _Emission_Multiplier)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
TLDR: looks like shader graph shaders compiled in 2022.1 break GPU instancing. Is there any fix for this? Because otherwise, that’s a severe performance regression.