Quick answer: Light leaking through walls and floors is almost always a shadow map problem, not a light problem. Visualize the shadow map, dial in shadow bias and normal bias, thicken paper-thin geometry, and enable two-sided shadow casting. If the leak happens at range, look at cascade splits and distance fadeout.
Light leaks are one of those bugs that every 3D game ships with at least one of, and they’re disproportionately annoying for players because they break immersion immediately. You see a glowing seam along the floor where none should exist, or the sun lighting a basement, and you know something is wrong even if you can’t name the cause. This guide walks through the most common culprits and the knobs to tune across Unity, Unreal, and Godot.
First: Is It the Shadow Map or the Geometry?
Every 3D engine I’ve worked with has a shadow map visualizer. Use it before you touch anything else. In Unity’s HDRP, enable the Shadow Map debug view from the Rendering Debugger. In Unreal, use Show > Visualize > Shadow Frustums and r.Shadow.Debug.ShowVirtualShadowMap 1. In Godot, enable Display Directional Shadows in the rendering debugger.
What you’re looking for is texel size at the point of the leak. If the wall casting the shadow occupies only one or two shadow-map texels, you cannot resolve its thickness with the current shadow resolution. No bias tuning will rescue you — the map is the problem. Increase shadow map resolution for that light, shrink the shadow frustum, or thicken the geometry.
Shadow Bias and Normal Bias
If the shadow map clearly covers the wall but light still leaks, you’re fighting bias. Shadow bias offsets the shadow comparison along the light direction; it’s what prevents a surface from shadowing itself (“shadow acne”). Too little bias and you get acne. Too much and you get Peter Panning — the shadow detaches from the object’s contact point, and light leaks under the feet.
The reliable procedure: turn shadow bias down until acne just appears on flat lit surfaces, then nudge up by 10–20% until acne vanishes. That’s your minimum viable bias. Then adjust normal bias to kill any remaining acne on curved surfaces. Normal bias samples the shadow map slightly offset along the surface normal, which hides self-shadowing on gentle curves without lifting shadows off the floor.
// Unity HDRP directional light — a good starting point
light.shadows = LightShadows.Soft;
light.shadowBias = 0.05f; // light-direction bias
light.shadowNormalBias = 0.4f; // normal-direction bias
light.shadowNearPlane = 0.2f;
// Unreal CVars for scene-wide tuning
r.Shadow.CSMDepthBias 10
r.Shadow.CSMSlopeScaleDepthBias 3
r.Shadow.FilterMethod 1 // PCSS
Godot 4 exposes directional_shadow/bias and directional_shadow/normal_bias on DirectionalLight3D with similar semantics. Its defaults are reasonable but often need tightening for indoor scenes because the default frustum is sized for outdoor terrain.
The Paper-Wall Problem
A huge fraction of “light leaks through my wall” reports come down to walls that are modeled as single-sided quads or as boxes one centimeter thick. Shadow maps can’t resolve that reliably at any useful distance. Two fixes:
Thicken the geometry. Walls should be at least 10 cm thick for interior environments and thicker for exteriors. If your art pipeline ships thin walls, add a shadow-only backer mesh that sits behind each wall piece and casts shadows but isn’t drawn to the G-buffer. Unity lets you set a mesh renderer to Shadows Only; Unreal has Hidden Shadow; Godot exposes shadow_mode = SHADOW_ONLY on MeshInstance3D.
Two-sided shadows. If the wall material is single-sided, the back face doesn’t cast a shadow and light pours through any seam at the top or bottom. Enable two-sided shadow casting on all wall and floor materials, even if the surface itself renders single-sided. It’s a small perf cost and it kills an entire category of leak bugs.
Every time I’ve been called over to help fix a light leak, the first thing I do is mash a cube into the wall in the editor and see if the leak survives. If it does, it’s bias. If it doesn’t, it’s geometry. That five-second test saves hours.
Cascaded Shadow Maps and Distance Falloff
Directional lights use cascaded shadow maps (CSM) to cover large view distances. Each cascade covers a different distance range with a different texel size. Leaks are common at cascade boundaries because the simulation switches from a tight, sharp shadow to a coarse, bleedy one in a single step.
Push your cascade distances in. Most games default to a far cascade at 200m or more, which bleeds resolution on geometry the player will never reach. Profile where your players actually are and set the last cascade just past that. Enable cascade blending if your engine supports it; it softens the discontinuity at the cost of some perf. In Unreal, r.Shadow.CSMSplitPenumbraScale and the per-light cascade distribution exponent both affect this. In Unity URP, Cascade Blend in the URP asset. In Godot, tune the directional shadow split settings on the light.
Depth Testing and Translucency Surprises
A category of leak bugs isn’t really a leak — it’s a depth-testing issue. If your wall material renders with Transparent blend mode, it doesn’t write depth, and any lighting pass that depth-tests against the G-buffer will treat the wall as if it isn’t there. Keep architectural geometry in Opaque or Masked blend modes. Reserve transparent materials for glass, particles, and decals.
Decals that use screen-space projection can also appear to leak light through walls when they project onto geometry behind the visible surface. Clamp decal projection to a bounded volume or switch to mesh-based decals for precise control.
Regression-Proofing the Fix
Once you’ve fixed a leak, add a screenshot test. Stand the camera in the exact position where the bug fired, render to a PNG, and compare pixel-by-pixel against a reference image on every nightly build. The most frustrating thing about lighting bugs is that a seemingly unrelated change — a new post-process setting, a shader variant collection update, an upgraded render pipeline — will bring them back six months later. A three-line comparison test in CI is cheap insurance.
Related Issues
For GPU-side issues adjacent to shadows, see best practices for error logging in game code. For a broader look at rendering-related reports, read how to debug streaming hitches in open world games.
Bias is a slider. Geometry is a truth. Always check the truth first.