Terrain Optimization
Terrain Optimization
well, with a particular focus on low end systems e.g. integrated graphics / mobile systems, or VR.
In a recent class of mine on some on some old integrated graphics based machines we were able to
increase the frame rate the student was experiencing from 2 fps to about 70 fps in just a few
minutes, and with more time and focus and following all of the tips shared here we could have done
better.
Unfortunately there is no silver bullet to optimization as every game is different. The approach I
take is to experiment with one setting at at time and keep experimenting and profiling until I get the
settings I am happy with.
Firstly, some cautionary of notes on optimization:
• What is your target audience going to be using at the time you think your game will release?
Graphical power is the area in mobile and desktop that is advancing at the greatest pace.
Knowing your target hardware will determine how much time you need to spend optimizing.
• Time is money – and optimization is a game of sometimes frustratingly diminishing returns.
Solve the big problems first and then get on with making your game. If you don’t need to do
it then don’t waste your time!
• Optimize early and often. Get a sense for how much content you can jam into your scene,
what assets and post fx you can use then stick to it. You will lose time later through re-work
if you don’t pay attention now.
• The profiler is your friend. Try stuff and keep the things that work. Be aware that running
the editor and the profiler pollutes your results and reduces framerate due to the overhead of
measuring and reporting what is going on. In fact, even running the project in your editor
pollutes the results.
• Optimization is all about making tradeoffs – you will most likely lose some visual quality in
the process – understanding this, and being artful in the way you hide these trade-offs is is a
key part of making games. For example, use fog to hide things in the distance and then
render lower LOD’s or not at all. Its technically worse, but visually your audience will never
know.
The best way to profile is on a compiled build. Be sure you disable vsync to stop it from influencing
your profile. However even profiling in the editor is enough to show you where the bottlenecks are
likely to be.
Here are some tips to explore. Some are mobile specific and some are more general. Pick and
choose whats good for you:
1. Spawn less stuff. Simple eh! The more you put into your scene the more expensive it is to
render. If you have performance issues, consider what you can cut from your scene. You will
not get a desktop scene to run well on mobile if it has too much content for the target device.
2. But I want an infinitely massive open world? Better sharpen your skills – this is hard to do
even for teams with experienced pro’s and it requires deep understanding of the engine and
how to get the best out of it. If you are new to game development then focus your attention
on smaller environments and filling them with great game play.
3. Unity terrain is expensive as it is a memory and resource hog. The higher the resolution, the
further the detail distance, the worse your performance will be. You can find your resolution
settings in the Gaia Defaults file. Check the bottom of this post for some sample mobile
settings. Here are some general rules of thumb:
1. Use lower resolutions and ensure everything is a power of 2
2. My rule of thumb for desktops is to make all the resolutions half of the terrain size.
3. For mobile you might make them a quarter or even and eighth of the terrain size.
4. Make your terrains smaller and consider a tool like World Streamer that will only
load the terrain if its in view.
5. Use less textures – a maximum of 4 on low end systems
6. Use less different grasses – each additional grass consumes memory, rendering and
culling overhead
4. Drop the size on your textures and normal maps to be more low end friendly. Experiment
with 256 and 512 sized textures. The textures supplied with Gaia are located in Gaia / 3rd
Party Samplers / GameTexturesDotCom. You are often better to pre-optimize your textures
with specialist 3rd party tools than to let Unity do it for you as they will most likely be
cleaner and this will have a substantial visual impact.
5. Use a maximum of 4 textures on your terrain. Every multiple of 4 textures causes the unity
terrain shader to render an additional pass (draw the terrain all over again). So even adding 1
texture over this boundary of 4 will cause another pass.
6. Run a smooth or two on your terrain after you have finished stamping. Smoothing the terrain
reduces the number of polys that need to be rendered.
7. Increase the Pixel error on your terrain. This will have the effect of reducing more distant
terrain at a lower resolution (LOD), but will also increase visual artifacts as you move
around. Experiment until you find a trade off you are happy with.
8. Either lose grass completely, or use it sparingly. It is a performance hog. In particular it will
cause jitter issues when it is culled. You can shrink the detail distance in your terrain
settings, and also lessen the detail density. Make sure that you color your grass so that it
blends with the color of the terrain – this way you lessen the visual impact of hitting the
detail distance.
9. By default the camera will use frustrum culling to remove objects that are out of view on
either side of the current camera view, however you can get another level of performance as
well by also using occlusion culling. Occlusion culling will stop objects that are behind
other objects from rendering and will result in more objects being culled than just frustrum
culling. Rendering less objects results means less draw calls and higher performance. You
can bake your occlusion culling via the occlusion culling window to generally get an
immediate performance improvement. TIP: Be creative during level design and use of larger
objects such as mountains, hills and walls in your scene. These will block your view of
distant objects, and hence increase your framerate via culling.
10.Reduce your shadow distance for each of the quality settings you use. If you can get away
with it, use hard shadows. You will find these under Edit -> Project Settings -> Quality :
Shadow Distance. Also explore the other shadow settings while you are there. Click on
Game view and experiment to get the visual settings you want.
11.Reduce your LOD bias for each quality setting you support. You will find these under Edit -
> Project Settings -> Quality : Lod Bias. Click on Game view and experiment to get the
visual settings you want.
12.Use Graphical Post FX sparingly. Profile the FX to validate their impact on performance. In
later versions of Unity you can see these at design time. Click on Game view and
experiment to get the visual settings you want.
13.Use mobile optimized trees. The tree samples provided with Gaia are desktop trees. If using
SpeedTree, experiment with your LOD and wind settings. Preferably lose wind completely.
14.Use mobile optimized assets in general. The assets that come with Gaia are good for
desktop, but not so great for mobile. Gaia will happily work with whatever assets you throw
at it, so you can easily swap your own in.
15.Lose wind completely – delete the Wind Zone object that Gaia creates. You will find it
under Gaia Environment / Wind Zone in the scene hierarchy.
16.Lose Unity water completely. The default Unity water is very inefficient. If you must use
Unity water then swap it out for the WaterBasicDaytime version that comes in Standard
Assets / Environment / Water Basic. Better yet purchase a good quality 3rd party water
shader optimized for mobile such as AQUAS.
17.Make sure you mark rocks and other assets that wont move as static, this will allow unity to
batch them, which in turn reduces draw calls and increases frame rate. Make sure when you
spawn these assets that their scale is a whole number and this will allow Unity to choose the
best case between dynamic and static batching.
18.Instance as much as you can. Instancing is the process of sending the object to the GPU
once, and then rendering it multiple times, as compared to sending it to the GPU for every
single time it needs to be rendered. Check this article out on Instancing SpeedTree.
19.In your lighting tab, select either Precomputed Realtime GI, or Baked GI, but not both. You
will need to update the lights in your scene to reflect the settings you have chosen.
20.In your lighting tab, make your ambient light source a fixed color. This is less GPU
intensive than using the Skybox.
21.In your lighting tab, make your sky a non procedural Skybox instead of the default
procedural Skybox. Its much cheaper often looks better.
22.Use baked lighting if you can get away with it. The means you lose the benefit of time of
day lighting, but you get it back in performance. If you remove shadows and other lighting
calculations then this reduces the amount of work the device has to do.
23.Lighting tip : Often in editor mode you will have objects that look really dark. Usually they
will display correctly only after you have finished the lighting bake. Be sure to set objects
that don’t move to static so that they will be affected correctly by lighting.
24.Use Forward instead of Deferred rendering path. This is cheaper for environments that have
a single light e.g. the sun. It will perform words however if there are multiple lights in the
scene. You will find this setting under Player Settings. File -> Build Settings -> Player
Settings. If you have multiple lights however, Deferred will be faster and better.
25.Select the “Fastest” setting under Quality settings. Edit -> Project Settings -> Quality.
Alternatively you can also attach the FrameRateManager script in the Gaia / Scripts /
ValueAdds directory to a static game object such as the terrain and it will dynamically
change your environmental settings to try and maintain a given frame rate. You will need to
modify its settings in the script to suit the type of game and the device you are supporting.
26.If you do need large environments, use World Streamer. It breaks the terrains down into
smaller chunks, and culls terrains that are not in view. It can make a dramatic performance
difference even on desktop games.
27.In your scripts, never leave the Update method if the script does nothing – this chews up cpu
even if its empty. If you must do something regularly, then consider using co-routines, or
using a master manager component.
28.In your scripts, always cache transforms and components, its much cheaper than getting
them during Update.
29.In your scripts, never use methods like Find(), except perhaps in Start(), its very expensive.
30.In your scripts, avoid using Vector3.Distance(), use Vector3.sqrMagnitude instead.
31.In your scripts, avoid using Ray casting, and if you must use, then use sparingly.
32.When using colliders, in order of cheapest to most expensive, use Sphere, Capsule, Cube,
Mesh, Convex Mesh. Mesh colliders are way more expensive, so estimate the collision
volume with a sphere or capsule if you can.
33.Use GPU Instancing on your SpeedTree’s. Check this post on how to set it up!
34.Set per layer cull distances on your camera using Camera.layerCullDistances
Low end settings:
Here is a sample setup for Gaia Defaults terrain settings for a low end desktop or mobile. Even if
not using Gaia, these settings can be set directly in your terrain object, and will still help your frame
rate.
Make a duplicate of your Gaia Defaults object and then enter these settings and save. Then open up
Gaia Manager and drag it onto the Defaults setting. Gaia will then use these defaults when it creates
new terrains.
Note: By dropping values, as suggested here, you are also dropping the accuracy of how Unity will
place your textures and grasses, as well as dropping the visual fidelity of the end result. You will
need to experiment with these to balance visual fidelity against the frame rate you get on your
device. Be aware also that the mobile industry is advancing at a very rapid pace, so you need to
make these decisions against where you think the hardware market will be by the time you are
ready to launch.
More information:
For a more thorough exploration of game optimization in Unity I recommend having a read of an
excellent book called Unity 5 Game Optimisation.
Also check these articles at Unity web site:
• Unity 3D Game Optimization And Lighting Articles
• Optimizing graphics rendering in Unity games
• Optimizing graphics performance
• Practical Guide to Optimization for Mobiles
• Graphics overview
Check out Gaia:
• Check out Gaia on the asset store.