Shadow mapping; shadow acne; peter-panning

Depth-map shadows and their two classic bugs: stripey self-shadowing (acne) and shadows that float away from the object (peter-panning).

the shadows look stripeythe shadow is detached from the objectshadow biaszebra stripes on my 3d modelfloating shadow under the objectwhy do my shadows look weirdshadowmapblocky pixelated shadow edges

See it

Live demo coming soon

What it is

Real-time shadows are a trick: the renderer first draws the scene from the light's point of view and stores only depth, producing a shadow map. When shading each pixel it asks 'is this point farther from the light than what the map recorded?' If yes, it's in shadow. The whole technique is one depth comparison, which is why its failure modes are so specific and so famous.

Shadow acne is the dark zebra striping across lit surfaces: the shadow map has finite resolution and precision, so a surface's own depth sometimes rounds to slightly greater than its recorded depth and the surface shadows itself. The standard fix is a bias, nudging the compared depth away from the light. Push the bias too far and you get peter-panning: the shadow detaches from the object's feet and the thing looks like it's hovering, named for the boy whose shadow came loose.

Gotcha: bias is a tightrope, and the better move is usually to stop needing so much of it. Shrink the light's shadow camera frustum to hug the actual scene (a directional light covering 1000 units wastes almost all its map resolution), prefer normal bias over constant bias, render back faces into the map for closed meshes, and use PCF soft shadows so the edges stop looking like stair steps. For anything static, bake the shadows into a texture and skip the whole problem.

Ask AI for it

Set up clean real-time shadows in this three.js scene: enable renderer.shadowMap with PCFSoftShadowMap, give the directional light a 1024 or 2048 shadow map, and tighten its shadow camera (left, right, top, bottom, near, far) to fit just the objects that need shadows. Fix striping with normalBias around 0.02 rather than a large constant bias, so the shadow stays attached at the contact point. Add a CameraHelper on the shadow camera so I can see the frustum while tuning, and bake or disable shadows on anything static.

You might have meant

depth buffer z bufferbakingambient occlusionz fightingrender target

Go deeper