In Unity 6.6 (6000.6.0a5), we’re adding Preprocessor Directives to Shader Graph, allowing you to add Pragmas, Defines and Includes to the shader without relying on Custom Function Nodes.
Here’s a concrete example of how you can use this to enable GPU instancing on a Particle Shader.
TL;DR; While shader graph shaders do support GPU instancing, they don’t implement Procedural instancing. As a result, when used on a Particle System set to Mesh Render Mode, GPU Instancing is disabled, and Dynamic Batching is used instead, which hits performance pretty badly as vertices are transformed on the CPU.
With the new Preprocessor Directives, you can :
- Add the pragma:
instancing_options procedural:ParticleInstancingSetup
The function ParticleInstancingSetup is located in URP’s ShaderLibrary.
- Include the file
Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl
When instancing is enabled, the Particles Color is not stored in Vertex Color, but in Particle Data.
This requires using a Custom Function Node to get the particle’s color.
#if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
#if !defined(UNITY_PARTICLE_INSTANCE_DATA_NO_COLOR)
UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID];
color = lerp(half4(1.0, 1.0, 1.0, 1.0), color, unity_ParticleUseMeshColors);
color *= half4(UnpackFromR8G8B8A8(data.color));
#endif
#endif
Color = color;
As a result, the Particle System is rendered with GPU Instancing instead of Dynamic Batching, which is a lot more efficient.
We shall update graph templates and samples to take advantage of this.
I’ll share more details later.




