Heya,
I was frustrated with how ECS handled rendering so I decided to make my own rendering system, and make it very fast while I’m at it. At first I thought I should just take every entity with mesh data and render that with Graphics.DrawProcedural in a command buffer, but then isn’t that just a draw call for each mesh?
I see the BatchRenderGroup API being thrown around online but I don’t think that will benefit my situation where every mesh will be unique. Is there some more obscure way to render multiple meshes with a draw call - like some sort of multi-draw in Unity? Or perhaps a way to do it with compute shaders?
What are my options?
Unity does not have support for any multi-draw API. The best you can do is use BatchRendererGroup because at least then the draw calls are emitted in native code in quick succession with shared state.
Out of curiosity, what did you find frustrating with Entities Graphics?
Just the large amount of components and features that are completely unnecessary for my use cases, but for some reason are required to be set. Plus I hate the way they store their meshes.
It may be great for rendering lot’s of the same mesh with assets, but is terrible for many unique meshes created during runtime.
I’m not sure I fully understand the arguments about components and features being unnecessary. Unless you are rolling a very stripped-down custom render pipeline, rendering is a very complicated ordeal.
It sounds like you just really don’t like creating mesh objects, registering them, and using MaterialMeshInfo and LocalBounds to make them visible. There are ways around that while leveraging Entities Graphics. But you need to tell me a lot more about your problem for me to provide the best recommendation.
Do your procedural meshes have anything in common with each other? Vertex count? Indexing strategies? UVs? Are they static once generated? Are they modified periodically? Or perhaps you are modifying them every frame in a Burst job? How many meshes are we talking? Hundreds? Thousands? Millions?
I don’t really want to go back to entity graphics tbh even if it gives better performance, I wanna give this custom rendering a go.
If you really must know, I’m working on a voxel prototype, meaning I’m generating chunks with each chunk having 6 meshes (one for each normal). I generate the triangles, normals, and vertices in a job where outside a job I create a mesh object, then put it in a big list where it is set to a rendermesharray which every mesh entity shares and indexes from. Just the whole setting of the shared components and the creation of those mesh objects, are taking up more than half of the time spent in generating new meshes. These meshes are ofc, static and don’t change very often.
Alright. So my recommendation would be to use this API: Unity - Scripting API: BatchDrawCommandProcedural
BatchRendererGroup has two callbacks OnPerformCulling and OnFinishedCulling which are called per camera view per frame. It is safe to do Compute Shader dispatches during these callbacks (and is especially optimal to do them in the latter).
Note that this is the path to what I believe would be the absolute most optimal solution you can come up with without native plugins. For something simpler that can better leverage instancing, remember that you can cull a triangle in the vertex shader by setting one of its vertices to asfloat(~0u). So for example, you could have an 8x8x8 cube mesh and four uint4 properties which are bitmasks and then discard triangles in the vertex shader that part of unused voxel slots.
Probs will use that thanks. However,
without native plugins
Has got me interested…