Unreal demo Android port
The first thing that happened when loading the demo on Android is that many materials failed to compile. This led to missing materials in the editor and crashing on native hardware. I have separated materials in to 2 categories:
1: Normal materials – used on most meshes.
2: Effect materials – used to render special effects
Fixing normal materials
The materials could not be compiled on mobile because they are using more than 8 texture samplers. I got the material to load by disabling ambient occlusion, normal calculations. I also had to limit the material blending to only use 2 materials instead of 4. Finally, I had to disable the emissive texture property. Now the material shader will compile.
The material has lost a lot of detail but most of it is not noticeable especially on a mobile screen. The only very big visual change is that the blue hexagons are missing.
To stay as close as possible to the original look I made separate materials and skeletal meshes for mobile and the normal view. This allows me to change material properties and see side to side changes in real time. For the mesh above it looks like the following.
I realize that the main problem is the shader being too complex so the solution to this is baking the material. To do this I created the following assets:
1: Render Target RT_TextureBaker, this will store the baked texture and is used to create a static texture from after baking.
2: Actor blueprint BP_RenderTarget, this will render the output of a material to RT_TextureBaker.
For this baking process to work the shading model of the material must be set to unlit otherwise it does not work. To bake out a channel it must be set to the emissive output of the material. The channel is then baked to RT_TextureBaker with a resolution of 512×512 and then I can make a static texture from RT_TextureBaker. Then I create a new material that uses these baked textures to render the object. This is far cheaper than doing complex calculations in real time. I will show the old material versus the new material below.
You can see the resolution difference but here is a side by side in game on the actual model. This difference is minimal and not easy to see on a mobile screen. The performance is much better because it uses less texture samplers.
This alone however is not enough for all materials. A material on mobile is limited to 8 texture samplers, 3 of these samplers are in use by the engine for lighting calculations which only leaves 5 samplers for materials. When baking the textures, I normally must use 1 sampler per channel. Complex textures might have a combination of the following channels:
- Base color
- Specular
- Metallic
- Roughness
- Ambient occlusion
- Emissive
- Decals
- Normal
This still easily exceeds the limit of 5 samplers especially since decals must be blended using an extra sampler. I can reduce the number of samplers further by manually blending the roughness, metallic and AO channels in a single texture using the red, green and blue color channels respectively. If a material also needs the specular channel then AO can be baked into the base color and the specular channel can be stored in blue.
This way I can reduce the channels needed to 6. Every material without decals works. If a material uses too many channels then I have to remove some. From looking at side by side comparisons I feel that the normal channel has the least impact on the visuals so it ends up being removed in most cases.
Fixing effect materials
This video is an example of a material effect.
The effect looks really nice but on mobile it does not compile, it would also be too heavy if it did.
My solution to this problem is to try and mimic the effect by using a much simpler material. In the case of the effect in the video I stopped it from moving and removed the blur calculations. These changes allow me to render the effect as an opaque material which then allows me to bake the result as a static texture. The baking process is mostly the same as before but I increased the resolution to 1024×1024. This resolution will be lowered for smaller effects.
I duplicate the baked result into 2 textures:
1: An opacity texture to make the new material translucent.
2: An emissive texture which I use to add color to the new material.
The opacity texture is already correct. The emissive emissive texture needs to match the color of the light that was taken into account in the original effect. I use this color information to get close to the original intended colors.
The new effect material gets close enough to the original intention while working on the mobile renderer while also costing less performance.
Each material effect will be different but my approach to bake the mobile version will be the same.