TIP: How to enable Dynamic Shadows & Correct Reflection Maps on mobile

There are a lot of questions and not a lot of concrete answers swirling around about dynamic lighting on mobile. Here’s how we got it to work in Mega Blast:

  1. Anything that receives or casts shadows must use the** Default Lit** material shading model*
  2. In World Settings, under Rendering, make sure that Allow Static Lighting = TRUE. This is the key part: To get non-black shadows, some lighting needs to be baked to generate indirect lighting information
  3. Set up a Lightmass Importance Volume that encompasses your entire visible game scene
  4. You should have two lights in your scene:
  • Skylight set to** STATIC**
  • Directional Light set to MOVEABLE
  1. The Directional Light should have the following settings:
  • Cast Shadows = TRUE
  • Cast Dynamic Shadows = TRUE
  • Edit the settings in Cascaded Shadow maps to optimize performance (for instance using 1 cascade is more efficient, but mobile supports up to 2 cascades)
  1. The Skylight should have Cast Shadows = FALSE
  2. You can use a cube map for your skylight to light the scene by using SLS Specified Cube Map as the Source Type for the Skylight (we do this because we don’t need a skymap in Mega Blast, since the sky is not directly visible)
  3. Make sure that you have some items in your scene that can cast static shadows and can have lightmaps - these can be set to non-visible at runtime if you don’t want these items to be visible in game. We set up a large placeholder ground plane that generates nice bounced lighting from the “floor”. We then hide this at runtime, since the “real” ground is constructed from dynamically-placed objects with real-time shadows.
  4. Build lighting - this will bake the lighting and generate indirect lighting information that will be used to lighten your shadows
  5. Test on device

Shadows should now appear correctly for objects that use the Default Lit shading model.** BONUS:** This method will also allow your reflection capture spheres to work correctly - **reflection captures currently require that Allow Static Lighting = TRUE **

Useful console commands that can also be set in Default Device Profiles for optimization:

r.Shadow.MaxResolution - sets the resolution of shadow maps
r.ShadowQuality - sets the number of cascades used (your Directional Light can be set to use 2 for instance, but each device can be set to use the same or less, or none)
r.Shadow.RadiusThreshold - sets the screen size ratio at which shadows won’t appear. If you see shadows “popping in” at certain distances, you can change this setting to make sure shadows are rendered correctly in the distance (0.02 seems to work well for us)

*The Defaul Lit shading model is very expensive on non-metal devices so it should be used sparingly. For non-metal devices we use unlit materials with no cast shadows. See this post on how to display specific assets per device.

Please let me know if this works well for you or if there are any gaps in this information that you come across for your project. I’ll update the information if there are any corrections needed.

Some screenshots of the dynamic lighting in Mega Blast:



Is it necessary to use mobile HDR for this to work? I also assume that you had to use physical assets on the characters?

We do have mobile HDR enabled. Having said that, anything that uses the Unlit shading model will not have dynamic lighting calculated for it, even if mobile HDR is enabled. We use this method to display unlit assets on lower-end devices. We then enabled lit assets case-by-case. For instance, the coins use a lit material even on low end devices, so that we can display reflection maps on them.

I’m not sure what you mean by “physical assets on the characters” - can you expand on that?

From what I have seen previously in UE3 and with some issues in UE4, the physical asset is necessary to optimize shadows for skeletal meshes. I haven’t had a chance to get shadows to work on mobile, so thought I’d ask if it was necessary for you.

For skeletal meshes, we set up 2 LODs and use r.skeletalmeshLODbias to control which LOD is shown on device. LOD 0 uses Default Lit materials and LOD 1 uses Unlit materials. Aside from that we haven’t had to make any changes to the normal workflow.

Thanks for the tip Crinity !

And congrats for Mega Blast and Mega series : ) .

Just thought I would add here that I had a ton of problems with my reflection capture spheres and boxes. For the longest time I couldn’t get them to capture anything. Finally I realized it was because I was running the editor window in the mobile preview mode. If you try to do reflection captures with the editor in this mode it will not work. You have to switch over to the PC shader models before you rebuild your lighting.
Hope this saves somebody some hair tearing.

Thanks for posting this! Just got Cascaded Dynamic Shadows working in our current mobile game.

I used a slightly different method to get to a similar result. (but without creating the Unit materials and duplicate LOD mesh) so this will not be as optimised as yours for the slower devices.

I bake the lightmaps into the scene with a stationary directional light, and also have a second movable directional light (with cascaded shadow maps) turned off in the scene. Then at level load we check the DetailMode (r.detailmode) of the current device settings and turn on/off the stationary light and movable lights.

you can then set something r.detailmode=0 on all non metal devices and r.detailmode=2 on all metal ones and have nice dynamic shadows.

I have logged a bug with EPIC about getting the cascaded shadow maps working with a Stationary Light as they do on PC, which would make the whole process a lot simpler.

Almost 1 year after OP posted, get dynamic shadow worked on my Nexus 6. Thanks.