Why isn't GPU Instancing enabled by default on materials?

I figure there's something I'm missing about GPU Instancing on materials, but to me it seems like it should be enabled by default, on my assumption that it leads to better performance. What's the reason it's disabled by default?

When enabled it disables dynamic batching and if it was enabled by default it would change behaviour of old projects.

1 Like

Ah, that's very helpful. I've been enabling GPU instancing for materials I only put on moving objects, but it sounds like I'm doing it wrong. For moving objects, I should leave GPU Instancing disabled, and let Dynamic Batching do the work?

Dynamic batching only works on small meshes, for larger stuff instancing is better.

2 Likes

I guess I'm still a little confused. I quickly tested out disabling GPU Instancing on some materials that are used only on moving objects. Here's the before stats, with GPU instancing enabled on the materials:

3858088--326806--upload_2018-11-5_10-54-27.png

and here's the after, turning off GPU instancing:

3858088--326809--upload_2018-11-5_10-54-53.png

It seems like the first version, with GPU instancing enabled on my dynamic objects, results in many fewer batches. So maybe I still don't understand GPU instancing.

look here

Thanks.

Note that on platforms that do not support GPU instancing (e.g. <OpenGLES 3.0), dynamic batching will still work just fine if built with enabled GPU instancing.

So, it's always nice to have it enabled. I haven't seen a case when it wasn't worth enabling it.

Also, keep in mind that dynamic batching will break batches, if even one property of the material is different.

Because in most cases
it is slower when material GPU Instancing is enabled, even on your screenshot it give you less FPS as you see.

Better not touch it or implement your own gpu instancing

i've just observed HUGE slow down when enabling instancing, but instancing isn't actually possible. so there seems to be a good amount of overhead when Unity even TRIES to instance.

GPU instancing should be used exclusively when objects are the same mesh (obviously), are dynamic and there are a lot of them in the same render. Otherwise, disable it!

4 Likes

[quote=“Darkgaze”, post:11, topic: 720571]
GPU instancing should be used exclusively when objects are the same mesh (obviously), are dynamic and there are a lot of them in the same render. Otherwise, disable it!
[/quote]
Hi Lidia, I’m going to test it in my project however I am not sure how much it can help: my project is an RTS where most unit models are used less than 50x times across the entire map and less than 15x times on the average screen.

When I add units to the game the rendering work on the CPU shoots up - I’ve noticed that it is not the case when I switch to using Entities with the Hybrid Renderer v2 and as I understand this is mainly because the Hybrid Renderer v2 has an advanced GPU rendering module

Using unity terrain with standard Tree Creator. In built in render pipeline. I enable GPU instancing on the material of the trees... no instancing whatsoever going on. Literally drawing the barks and leafs one by one. I searched the forum and it's known issue and broken since 2017 at least. I mean, the main usage of GPU instancing would be on terrain trees. So... what gives?

[quote=“creat327”, post:13, topic: 720571]
standard Tree Creator
[/quote]
Yeah, don’t use it. If you’re using built-in - SpeedTree is decent.
As well as Mtree could be worth investigating (has same in Unity Editor features, and instancing / indirect instancing support).

Yeah, this should really be a configurable option, per project, and enabled by default for new projects. (Eg "Project Settings/Editor/Enable GPU instancing on new Materials" or something)

In the majority of recent projects I've worked on, (Mostly mobile, across a wide range of target devices), disabling GPU instancing in favour of dynamic batching is the exception, not the norm.

GPU instancing can replace dynamic batching in pretty much any situation.

Objects will only dynamic batch if they share the same material, and are under the 900 vertex attribute limit. It also does not allow for per-object data, and also is incompatible with several shader techniques.

Using Instancing instead of Dynamic Batching means objects that share the same material, but not the same mesh will increase draw calls, but your SetPass calls should stay the same, and SetPass calls impact performance a lot more than draw calls. This frees the CPU from having to manually transform all of your dynamic-batched vertex attributes from object to world space every frame.

Perhaps the only situation in which dynamic batch still wins, is with very small meshes. (I'd say less than 32 vertices)
As the GPU dispatches workloads in 32-64 threads, and there is one thread per vertex. So if there's only 4 vertices, eg a single quad, you're wasting 28 or more threads.

1 Like

[quote=“VergilUa”, post:14, topic: 720571]
Yeah, don’t use it. If you’re using built-in - SpeedTree is decent.
As well as Mtree could be worth investigating (has same in Unity Editor features, and instancing / indirect instancing support).
[/quote]

I´ve tried SpreedTree on mobile and the performance is horrible. x2 to x3 slower than the unity creator trees.

Hi Guys,
I want to ask for a help. I am testing dynamic objects which use same materials which has GPU instancing enabled on 3 different phone. Interesting that on 2 of them performance decreases when I enable gpu instancing... On other phone(galaxy s7) performance increase.. So, what should I do now?
Performance decreasing phones they both have PowerVR Rogue GE8320 gpus. Is it related gpu?

[quote=“Arycama”, post:15, topic: 720571]
Using Instancing instead of Dynamic Batching means objects that share the same material, but not the same mesh will increase draw calls.
[/quote]

Correct me if I’m wrong, but GPU Instancing only works for the same object with the same material. It’s just meant to be used to copy the same item hundreds of times. And it has to be a dynamic object. That’s the only point of GPU Instancing.
Were you referring to GPU Instancing in that phrase?

Yeah, my point is even though GPU instancing causes more draw calls than dynamic batching, the amount of setpass calls doesn't necessarily increase. It's possible to draw several different meshes with the same material, without additional setpass calls. Setpass calls are generally what slows down rendering, not draw calls.

1 Like

[quote=“Gokcan”, post:17, topic: 720571]
Hi Guys,
I want to ask for a help. I am testing dynamic objects which use same materials which has GPU instancing enabled on 3 different phone. Interesting that on 2 of them performance decreases when I enable gpu instancing… On other phone(galaxy s7) performance increase… So, what should I do now?
Performance decreasing phones they both have PowerVR Rogue GE8320 gpus. Is it related gpu?
[/quote]

GPU instancing doesn’t affect the GPU in a noticeable way, it only affects the CPU. You may be CPU or GPU bound on any of those devices, and it could be any number of things, such as scripting, culling, setpass calls, vertex count, tri count, shader complexity, screen resolution/overdraw, etc.

Some of those devices may be CPU bound, and enabling instancing improves CPU performance. The other ones may be GPU bound, so GPU instancing does not help. They may be bottlenecked by something else such as vert count, overdraw or shader complexity, however.

You need to find where your bottlenecks are and optimise them.

5 Likes