ShadowGun: Optimizing for Mobile Sample Level
Here at Unity, we want to offer you the smoothest experience for making fantastic games. One of the biggest parts of our job is ensuring that Unity is a highly performant platform for you to deploy to mobile devices, but when it comes to getting the best performance out of your games – that’s where you come in. So that you’re not in the dark when it comes to optimising your games, we got together with MadFinger Games, the developers of blockbuster mobile title ‘ShadowGun‘ to offer you a sample level project packed with innovative techniques, to help you learn about the techniques that they employed when creating their game.
We now have a dedicated forum thread for discussing the optimization tips shown in this sample level. Please continue discussion there -
The sample level project can be downloaded via the button below. It should be noted that this is not a gameplay example but purely designed to assist you in learning about optimal mobile techniques -
We’d like to thank MadFinger for their help with this project and for all the information they provide below. For those of you new to some of the terms mentioned here, we include links to external sites explaining the concepts involved:
If you want to have a 3rd person action game with beautiful graphics, complex levels with bunch of enemies with decent A.I. which runs flawlessly on iPhone 3Gs, you must put lot of effort into optimization. For the graphics side, you can optimize the number of triangles, amount of textures in memory and, of course, the shaders. We found that on mobile devices, shaders can be a real performance killer but also an incredible and powerful servant.
Alpha blending kills
The amount of faces using alpha blending, especially when it fills a large portion of the screen, reduces performance on mobile devices dramatically. When a bunch of alpha faces overlap each other and thus increase overdraw, it is a consistent killer for performance on slower devices.
Complex, per-pixel shaders kill framerate
We found that rendering large surfaces (in terms of screen area) with complex fragment shaders kills the framerate even more consistently than alpha blending. Complex fragment shaders should be used for smaller objects only.
Shaders in ShadowGun
Thanks to great cooperation between our programmers and graphic artists, we managed to create shaders that allow us to create advanced effects that do not have great demands on performance. The following shaders were used in the sample level from ShadowGun:
Environment specular maps (Shader Virtual Gloss Per Vertex Additive)
This shader combines Diffuse (RGB channels) and Specular (Alpha Channel). The Specular map uses the alpha channel of the texture to define the glossy vs matte parts of surface as usual, but specularity is not calculated per-pixel, but rather per vertex.
The resulting effect is reasonably convincing and it is significantly faster than using per-pixel specular calculations. It is perfectly suitable for large area meshes (like a level environment). This shader allows us to modify the strength of the specular effect and to approximately determine the direction of “light”.
Optimized dynamic character lighting and shading (Lightprobes and BRDF Shader)
The traditional problem with static lighting (Lightmaps) is achieving proper lighting on the dynamic objects (i.e. Player characters and NPCs).
Unity offers a classic solution, which stores lighting information for dynamic objects in proxy objects (Light probes). Dynamic objects then reconstruct incoming light information from nearby probes.
Unity also contains superb character shader, which is well optimized for mobile devices (check out the Mutant character in the sample scene). This shader supports Diffuse, Specular and Normal maps and uses a special script that generates a texture which is used for evaluation of the lighting in BRDF-like fashion. Resulting effect on characters perfectly mimics the next-gen character shading from big console titles.
Fog and volumetric light rays (Shader Blinking Godrays)
When you turn on the global fog in 3d engine, the framerate often drops below a usable level, especially on older mobile devices.
From a graphics point of view however, fog dramatically improves look of the environments, especially helping to perceive the depth and space of a scene. The solution we came up with is the use of simple mesh faces with a transparent texture (Fog planes) instead of global fog. Once a player comes too close to a fog plane, it fades out and moreover, vertices of the fog plane are pulled away (because even a fully transparent alpha surface still consumes lot of render time).
Preparation of the mesh in 3D app to work correctly with shader
- Vertex color alpha determines which vertices are moveable and which are not (in our case, vertices with black alpha stays, those with white alpha moves).
- Vertex normal determines the direction of movement.
- The shader then evaluates distance to the viewer and handles surface fade in/out appropriately.
Its simple to duplicate and distribute Fog planes through the level anywhere its needed. In a very similar way we use this shader for light rays, light source cones and other alpha effects.
Dense animated smoke at plane crash (Shader Scroll 2 Layers Sine Alpha-blended)
Because of density, the smoke particles are pretty expensive, and we found that it is better to use simple mesh with animated smoke texture (e.g. for background fire on crash site).
In our case, the smoke is animated by blending two textures and moving them over each other. There is also vertex alpha involved in order to smooth the edges of the mesh. The mesh is also colored with vertex colors (orange to mimic flames on the ground and greyish as smoke blends to the sky).
Moving Skybox (Shadow Scroll 2 Layers Multiplicative)
For our custom skybox, a similar technique with regards to scrolling in the shader creates a dynamic cloudscape -
Flags and cloths in the wind (Shader Lightmap + Wind)
Any animated objects in the scene brings life to level and when they are animated for “free” by the shader itself. We have animated the flags and cables in the wind in this way. Information which vertices are fluttering in the wind and which are not is defined by the vertex colors alpha in 3d modeling program (white alpha moves, black alpha dont). In shader parameters, user must define the direction and speed of flutter only.
All custom shaders in SHADOWGUN sample level are intelectual property of MADFINGER Games, a.s. and they are free to use (apart from BRDF character shader, which was created by Unity Technologies and is also free to use).
Meshes and textures in the level remains property of MADFINGER Games, a.s. and cannot be used for any commercial purpose without permission from MADFINGER Games, a.s.