I’ve been building environments in VRChat for years. I’ve experienced lag in my worlds often and I have spent a lot of time trouble shooting and trying to figure out the best practices for optimizing a space. All the content in VRChat is from the community meaning you have no control what the players bring into your environment. Player’s avatars can add up on your GPU meaning I want my world to be as low performance as possible. Here are some of my best practices for making sure my worlds are optimized.
A good way to cut down on draw calls is to cut down on the amount of materials used in a world. I like to atlas as many objects together as I can. This means having multiple objects share a UV map and material. This usually isn’t recommended because this can cause your textures to seem compressed and blurry, but to me its very necessary for a game like VRChat. It lets me save on a ton of materials and makes the space easy on Android devices.
I like to bake high poly meshes onto low poly meshes. This is standard practice for game development. Having lower poly meshes will make your mesh data lower in file size and can help with light baking. It also means less polygons for the player to render.
I bake all my lights. Always. Realtime lights effecting non static game objects can be a lot for your pc. Baking your lights will save all that light data and players won’t have to simulate it. Realtime lights are usually the cause for a laggy world. I only use real time lights in very specific circumstances, when it comes to building on Social VR platforms. When I do use realtime lights I make sure to have the lights affect objects on a specific layer, so that it the player only needs to render the light on the objects that need it.
In Blender, I like to join objects based on occlusion areas. Basically I join all the meshes in an area where the player is most likely going to need to render all those objects. This means there will be less objects in the scene and will lower the draw call count.
Baking Occlusion in a map is very simple. I mentioned occlusion a bit above. Having occlusion in a world means that players won’t render the game objects they can’t see. So if a player is facing a wall and a couch, all the player will render is the wall and the couch. There is no need for the player to render everything else in the world.
I take most of this to the extreme. I want to make sure my spaces are as optimized as possible. This is because it makes it easier on android devices and players using unoptimized avatars will normally blame the world for the lag and not themselves, so I try to do my best in anticipation of bad player content coming into the world.