I mostly use Unity for large-scale simulations and visualizations and often find (found) myself subdividing meshes to get around the 64k limit. Detailed 3D models can also easily push the 64k ceiling. Or over in voxel-land, they like to chunk their terrain meshes for a different set of reasons, but in a Unity context the average chunk size (16x16xN, say) will usually be representable by a single < 64k mesh anyway. There are many reasons to subdivide or chunk a mesh other than Unity’s proprietary 64k limit which no longer exists, and I’m just curious whether this particular change is a convenience or truly enabling for some.
For terrain it could be truly enabling mesh-based workflows. I wonder if it also affects dynamic batching, which potentially could bring performance gains in the drawcall department. Does anyone know that?
Not having to build higher level abstractions to deal with modifying geometry dynamically is kind of a big win. Combined with shader LOD so you don’t need to break up the mesh just for LOD.
This in particular happens to be directly relevant to something I’m doing right now. We can do mesh-based terrain stuff as we are, but by default it reimports as strips which are a pain to work with for some stuff. Not the end of the world, but better workflows are always welcome. I just hope it doesn’t impact performance, which is my only guess at why it wasn’t this way in the first place.
The other thing that springs to mind is better support for people working with models from CAD stuff. For production use you want to make real-time optimised versions of your models anyway, but for in-house stuff with beefy workstations this could simplify stuff a bit, which overlaps a lot with what @snacktime has said.
I guess, dynamic batching gets slower the more mesh data has to be processed. It would software-process (transform etc) gazillion vertices on the CPU, that probably isn’t very efficient
Unity Technologies don’t recommend to use Dynamic Batching on modern platforms, it does not even work anymore in specific cases:
https://discussions.unity.com/t/675719/2
Aaaand… that Dynamic Batching is not working, is “By Design”
https://issuetracker.unity3d.com/issues/dynamic-batching-draw-calls-always-0-in-a-player
Bear in mind that if you are breaking the 16-bit index limit, then you’re talking about a single mesh which has more than 65k vertices - and that things like culling in Unity are performed on a per-object (i.e. per-mesh) basis. If you try handing the engine a terrain which is a single mesh with a few billion vertices, then you’ll likely find that you now have GPU workload problems…
So sad, because I feel like I had an excellent usecase for dynamic batching. E.g. many different projectile meshes that share the same material and are very low-poly each. Dynamic batching might fit them all into 1 drawcall, but instancing could be like a dozen different ones because so many of the meshes are different. Or I wanted buildings to be lowpoly blocky things with custom vertcolor data per mesh, to store localized damage effects per mesh, that’d also not work with instancing because there I only could store the data per mesh and not per vertex.
When did dynamic batching break? I tested our spent casings in 5.5 I could have several hundred cases and only 1 draw call. This is not at all good… We let the casing stay for 30 seconds. With 12 players that can be alot of draw calls if dynamic batching no longer works. Need to investigate
If the cases are all the same mesh you could use instancing. Or how about shared particle systems? One for all bullet casings of the same type, so maybe 1 for rifles, 1 for handguns, 1 for shotguns? The spatially cached raycasts of particle systems could potentialy save on physics calculations for having them collide with the world.
nope, same material, different mesh depending on caliber, and if spent or unspent
The grim end of Dynamic Batching
In the days of rome and ancient history, Dynamic Batching was a design intended for ancient mobiles where you’d be thinking about doing up to 200 draw calls at the most, and in cases like this, it really helped. Fast forward to the PS Vita days (Unity 4-5x) we found that dynamic batching was causing more harm than good and simply didn’t work well once threaded draw calls started happening.
And as jobs are threaded draw calls on steroids, we simply do not enable dynamic batching to begin with. Yes the batch count looks evil! no, the setpass count doesn’t = all is well!
If we want savings, we use Instancing, particle system, things like that.
What if I have multiple particle systems that I’d want to be dynamically batched? Instancing doesn’t work on those as far as I know. And single shared particle system doesn’t work because of z-order issues.
If there are z order issues, they weren’t getting batched to begin with. That’s one of the criteria for breaking batching (transparent depth sorting etc).
I’m pretty sure it will not change framerate to use dynamic batching on anything except old phones… In any case it’s likely the dynamic batching is being turned off on the player.
Do you have more than 100 particle systems going on screen at the same time? Also a lot of other things prevent particle systems from batching. Did you check the info box at the top of the particle system component for warnings?
(I really hate using fixed numbers like 100 in discussions like this)
As far as I know, ParticleSystem’s feature their own “batching implementation” and do not rely on Dynamic Batching. I remember an explanation in the Unity documentation what you have to do to make ParticleSystem’s actually batch, but I’m unable to find it.
The only resource I was able to find is the following support article:
https://support.unity3d.com/hc/en-us/articles/207840303-Particle-Systems-are-no-longer-batched-in-Unity-5-3
The one in question is a particle system for burning wrecks of destroyed units, that goes out after a while. There usually are a few close enough to each other that at least some of them could be batched together, so if there were 100 of those with 1 other transparent object passing through that area it could be still drawn in 3 batches theoretically (including the other passing through object), wheras without any kind of dynamic batching it’d be 101 drawcalls.
I don’t remember any warnings but I didn’t know to look for them at the top of the particle system either, so I’ll keep an eye open for those, thanks.
When I used frame debugger on my scenes in the editor I did confirm that some of the particle systems are indeed getting dynamically batched together.
Tell you what, I’ll just disable dynamic batching in the editor and if I don’t notice a big difference I’ll try to stop worrying about it.
Ok, set pass calls is whats expensive for us. Around 300-500 set pass calls and you start to see dips below 90 fps in VR
Sort the setpass calls out. Try to cap at 200 ish for a modern game, it’s not that hard, just good material management.
Yeah, sadly when a player brings up a powered sight (zoomable sight) we need to draw the game an extra time. I wished Unity somehow could fix single pass rendering for a third camera.
Why do you need to draw the game an extra time? is it a zoom scope? If it could be made so you don’t look through it manually (swap to scope) it could be a good time saver. I guess you do not want that.
I’m curious, if you e.g. have an rts with lots of transparent particle effects that need to be z-depth staggered alternating between different materials, how would you solve that with “just good material management” if you let’s say have a screen full of explosions, lasers, smoke, fire, missiles, all using different transparent shaders?
I’m not saying that’s my usecase, but I’m interested in your answer nonetheless because I still find myself exceeding 200 setpass calls easily and I that blanket statement of staying below 200 being easy-ish in all cases doesn’t seem accurate to me.
What I’m doing to cut those down is use non-transparent shaders wherever I can, e.g. for projectiles, missiles and lasers, and do the glow with bloom in post, make common effects share the same particle system wherever I can (e.g. explosions), and make things use the same material if possible (e.g. flamethrower and burning vehicle wrecks use the same particle material so they can be dynamically batched). Custom layer sorting for particles also seems to be a way to lower setpass calls at the cost of z-ordering issues.
I’ll admit RTS kind of games with PCG landscape and everything being destructible must be one of the harder drawcall problems because none of the static batching techniques work and there’s a larger need for objects beeing separate meshes instead of batching them manually at runtime into chunks of compound meshes.
Rendertexture for zoomed scope with different FOV?