SCRAPS

Dev Notes

A Practical Guide to Unity Draw Call Batching: Dynamic Batching Unity Relies On and Unity Combine Meshes Techniques

Unity draw call batching is one of those topics where the received wisdom is a decade out of date, and most of what circulates as a unity dynamic batching tutorial hasn't caught up. Plenty of guides still explain how to reduce draw calls by merging meshes, and that advice was correct once. It just answers a question modern Unity render pipelines mostly don't ask anymore, because the bottleneck it was solving has moved.

This piece covers both sides honestly: the older static and dynamic batching model, a genuinely clever 2015 technique for batching independently-moving vehicle parts, and what actually determines rendering performance in a current Unity project using URP or HDRP. If you're profiling a slow scene right now, skip to the SRP Batcher section: that's almost certainly where your answer is.

Schematic diagram of scattered angular polygon fragments converging via dimension lines toward one combined shape
FIG. 01 Draw Call Batching — Parts Into One Mesh

What Unity Draw Call Batching Actually Means for Performance

A draw call is an instruction from the CPU telling the GPU to render something: this mesh, with this material, at this transform. Each one carries overhead on the CPU side, and a scene with thousands of small separate objects can spend more time issuing draw calls than the GPU spends actually drawing pixels. Unity draw call batching, broadly, is any technique that reduces that overhead, whether by merging objects into fewer draw calls or by making each individual draw call cheaper to issue. Those are two different problems, and conflating them is the single most common mistake in this area.

The distinction matters because the two eras of Unity rendering solved different halves of it. The classic approach, still worth understanding, attacked draw call count directly.

Static and Dynamic Batching Unity Shipped With for Years

How the old batching model worked

Static batching combines non-moving objects that share a material into a single mesh at build time, provided they're all marked static in the inspector. The old dynamic batching Unity shipped for years did the same thing for small moving objects, at runtime, transforming their vertices on the CPU each frame so they could still be issued as one draw call. Both were genuinely useful when they applied, and both came with real limits: dynamic batching capped out at a low vertex count per object, broke the moment two objects used different material instances, and cost CPU time doing the vertex transforms it was supposedly saving you from.

A unity dynamic batching tutorial written before 2018 is worth reading for the mental model. It's not worth following for the exact settings, most of which have either moved, changed default values, or stopped applying once a project switches to a Scriptable Render Pipeline. Dynamic batching Unity still ships as a legacy feature under the built-in render pipeline, but URP and HDRP projects rarely lean on it, because the pipeline replaced the whole approach rather than tuning it. Bookmark a unity dynamic batching tutorial for the historical context if you like, but validate every setting it recommends against your current Unity version before trusting any of it in production.

A 2015 Trick: Batching Independently Moving Vehicle Parts With Unity Combine Meshes

Merging static geometry is one thing. Merging geometry that keeps moving independently is a harder problem, and it's where the more interesting historical technique lives. That's the essence of what people mean by unity combine meshes today when the goal is a single draw call: taking several separate meshes sharing a material and folding them into one, so the renderer issues one draw call instead of many.

Detail — A period-accurate technique

In a September 2015 Game Developer article, Bill Borman, the developer of Scraps, described a way to batch a vehicle's independently-moving parts into a single draw call by reusing Unity's skeletal animation system. Rather than treating each moving part as its own GameObject, the parts were combined into one mesh and driven as "bones" the way a character rig would be, letting the GPU handle the per-vertex transforms on DirectX11-and-later hardware instead of the CPU. In Borman's own words, the approach was to "combine everything, and have the GPU do the transforms directly on the vertices of the parts that move." Bill Borman's 2015 approach to unity combine meshes went further than a simple static combine, precisely because the parts in question never stopped moving. The full article is publicly available: Game Developer — "Unity 3D: Batching independently moving GameObjects into a single mesh to reduce draw calls".

The unity combine meshes performance win in that kind of setup was always about draw call count specifically: one vehicle, one draw call, regardless of how many wheels or turrets were rotating independently on it. It's a technique worth knowing even now, particularly for any project still targeting the built-in render pipeline, or any case where the GPU Resident Drawer path described below simply doesn't apply.

The SRP Batcher, GPU Resident Drawer, and Forward+ Today

A different mechanism, not a faster version of the old one

Here's the part that trips up anyone applying old knowledge to a new project: URP and HDRP's SRP Batcher does not reduce the number of draw calls at all. It makes each draw call cheaper by caching per-material shader properties on the GPU, so switching between objects that share a shader variant no longer requires re-uploading that data every time. Fewer, larger CPU-to-GPU transfers per frame, not fewer draw calls. That's a fundamentally different mechanism from static or dynamic batching, and it's why a scene can be "SRP Batcher compatible" and still issue exactly as many draw calls as before, just far more cheaply.

