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:

10 Likes

This is great info! I’ve been working on a mobile game in UE4 recently and was pulling my hair out with dynamic shadows. Thanks for your share!

Jon

No problem - I went through the same hair-tearing process, so I figured it would be good to post this info all in one place once we figured it out! Nice work on Q.U.B.E by the way!

1 Like

On a simple level containing 2 cubes, when I set the Directional Light to Moveable it halves my fps (from 60 to 30 fps), is that what I should expect on mobile (Nexus 5)?

I have the same problem…

I’m not too familiar with that Android side of things (we are primarily focused on iOS), but this generally is to be expected. I found that it didn’t really matter how many objects were on screen or how complex they were, but how much screen space they took up. If you zoom out so that the cubes are very small on-screen, do you see an fps increase?

We get great performance on metal-enabled devices, and comparing the Nexus 5 to the iPhone 6, there is a big difference in capability: Google Nexus 5 vs. Apple iPhone 6 in GFXBench - unified graphics benchmark based on DXBenchmark (DirectX) and GLBenchmark (OpenGL ES)

My hunch is that you should be able to add more objects to the scene without much of an fps decrease - the biggest hit is from using dynamic lighting at all.

Thanks! Nice job with Mega Blast! It looks great!
I’ve just used your tutorial in a small project we’re working on and it’s looking amazing, thanks to you! :smiley:

@ZeJudge

Nice to actually see the person (member of the team) that was involved in making one of my favourite puzzle games.

I love portal and was looking for something in the same genre that gave me the same experience, then I found your game. I love it.

Great work.

Sorry to bombard the thread with, what can only be described as a ‘fanboy thank you’.

@anonymous_user_af6c1130,

Great information that I am sure, many will find extremely useful. I will try to implement this in my mobile project. Thanks.

Thanks for this very helpful!

One thing I’d like to add is that having the Skylight set to ‘static’ prevents it from making any difference in my game at all - not sure if that’s just something I’ve messed up in my project, or is it to do with cubemaps? I don’t use them.

As such, changing skylight mobility to ‘stationary’ and checking ‘force no pre-computed lighting’ in world settings gives me nice lighting and prevents the need for lightmaps.

Of course if you want any static lighting at all you need to keep that unchecked.

@Doug - have you made sure to set Allow Static Lighting = TRUE and that you have at least one object that can receive lightmaps in your scene when you build lighting? You’ll need to turn OFF “force no pre-computed lighting” with this method, so that indirect lighting can be built, which will make sure that dynamic shadows are not pure black.

Out of curiosity, are you able to achieve non-black shadows on iOS by setting the Skylight to Stationary? We were only able to achieve non-black shadows on iOS by building static lighting.

I do get non-black shadows on my 5S with a stationary skylight and no precomputed lighting - then again I’m only using solid colours in my game (no textures) so it’s possible the skylight just lightens them!

Since I first tried a skylight many versions ago I have only been able to get it to actually affect the world properly by setting it to stationary - I imagine I’m doing something wrong, but basically any surface that is not in line of sight with my directional light is very dark with the skylight set to static. Even when I was using static baked lighting this was the case.

I’ve tried your plane method whilst allowing precomputed lighting + static lighting in the directional light (with a lightmap on the plane) yet all my shadows stay pure black.

Edit: I notice that deleting the default skybox gives me black shadows. Perhaps this is a factor?

Thanks Crinity. Your tips were of great help. Although, after activating the settings, there was a massive FPS compromise that happened. Can’t figure how to workaround that.

This drop affects iPad3 and not the other ones. Wondering how to enable HDR for specific devices within a single apk.

I’m using UE4.9 and recently 4.10r3. Device: Samsung S6

I can only get any directional dynamic shadows when it’s set to Moveable (but this is apparently unsupported and gives me upside down dynamic shadows - on Samsung S6). Apparently the only dynamic dir shadows supported are dir light set to Stationary.

A Stationary Dir Light gives me no shadows at all on device (or in Editor if I set it to emulate Android (UE4.10r3) or ES2 (UE4.9)viewport)

THX! A lot hahaha

Thnx Man, U re the best! :smiley:

hey Crinity:
Thanks for your share. I set up my project as you said, and got the right shadow when playing in the engine.
But no shadow&wrong light on device(package to android gearVR).
i’m using UE 4.14 Device:Samsung S6edge

Same for me. Using 4.25.3. Shadows appear in PIE, PIE 3.1 but not when deployed to device (Samsung A20s, Android 10, Adreno 506). And, as per official docs, dynamic shadow is not supported yet (allow receiving correct lighting though).

I Just create a new project in 4.26 and configure like you but the shadows are not working on my Xiaomi, any idea ? :confused:

Hello crinity thanks for your share. I need dynamic shadows for mobile game. In my scene I have all meshes static except car and character. Static meshes in my scene should receive baked shadows whereas car and character should receive dynamic shadows how to do that. Pls reply

Hi guys a UE5 update related to this:

UE5 Fully dynamic lighting and shadow setup for mobile (android, iOS)

For:
Unreal Engine 5
Target Platform: Mobile
Starting from an empty level
Fully dynamic lighting/shadows (using Cascaded Shadow Maps - CSM)
And not using any static/stationary light baking:

Project Settings:
Rendering, Misc Ligthing, Allow static lighting: OFF (restarts editor)

Top right, Settings:
Preview Rendering Level: Android ES 3.1 (or iOS)


Add meshes/objects:

Movable

Add one directional light:

Movable
Use ctrl-L to point light at scene
Directional Light, Cast static Shadows: ON (on by default)
Directional Light, Cast Dynamic Shadows: ON (on by default)
Directional Light, Cascaded Shadow Maps:
-[Dynamic Shadow Distance] lower until you see shadows

Also, make sure scalability setting: sg.ShadowQuality is 1 or more

Has big impact on performance on device, so beware!

[END OF REPORT] - and have a nice day :slight_smile: