Dynamic Indoor Lighting - Shadow Banding Artifacts

Hey everyone,

I’m trying to light an angular indoor environment with dynamic lights, but can’t find a decent way to set it up without running into major self-shadow artifacts. Changing the shadow bias can somewhat alleviate the issue, but even a bias of 1 doesn’t get rid of it completely, not to mention that the overall shadow accuracy greatly suffers in return.

Does anyone know how to achieve usable dynamic indoor lighting (in UE4.20 or 4.21)? Is baked lighting the only viable option?

Sample project download (18MB)

Dynamic shadows have really poor quality in UE 4, you have to increase shadow bias a lot to alleviate that.

That’s quite… unfortunate. As mentioned before, I have to set the shadow bias to the maximum value to reduce the artifacts to an acceptable level. And that’s just trading one problem for another.

If anyone can share some tips and tricks to avoid these issues with dynamic lighting, I shall be eternally grateful!

There’s a few technical factors at play here, just like with anything, there’s limitations on how to use any software tools; if you can get a better understanding of the “why” it’s happening, you can make better decisions on how to use these things.

That said, the main thing you’re trying to do is light an interior with dynamic lighting only- correct?
If that’s the case, you’re going to have to play by some rules.

Dynamic lights use classic shadow mapping techniques, so the size and accuracy of the shadow map will be limited. Here’s some important things that play into the shadow map’s limitations:

  • angle of the shadow receiving surface to the light’s vector (this is true for dynamic directional, spot, and point lgihts- but is VERY obvious with directional lights at steep angles/low elevations)
  • radius of the light: this determines how much surface area the shadow map will have to cover, larger areas mean the shadow map (which is limited in size) has to cover more area, leading to lower resolution shadows
  • default settings: shadows maps use default settings that are more optimized friendly, making them useful for most applications and target hardware. In some cases, like cinematics for example, you’ll want to increase your shadow map resolutions for problem lights, improving realtime shadowing
  • object shadows: objects also determine their own shadow casting resolution; by default the resolution is balanced between performance and quality- but in some cases (i.e. cinematics) you’ll want to increase shadow resolution for some assets, for example a character or hero mesh, this usually alleviates the problems you’re specifically having

Here’s some tips for you:

  • don’t make dynamic light attenuation radii super big (if it’s a shadow casting light), use the largest radius you can while obtaining the results you want. In most cases, you may have to come up with custom solutions for filling in the gaps- i.e. fill lighting. Professional lighting artists will usually create custom light rigs for environments, etc.- this is a limitation of realtime lighting pipelines in general, not an Unreal problem specifically
  • don’t go increasing shadow map resolution all over the place, unless you’re doing prerendered cinematics or a product not targeted for realtime production- then feel free to crank all your shadow res up like crazy
  • if you can, try to use a hybrid static/dynamic lighting rig for whatever you’re doing
  • realtime dynamic lighting in production is really hard, so don’t feel too bad if you find it difficult; at studios we usually have dedicated graphics engineers that will modify the engine and add new features to alleviate these problems (obviously probably not an option for you, but just giving you a peek inside how pro studios work so you don’t pull your hair out thinking you’re doing everything wrong)
  • use spotlights: point lights are very limited with their shadow map res for obvious reasons; try to use spot lights whenever possible to get best results
  • avoid (shadow casting) point lights: whenever possible, avoid shadow casting point lights, they are super expensive and can kill perf when not used correctly. In production I usually disable this feature in the engine so that designers, etc. don’t accidentally place shadow casting point lights everywhere when grayboxing levels and kill perf (I’ve had this happen before in the studio environment and it’s a pain)

If you have any other questions, feel free to ask!

2 Likes

Point and spot shadows in UE4 are done by storing the distances from each point to the light into a 16-bit floating point depth buffer. Since it’s 16-bits, it can only represent 65536 unique values, and since it’s floating point these values are distributed in a logarithmic scale with precision being the highest closest to zero and dropping as the value increases.

This means that the further an object is from the light, the smaller is the precision of it’s distance value stored in the shadow depth buffer, causing self-shadow artifacts (banding) and requiring higher bias values.

Your scene hits all of these limitations, *hard. *You’re using lights with a radius of 3000 plus a custom attenuation falloff exponent causing light to reach further away. Basically, the point and spot shadows were designed for small radius lights and break apart with large radius ones.

Yes, it’s annoying. Epic should allow more options for dynamic point/spot shadow casting to support more use cases. Large radius lights would work much better if they could use linear 16-bit integer depth instead of floating point, for example. That would give around 21 shadow “steps” per unit for a 3000 radius light, more than enough for very detailed self-shadowing.

Unfortunately this is an old flaw of UE4 as it has not implemented any slope bias method yet. It has nothing to do with shadowmaps depth. A thread about it:

https://forums.unrealengine.com/unre…tifacts/page25

Thank you so much for the detailed answers! It’s super helpful to know where exactly the issue is coming from and that there isn’t much that can be done about it. Not for a small indie dev, anyway.

Static lighting isn’t an option for me, but I’ll try placing shadow-casting point lights more strategically, lower their radii, and replace them with spotlights whenever possible. Maybe I can leverage DFAO to give my scenes more depth and detail even without shadow-casting lights all over the place.

I’m not sure if this is really the same issue. I think the thread you linked to is mainly talking about problems with smooth surfaces, which can be ‘fixed’ by increasing the polycount. In my case, I could increase the polycount of the objects a thousandfold and it wouldn’t make any difference.

It is still a factor.

It is.

Disregarding the issue, such usage strategy for point lights is not optimal.