I am working on a custom render feature for the URP pipeline to render special shadows.
It works fine, but I am loosing a lot of performance when using cmd.DrawMesh within the render feature.
Is there some way for me to make these command buffer calls without it also calling SetPass under the hood to emulate some resemblance to the SRP batcher?
I have also tried using Mesh.CombineMesh, but all performance I hope to gain is lost in the costly combining process.
As per this post URP - Limited number of pixel lights, why ? , it seems differed lighting is ideal with working with fewer lights/shadows since performance is improved. Looks like cmd.DrawMesh relies highly on CPU which might create those performance issues you are seeing.
In this case, it would be a good idea to either go through deferred lighting and then turn off G-buffer normals off to increase performance:
Thanks for your help and insight. Also I should mention I am not using the built in shadow renderer. I am making my own.
Unfortunately I cannot go the route of GPU instancing, because all the meshes use different geometry.
In the Graphics API there is a command for Graphics.DrawMeshNow. Under the hood it is not calling SetPass again, and it is reusing the shader pass from the previous draw. This is also what the SRP batcher is doing. What I am really looking for is a way to do that with command buffers in a render feature.
It is clear that command buffers closely mirror the Graphics API as all their methods are almost identical. The only method missing is DrawMeshNow(). Is there a way that I can get around this, and achieve the same effect that the SRP batcher does? Can I manually submit meshes to a SRP batcher loop?
I have the same question.
I’m working on an open world game which will have around 100000+ renderers in view frustum after using LOD and Hiz culling, create gameobject with MeshRenderer is unacceptable for CPU usage, the only way is to DrawMesh by my self, so it is very important to reuse the SRPBatcher for those meshes, is there any way to do it?
CommandBuffer.DrawMesh is using a generic rendering code path that setup GPU completely (including SetPass) so it’s not really fast.
DrawMeshNow doesn’t call SetPass but it runs on the main thread and the mesh won’t be added in each rendering pass (like depth prepass, shadow etc). For a custom rendering pass it could be ok but keep in mind it still sets some GPU state ( like uploading obj2world matrix one by one ).
Did you try Graphics.DrawMesh, with just a mesh, matrix & material as arg? ( keep materialPropertyBlock to NULL ). This should use the SRP Batcher code path.
And then, for maximum performance when dealing with custom mesh rendering, you could use the recent BatchRendererGroup API. It requires a bit more work to setup but it’s pretty fast.
If @arnaud-carre or anyone else has further insight/clarification, as I understand it, WebGL does support SRP batching, but it isn’t listed as a compatible platform for BatchRendererGroup.
… then on January 2022, quote from x.com
“Unity 2021.2 brings URP SRP batching support to WebGL. Thanks to Jukka Jylänki at Unity for developing an extension to Emscripten to make this happen.”
Will it work in 2022.2 beta (or 2023.x) and the lack of listing in platforms was just an oversight, or it’s really not supported because of some other technical challenge beyond SRP batching? Or is BatchRendererGroup for WebGL 2 partially supported (i.e. it will work/won’t crash if you do use it, but without much benefit over other methods), or ? Thanks!
SRP Batcher is supported on WebGL. BRG is built on top of SRP Batcher (mainly reusing the persistent material data in GPU memory) but also introduces a complete new GPU data layout. For instance, BRG requires a new shader variant, fetching data from SSBO.
With the recent BRG support of OpenGLES3.1, we added some new code to bypass the GLES3.1 SSBO access from vertex stage limitation. From a pure GPU perspective, BRG on GLES3.1 is really close to what BRG would be in WebGL.
But supporting a platform also involves looking at the CPU performance. BRG and more generally entities.graphics rely on Burst & jobsystem support. We should carefully look at how these systems interoperate before making any decision.
To sum up, WebGL BRG support is not decided yet but product & engineer teams are actively discussing it.