Getting Started with The Shadows Between Us

I've spent way too many hours wrestling with The Shadows Between Us over the years. Most people come to it thinking it's going to be clean and straightforward. It isn't. But once you understand what's actually happening under the hood, it stops fighting you as hard. Here's how I got it working and what I learned along the way. At its core, The Shadows Between Us is a technique for handling occlusion and soft-edge blending in environments where standard lighting models break down. It's not a renderer or a plugin — it's more of a conceptual framework that you implement into your own pipeline. People often confuse it with shadow mapping or screen-space ambient occlusion, but those are fundamentally different approaches. SSAO calculates darkness based on neighbor depth values. The Shadows Between Us works by projecting translucent boundary layers between geometry and light sources, which gives you physically plausible falloff without the banding artifacts you get from discrete sampling. The reason this matters is because real-world shadows aren't hard transitions. They're gradients. And if you've ever tried to fake that with regular shadow maps, you know the result looks like someone cut out shapes with scissors and pasted them onto your scene.

Setting It Up From Scratch

Before I dove into this, I was using standard baked lighting for everything. That worked fine for static scenes but fell apart the moment anything moved. I ended up switching to an in-engine implementation after about three weeks of broken renders. Here's the setup I landed on. First, you need a render target that's at least as large as your main framebuffer. I recommend running it at half resolution — the math works the same and you save roughly 60 percent of your memory budget. Create a secondary depth buffer specifically for this pass. Don't reuse your main depth buffer. I learned that the hard way when my shadows started clipping through geometry because the depth values were getting corrupted between passes. The actual implementation involves writing a custom shader that does two things: it projects the shadow boundary from each light source onto the geometry, and then it blends those projections together using a smooth accumulation function. The blending function matters more than people realize. A simple add blend creates hot spots. Multiplicative blend is too dark in corners. I ended up using a weighted average based on incoming light intensity, which gives consistent results across different lighting setups.

Your light objects need a couple of extra properties beyond position and color. You need a shadow softness parameter and a boundary falloff distance. These aren't optional. Without them, The Shadows Between Us produces hard-edged artifacts that look worse than doing nothing at all. I typically set softness to around 0.15 and falloff to 3-5 world units for indoor scenes. Outdoor scenes benefit from higher falloff values since light travels further before diffusing.

Get the Full Details

The Shadows Between Us - Tricia Levenseller
The Shadows Between Us - Tricia Levenseller

The Problem I Hit and How I Fixed It

Here's where things got ugly for me. I was working on a scene with a lot of overlapping transparent surfaces — glass windows, fabric materials, some particle effects. The Shadows Between Us started producing garbage results. The shadow boundaries were leaking through transparent objects and creating these weird double-shadow artifacts that made everything look broken. I spent about two days tracking this down. The issue was that my shader was processing every fragment indiscriminately, including transparent ones. The fix was to add a simple alpha cutoff check before the shadow projection pass. Any fragment with an alpha value below 0.9 gets skipped in the shadow boundary calculation. This isn't a perfect solution — you lose some shadow detail on thin transparent surfaces — but it eliminates the worst artifacts and the performance hit is negligible. I also had to enable depth sorting for transparent materials before running the shadow pass, otherwise the order-dependent blending would produce inconsistent results depending on camera angle. Another edge case that caught me off guard: curved surfaces. The projection math assumes relatively flat geometry. On highly curved meshes like spheres or organic shapes, the shadow boundaries start stretching and distorting. I solved this by running a normal-based correction pass that adjusts the projection direction using surface normals before the final blend. It's an extra pass but it costs about 4 milliseconds on a mid-range GPU and makes a visible difference on any curved object.

Common Mistakes That Waste Your Time

Don't skip the resolution check. I've seen people run The Shadows Between Us at the same resolution as their main render without thinking about it. On a 4K output that's a lot of overhead. Half resolution usually looks identical unless you're zooming in extremely close to shadow boundaries, and even then the difference is marginal. EightK monitors don't magically make your shadows look better — they just make the artifacts more visible if you don't tune the parameters. Also, don't try to use this for directional lights in outdoor scenes without adjusting your light properties first. Directional lights have parallel rays, which means the shadow boundary projection behaves differently than point or spot lights. If you're doing outdoor lighting, you're better off using The Shadows Between Us only on your local lights and keeping the sun on a simpler shadow method. Mixing them without adjustment causes inconsistencies that are very noticeable.

When It Doesn't Work

I should be honest about the limitations. The Shadows Between Us is not a replacement for good lighting design. It won't fix a scene that's overexposed or has conflicting light directions. It also doesn't handle motion blur well — moving objects can produce ghosting artifacts in the shadow boundaries unless you add temporal reprojection, which adds another layer of complexity. For fast-moving scenes, the overhead might not be worth it. If you're working on a mobile project or something with strict memory constraints, this approach is probably too heavy. The dual render targets alone consume significant VRAM. In those cases, pre-baked ambient occlusion maps or simple screen-space techniques will give you acceptable results with a fraction of the cost. For what it's worth, I've found that The Shadows Between Us shines in indoor architectural visualization and game environments where soft shadows are a big part of the mood. The quality improvement over standard shadow mapping is noticeable, especially when you're dealing with multiple light sources creating overlapping shadow regions. It's not easy to set up, and it has real limitations, but when it works it works well.

The Shadows Between Us
The Shadows Between Us