hello
i was reading a lot about reduce draw calls
but i can’t implement that
my game have alot of buildings
every building have it is own style and colors , materials
how to reduce the draw calls
i am target mobile not pc
so the draw calls come to 200 to 400 sometimes
and that is big large
i tried to reduce number of materials
but i failed
i know about mesh
but i need a tutorial for that target
thanks
All the buildings should be one mesh, all sharing one material and one texture.
You could try the combine children script if u have enough mats textures similar it would do a decent job. check the wiki for the script if u don’t have it.
depends… if fps then occlusion culling might help
Well it depends: do you use same shader for this buildings? If so, you may want to put all your textures in one atlas to be able to use one material for your buildings. Also, if you have Pro version,and your game can benefit from culling, I’d recommend you use static batching instead of mesh combining.
-
Atlasing (sharing a texture of higher resolution) between asset is one way of doing it, yet if it’s the only way taken, you’ll hit your head hard on trying to get quality without exploding the 2k resolution limit of some hardware.
-
There’s the possibility to create a system which create an Atlas for a group of assets made of multiple materials that are “fused” from the engine point of view. That’s what is used when you bake lights&shadows within Unity. One huge set of Atlas automatically generated from multiple (not rare to have for 300Mo worth of textures in size for 1 Atlas) 2K textures fused by the system. (You could see this as a group in which the system only call once per frame as a whole, yet for the VRAM it only take 2K worth of data maximum per uv shells. (it can take as less as 32x32 if the uv shell is small enough)
The main problem of this system is that it’s complex to set-up.
There’s some documentation about the script to get an Atlas of Texture :
Unity - Scripting API: Texture2D.PackTextures -
Like mentioned above, if you have Unity Pro, you can uses the Occlusion Culling. While it will take more RAM to run (which never really lack in PCs), it allow the engine to “ignore” anything that doesn’t appear forward in the camera. It require many tries&errors&retries based on the complexity of your city. (you have to manage each single asset’s occlusion so that thing doesn’t goes missing or doesn’t render the system useless.)
Unity - Manual: Occlusion culling
If you’re not building a game with a free sky view (like a city builder).
- If you don’t have Unity Pro (or if the Occlusion Culling doesn’t work for your city), you still can create a homemade mechanical occlusion system by separating your city in zones. Ideally, you can do this in 2 layers : 1 being the zoning for rendering and the other is the zoning for closed areas.
I’ll tell you now, this methods is actually more “functional” than the official Occlusion Culling, but also require A LOT more work and preparations. This is also what was used prior to the Occlusion Culling when consoles didn’t had enough memory for such per-mesh processes and it’s still used over the O.C. for simpler/large zoned areas.
First, you have to zone your city. This means to make the city in a way that allow you to have view cutting asset on every direction in every X meters. (Here, X represent a distance based on what kind of hardware you’re aiming for) For example, with a city, you you will have to block every view with building by making uses of streets like this :
║llll╔
╚═╬═╦═╗
This allow you to zone the areas more easily.
Then, you place every assets in each zone into an empty object per zone named in a way you can recognize and easily identify later or by a system. (Numbers would be best for easier scripting)
After that, create a bunch of Collision boxes or Collision Mesh for every zones. (Ideally, make them just overlaps as less as possible, yet the player must NEVER be outside of one of the collision zones, so the city must ALWAYS be in one of the collision boxes). As you can guess, make those Collisions assets as triggers.
Now, you will have to create a script that will allow you to choose which Empty objects you created earlier should be enabled while all the others well be disabled and that for each collision areas you created. (The best way is to make create a script with bunch of public serialized insertion point in the inspector on which you can just enter the number of zones to be draws and drag&drop the zones’ empty objects inside.)
This will allow you to “disable” zones (and so remove LOTS of drawcalls) that aren’t viewed without using the Occlusion Culling system. Again, this means you will have to manage the layout of the city so that either each zone is separated by something that cut off the view or, in some cased like long straight roads, the view would have to be “blocked” by something like some atmospheric fog or weather effect(s).
Another tip I could give you, with this method, is that the amount of memory/drawcalls you allow should be only the half of the hardware capacity which you’re aiming for. The reason is that there are risks whenever a player move from one zone to the other that both “zones” surrounding zones gets enabled at the same time for whenever the player move across.
And, at last with this method, if you plan to have planes, helicopters or simply having the player moving on roofs, you will have to create the city twice. Once for the “high detailed” version which is, for example, the zone (and maybe surrounding zones) in which the player is and the other should be “cheap” zones made of almost just the big assets with a low resolution (you could fit a whole zone into a single 1k-2k material and have all the buildings as simple as possible). This last step is mostly a Field of View (FoV) system so that “far” zones doesn’t just pop-up whenever the player move above the buildings. Again, if you plan this, you should script it so that it’s easier tomanage in the inspector.
Mixing the Occlusion Culling + this last method also works awesomely well (and that’s how GTA4, Saint Row 1-4 and many others create big maps). There is one single issue which I should warn you if you plan a city above 8Km x 8Km and if, in the inspector, you work with units as meters. You will have to plan on adding a zeroing system. A zeroing system is simply a system that makes the player always stay in the 0,0,0 position while the whole world is moving around. This is due to the imprecision of the float 32 bits data. Whenever it reaches 6-7 digits, it become unstable and might give out wrong numbers on the last 1-2 digits. (Commonly called “Floating Point Imprecision Problem”)
For example, if the player move to the point X:6750,284 / Y:10559,47 / Z:1,454564.
Meaning that the player is at 6.75km on X, 10.55Km on Y and 1.45m in elevation(Z).
(I might be mixing Y and Z… sorry about that)
The player as well as any local assets around 10.55 km on Y might move up to 0.99m every frame since, at each frame, the 32bit(7digits) data is being read again and the last 2 digits might be off.
This is a great post for some solutions : Dynamic Terrain Loading - Questions & Answers - Unity Discussions
Hope this helps you and good luck&success with your game!
@Max_Bol : That is one LONG post!
Also didn’t know that “fusing” was a way to get even texture quality across surfaces. Might try that for a game I’m building (atm, I have the terrain and my race track on one texture, but the track itself isn’t looking too pretty at times… )