Rendering optimization on runtime generated objects
Hi, I have some performance issues caused by rendering quite a lot of objects. I've read about occlusion culling, frustrum culling and call batching, but I either can't use this solutions and the remainder that I can use don't get the job done. The reason I can't use some of those is because I create and instantiate the objects at runtime. Right now I use about 10000 cubes to generate a level, but this can become much more very quickly. Currently they are cubes, which is one of the easiest meshes to render, but I plan on making them have a bit more complex meshes. Can someone give me some ideas for rendering optimization that can be performed during runtime? I am aiming for about 90 fps (I am developing for the Oculus Rift) so every piece of advise is welcome.
Answer by JPhilipp · Dec 22, 2017 at 08:16 AM
We ran into similar issues due to the need for real-time generated objects and no chance of baking as it's a sandbox universe. Here's some of the things that helped a lot:
Merge as many meshes together into one as possible. This can be done during runtime. Look into CombineInstance on how to do it. Only meshes of same color and material can be easily merged. Careful about exceeding vertices max count (which can be increased in Unity 2017.3, look for IndexFormat).
Use sharedMaterials created from your own locally managed stack to avoid duplicating memory, as this slows down Unity a lot. Careful, as soon as you adjust on a gameObject a material that you set as sharedMaterial, it will automatically instance itself and create additional memory.
Restrict your number of dynamic light sources.
Manually only show the nearest objects as your person moves along the scene. The Linq library and OrderBy command can help you order by smallest Vector3.Distance to your person head transform. You may want to add additional signals outside of just distance, like preferring larger objects even if further away.
You mention you use cubes and plan to upgrade to other meshes. If you do however end up with cubes only, search Google for [unity voxel engine] and similar, as there's many specialized approaches for that.
Look into GPU instancing, like the Shader component's bottom tickbox "Enable GPU instancing". The latest Unity 2017.3 final may help you here, as they say they fixed some more bugs with it. (It didn't work for us in 2017.2.)
Good luck!
Thank you very much! I am certainly going to look into these!