fixed disconnected shadows

This commit is contained in:
DramaticShape
2026-07-29 21:51:42 -04:00
parent f841378330
commit 18857e039a
5 changed files with 81 additions and 10 deletions
+28
View File
@@ -362,6 +362,34 @@ local function fit(cx, cy, vw, vh)
ShadowMap.bias = ShadowMap.slack / math.max(1, far - near)
end
-- A CASTER sunk slightly down the sun ray before it is drawn into the map.
--
-- The depth compare forgives `slack` world pixels (BIAS + the SLOPE term)
-- so lit surfaces do not acne against their own texels -- but that same
-- forgiveness is what lets the ground right next to a standing figure read
-- as lit: the first `slack` of its shadow falls inside the compare's
-- tolerance, so on screen the shadow starts that far from the feet, and the
-- gap grows as the sun drops (the same bias reaches further horizontally
-- the more oblique the ray). Peter-panning, in the literature; it went
-- unseen while the sun hung at a fixed 45 degrees and shows plainly at a
-- day/night golden hour.
--
-- Storing the card that much DEEPER along the ray cancels the bias for the
-- shadow it throws -- the root lands back under the feet -- while touching
-- nothing else: the card's own lookup now reads a deeper stored value and
-- is more confidently lit, no terrain moved, and the acne margin the slack
-- exists for is intact. For sprite cards and other thin stand-ins only;
-- sinking the TERRAIN would cancel the bias everywhere, which is the acne.
--
-- Valid between begin() and finish(), which is when `slack` matches the
-- frustum the map is being drawn with.
function ShadowMap.sink(model)
local f = sunDir()
local s = ShadowMap.slack
return Mat4.mul(Mat4.translate(f[1] * s, f[2] * s, f[3] * s),
model or IDENTITY)
end
-- Whether the map has to be redrawn for `sig` -- a caller-built stamp of
-- everything the pass depends on (camera, terrain meshes, every pose). A
-- frame that changes none of it reuses the map it already has, which is