VRChat is a well known social platform for all those who have VR equipment, and even if you don't have any specific hardware, you can join the party from your standard PC screen too! When you create a scenario, you have to be cautious with texture sizing and data management to make sure you can run your scene, but also the target audience can too! If you fail to democratize hardware requirements then you fail to create a popular VRChat World.
What is the Static value
If a GameObject does not move at runtime, it is known as a static GameObject. If a GameObject moves at runtime, it is known as a dynamic GameObject.
To apply only one type of static to an object is as easy as clicking on the dropdown arrow next to Static and mark all your desired values.
Static can make a huge difference in how performance behaves in Unity, is a 101 in optimizing your work and getting it running into potatoes. The whole Static well used is the secret for smooth fps.
In the Game view we can find a little tab called "Stats" there we can see how many batches are being processed by frame in the current FOV of the Camera set in scene. Without Lightbakes, Occlusion Culling, Batching Static and others this could easily rise as every feature needs a single calculation by object.
This means (among others): calculate mesh visualization, apply material (1 batch per shader pass), lighting (if realtime 1 batch per object), realtime effects like particles, skybox... So you can get that Static-ing your objects is crucial, specially the one that tells the engine to don't modify anything from its render/transform: Static Batching.
Before we get our hands on Static Batching, we will unravel the different types and do a brief explanation and usage:
You can find information about creating a good Occlusion Culling system in VRChat here:
The Static Batching in the Gauguin Avatar Garden
The Static Batching tells the Engine to combine similar meshes in order to reduce its calling count. But what is similar for Unity?
Unity will combine all meshes that have the Static Batching checked and have the same materials, in order words, Unity engine combines by material.
This reduces notably the amount of times its calling to render a mesh without killing its independence as an object. Combines the mesh but still considers all the GameObjects and their respectively components (Transform, Physics...) but they won't move. So Animated objects are off the table as they are Dynamic Objects and should be performance improved using other ways.
As an example, here in the Avatar Garden we find that we have repeated along all the environment a set of assets that vary in Transform values but remain the same in all the others (Material settings), all these objects are marked as Static so Unity only renders:
... and so on with every Material match between all the Static Batched GameObjects.
The result of Static Batching led Unity to combine all the meshes that used the same Water material or combining all the meshes that used the ground material.
If you animate a GameObject by its transforms and has the Static Batching checked it won't move on runtime. Meanwhile if you have an Animation based on shader values it will get animated. This means that Shader modification on runtime is still possible for Static Batched meshes.
The river in the Avatar Garden is an animation of the values of the Material Shader. The engine is told to interpolate two values in an amount of time and it does it through the Shader, this allow us to make this type of effects and at the same time maintain low the draw calling rate.
Also notice that the shadow doesn't get displaced during the animation, this is due to the UV space they are using. Standard shader uses the UV0 for input texture maps like Albedo, Metallic, Smoothness etc and so all the values modified during runtime only affect the UV0 channel of the model. On the other hand lightmaps make use of the UV1 and they are not modified during runtime.
For more information on how we created the river in the Avatar Garden, check our article about it!
Reducing draw calls
To draw a GameObject on the screen, the engine has to issue a draw call to the graphics API (such as OpenGL or Direct3D). Draw calls are often resource-intensive, with the graphics API doing significant work for every draw call, causing performance overhead on the CPU side.
To reduce this impact, Unity goes for Dynamic batching or Static batching as we stated previously, good practices to reduce draw calls include:
This is an example of Atlas packing, all the objects from the exterior are using the same texture maps and so they will be draw called once.
The Avatar Garden uses tileable textures and so it reduces too the number of materials. For color depth and variation we used Lightbaked lighting.
The static value is a must in the improvement of performance during runtime in Unity. Well executed can heavily impact on all machines and can let people with low-end machines running high-end experiences.
You are more than welcome to drop any question or your try-out and results!
Join us: https://discord.gg/UDf9cPy
I purr when you're not looking. I'm passionate about environments and all the techie stuff to make them look rad. Learning and improving everyday to be a better hooman.