I've read Unity3D
draw call batching documentation.
I understood it, and I want to use it (or something similar) in order to optimize my application.
My situation is the following:
- I'm drawing hundreds of 3d buildings. Each building can be represented using a
Mesh
(or a SubMesh for each building, but I don't thing this will affect performances) - Each building can be textured with several combinations of texture patterns(walls, windows,..). Textures are stored into an
Atlas
for optimizaztion (see Texture2d.PackTextures) - Texture mapping and facade pattern generation is done in fragment shader. The shader can be the same (except for few values) for all buildings, so I'd like to use a
sharedMaterial
in order to optimize parameters passed to the GPU.
The main problem is that, even if I use an Atlas, share the material, and declare the objects as static to use static batching, there are few parameters(very fews, it could be just even a float I guess) that should be different for every draw call.
I don't know exactly how to manage this situation using Unity3D
.
I'm trying 2 different solutions, none of them completely implemented.
Solution 1
- Build a GameObject for each building building (I don't like very much the overhead of a GameObject, anyway..)
- Prepare each GameObject to be static batched with StaticBatchingUtility.Combine.
- Pack all texture into an atlas
- Assign the parent game object of combined batched objects the Material (basically the shader and the atlas)
- Change some properties in the material before drawing an Object
The problem is the point 5. Let's say I have to assign a different id to an object before drawing it, how can I do this?
- If I use a different material for each object I can't benefit of static batching.
- If I use a sharedMaterial and I modify a material property, all GameObjects will reference the same modified variable
Solution 2
- Build a Mesh for every building (sounds better, no GameObject overhead)
- Pack all textures into an Atlas
- Draw each mesh manually using Graphics.DrawMesh
- Customize each DrawMesh call using a MaterialPropertyBlock
This would solve the issue related to slightly modify material properties for each draw call, but the documentation isn't clear on the following point:
Does several consecutive calls to Graphic.DrawMesh
with a different MaterialPropertyBlock would cause a new material to be instanced?
Or Unity can understand that I'm modifying just few parameters while using the same material and is able to optimize that (in such a way that the big atlas is passed just once to the GPU)?