Quick answer: Set keyword Scope = Local and Definition = Shader Feature. Override per-property declaration to UnityPerMaterial. Material → Enable GPU Instancing on. Frame Debugger shows “Draw Mesh (Instanced)” on batched calls.
Add a USE_DETAIL keyword to a Shader Graph. Frame Debugger goes from one instanced draw to one draw per renderer. Global keyword scope broke the per-material CBUFFER assumption.
The Symptom
GPU Instancing stops batching after a shader change. SetPass calls climb. Per-renderer draws appear in Frame Debugger.
The Fix
In the Blackboard, click the keyword:
Reference: _USE_DETAIL
Scope: Local
Definition: Shader Feature
Local + Shader Feature emits a per-material keyword that stays inside the UnityPerMaterial CBUFFER — SRP Batcher and DOTS Instancing both compatible.
For every property used in the shader, set Override Property Declaration to UnityPerMaterial (not Global) so they stay in the CBUFFER too.
Material Setting
Material Inspector:
Enable GPU Instancing: true
Without this checkbox, no instancing regardless of shader. With local keyword and instancing on, batches recover.
Verifying
Frame Debugger. Find your draws. Should read “Draw Mesh (Instanced) Count: N” instead of N separate “Draw Mesh” calls. Stats overlay confirms lower SetPass calls.
“Local + Shader Feature. UnityPerMaterial. Enable GPU Instancing. Batching restored.”
Related Issues
For SRP Batcher, see SRP Batcher. For Shader Graph keyword stripping, see keyword stripping.
Local keyword. UnityPerMaterial. Instancing batches.