Layered on top of that in current Unity is the GPU Resident Drawer, which can operate in an "Instanced Drawing" mode, alongside the Forward+ rendering path, both aimed at the same underlying goal: keep the CPU out of the way of the GPU as much as possible. None of this eliminates the value of actually reducing object count in a scene. It just changes which lever you pull first. Chasing unity combine meshes performance gains by hand is far less necessary once the SRP Batcher and GPU Resident Drawer are already doing that job for you.

The MaterialPropertyBlock gotcha

One silent performance regression shows up constantly in real projects: using a MaterialPropertyBlock on a renderer to tweak a per-instance shader value makes that renderer incompatible with the SRP Batcher, and it also blocks the GPU Resident Drawer path from picking it up. The code still runs. Nothing throws an error. The renderer just quietly drops out of the fast path, and the only way to notice is checking the Frame Debugger or the pipeline's batching statistics directly.

Any serious unity draw call optimization pass today starts there: profile with the Frame Debugger, confirm what's actually SRP Batcher-compatible, and only then decide whether manual mesh combining is worth the maintenance cost it adds. The single biggest unity draw call optimization mistake left over from older habits is assuming the SRP Batcher reduces draw call count the way old batching did. It doesn't, and treating it as if it does will send you looking for the wrong number in the profiler.

Frequently Asked Questions

What is draw call batching in Unity?

Unity draw call batching refers to techniques that reduce the CPU overhead of issuing render instructions to the GPU, either by combining multiple objects into fewer draw calls or by making each draw call itself cheaper to issue. The two goals use different mechanisms and shouldn't be assumed to be the same optimization.

Does the SRP Batcher reduce the number of draw calls?

No. This is the most common misunderstanding about it. The SRP Batcher makes each draw call cheaper by caching shader properties on the GPU rather than reducing draw call count, which is what older static and dynamic batching did instead.

Is dynamic batching still relevant in Unity?

Dynamic batching still exists as a legacy feature of the built-in render pipeline, but URP and HDRP projects generally don't rely on it, since the SRP Batcher and GPU Resident Drawer address the same underlying cost through a different, more effective mechanism.

How do you combine meshes in Unity for better performance?

For static geometry sharing a material, Unity can combine meshes automatically at build time via static batching. For geometry that moves independently, a manual combine is more involved; one documented approach reuses Unity's skeletal animation system, treating moving parts as bones of a single combined mesh so the GPU handles the transforms.

What breaks SRP Batcher compatibility?

Using a MaterialPropertyBlock to set a per-instance shader property on a renderer is a common cause; it opts that renderer out of the SRP Batcher path and also prevents the GPU Resident Drawer from picking it up, silently, with no warning in the console.

What is the GPU Resident Drawer?

It's a rendering feature that can operate in an instanced-drawing mode, working alongside the SRP Batcher and the Forward+ rendering path, aimed at keeping the CPU from becoming the bottleneck as scene object counts grow.

How do I check if my scene's draw calls are actually a problem?

Open the Frame Debugger and step through the frame's draw calls directly, and check the pipeline's batching statistics to see how many objects are actually SRP Batcher-compatible. Guessing which meshes to manually combine without profiling first usually wastes engineering time on the wrong fix.

Is manually combining meshes still worth doing?

Sometimes, particularly on the built-in render pipeline or in cases the GPU Resident Drawer doesn't cover well. But it adds real maintenance cost, and on a modern URP or HDRP project it's worth confirming the SRP Batcher and GPU Resident Drawer aren't already handling the cost before committing engineering time to a manual combine.

Why did older Unity vehicle games need custom batching tricks?

Before the SRP Batcher existed, a vehicle built from many independently-moving parts, wheels, turrets, hinged panels, would otherwise cost one draw call per part. Reusing the skeletal animation system to drive those parts as bones of one combined mesh was a way to bring that back down to a single draw call per vehicle.

Where can I read more on Unity's official batching documentation?

Unity's manual covers the SRP Batcher directly: docs.unity3d.com — SRP Batcher. For a deeper practical breakdown of draw call optimization decisions, thegamedev.guru has a dedicated write-up: thegamedev.guru — Draw Call Optimization.

Conclusion

Unity draw call batching hasn't stopped mattering; it's just stopped being one thing. The old static and dynamic batching model earned its keep for years by directly cutting draw call count, and Bill Borman's bone-rig trick for moving vehicle parts is still a legitimate answer for anyone stuck on the built-in pipeline. On URP or HDRP today, though, the SRP Batcher and GPU Resident Drawer solve a related but distinct cost, and reaching for a manual mesh combine before checking whether those two are already doing their job is how projects end up "optimizing" a number that was never actually the bottleneck.

Check the Frame Debugger before you touch a single mesh.