Skip to content
← Back to Blog tutorials

GPU instancing in Unity URP: cut draw calls for repeated props

By BitSoul3D5 min read253 views

GPU instancing in Unity URP cuts draw calls by rendering hundreds of identical meshes in a single GPU batch — the difference between 60 FPS and a slideshow on mid-range hardware. If your scene has repeated props (trees, rocks, barrels, fence posts), and the Unity profiler shows hundreds of draw calls for geometrically identical meshes, instancing is the fix.

GPU instancing in Unity URP: cut draw calls for repeated props

Why draw calls are your enemy

Every time Unity tells the GPU "draw this mesh with this material," that's a draw call. On desktop GPUs you might handle 2,000–3,000 before performance degrades. On mobile, the limit is closer to 200–300.

The trap: a scene with 500 identical barrels doesn't have one draw call per unique mesh — it has 500. Each one carries CPU-side overhead to set state, bind textures, and issue the command. At 500 identical objects, the CPU becomes the bottleneck long before the GPU even breaks a sweat.

The Unity Frame Debugger makes this visible. Open it via Window → Analysis → Frame Debugger, hit Enable, and look for cascading "Draw Mesh" entries with the same mesh name. That's your target.

Why draw calls are your enemy — illustrated

Key terminology before diving in:

TermWhat it means
Draw callOne CPU-to-GPU command to render a mesh
BatchMultiple draw calls merged into one GPU submission
GPU instancingRendering N copies of one mesh in a single draw call with per-instance data (transform, color) on the GPU
SRP BatcherUnity's alternative batching for URP — compatible materials share a CBUFFer, reducing state changes

How GPU instancing works in Unity URP

GPU instancing pushes per-instance data (the transform matrix, any per-object material properties) into a structured GPU buffer. The GPU then runs one draw call that iterates over all instances internally — no CPU round-trip per object.

In Unity URP, instancing works alongside the SRP Batcher, not instead of it. The SRP Batcher handles materials with different property values; GPU instancing handles large counts of the same material on the same mesh. They're complementary.

Three conditions must all be true for instancing to kick in:

  1. Enable GPU Instancing checked on the material
  2. The mesh is a static mesh (or you use Graphics.DrawMeshInstanced / Graphics.RenderMeshInstanced for dynamic objects)
  3. Objects share the same mesh + material combination (no per-object material overrides via renderer.material — use renderer.sharedMaterial)

How GPU instancing works in Unity URP — illustrated

Step-by-step: enabling GPU instancing in Unity URP

Step 1 — Enable instancing on the material

In the Inspector for any URP Lit or Unlit material, check Enable GPU Instancing. That's it for built-in URP shaders — they already have the #pragma multi_compile_instancing directive.

For custom ShaderGraph shaders:

Step 2 — Mark objects as Static (or use DrawMesh APIs for dynamic)

For environment props that don't move: select them in the scene, tick Static in the Inspector header. Unity's static batching and GPU instancing are separate systems — for instancing specifically, objects don't need to be static, but they do need to share materials. Static batching actually prevents instancing because it merges meshes at build time into one combined mesh. Choose one:

For runtime-spawned objects (particles, procedural props), use Graphics.RenderMeshInstanced:

// Cache the render params once
RenderParams rp = new RenderParams(instancedMaterial);
rp.worldBounds = new Bounds(Vector3.zero, Vector3.one * 1000f);
rp.matProps = new MaterialPropertyBlock();

// In Update or via ComputeShader
Matrix4x4[] matrices = GetInstanceMatrices(); // your data
Graphics.RenderMeshInstanced(rp, mesh, 0, matrices);

This bypasses GameObjects entirely — zero MonoBehaviour overhead, pure GPU throughput.

Step 3 — Avoid the renderer.material trap

Accessing renderer.material (not renderer.sharedMaterial) creates a material clone per object. That breaks instancing immediately — Unity can't batch materials with different instance IDs.

// WRONG — creates unique material per object, kills instancing
renderer.material.color = tint;

// CORRECT — use MaterialPropertyBlock for per-instance overrides
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
renderer.GetPropertyBlock(mpb);
mpb.SetColor("_BaseColor", tint);
renderer.SetPropertyBlock(mpb);

MaterialPropertyBlock lets you vary per-instance data (color, UV offset, float params) without breaking the batch. Unity serializes these into the instanced data buffer automatically.

When instancing fails — and what to do instead

GPU instancing has hard limits:

Skinned meshes — instancing doesn't work on SkinnedMeshRenderer. For large crowds, use Vertex Animation Textures (VATs) to bake animations into textures, then render with MeshRenderer + instancing.

Shadow casting — by default, each instanced object still generates shadow draw calls. For thousands of distant props, disable shadow casting on the renderer or use LOD groups with shadows disabled at LOD2+.

1023 instance limit per batch — Graphics.DrawMeshInstanced caps at 1023 instances per call. Graphics.RenderMeshInstanced (Unity 2022+) removes this limit via indirect rendering.

SRP Batcher conflicts — the SRP Batcher and GPU instancing are mutually exclusive on a per-object basis. If the SRP Batcher is active (it's on by default in URP), instancing only activates for objects using Graphics.DrawMeshInstanced. For scene GameObjects, the SRP Batcher takes priority. Profile both paths — for 10–50 objects, SRP Batcher usually wins; for 200+ identical objects, force instancing via the DrawMesh APIs.

Check which path your objects are using: in the Frame Debugger, look for "Instanced" vs "SRP Batch" labels on draw calls.

Quick checklist before profiling

Browse the BitSoul marketplace for 747 free GLB props — all game-ready and optimized for instancing workflows in Unity, Unreal Engine 5, and Godot.


This post is part of the Ultimate Guide to Free 3D Game Assets — BitSoul's complete reference for formats, texturing, rigging, optimization, and engine integration.


Need drop-in assets for this workflow? Grab the 70-model Food Bundle on the BitSoul marketplace and drop them straight into your project.

Tags: food

Skip the modeling — download it instead

A free BitSoul3D account gets you 2 GLB downloads every month for personal use plus 25 one-time AI Engine credits, no card required. PBR-textured GLB downloads with a full 3D preview before you buy, for Unreal, Unity, Godot or Blender — OBJ and 3D-printable STL come with any purchase or paid plan.

Browse 1,051 models — from $4.99 → or start free (2 downloads a month)