Switches the shadow comparison on or off for the draw about to be issued
(§49's receiveShadow, §69) — mirrored on the CPU and uploaded only on
change, exactly as LitProgram.setFeatures mirrors useMap.
Pass lights.hasShadow && item.receiveShadow: the two reasons a draw is
not shadowed are "nothing casts" and "this node opted out", and folding
them into one uniform is what keeps a shadowless frame at zero calls while
a non-receiver inside a shadowed frame costs exactly one.
Uploads the frame's shadow matrix, biases and tap size — or nothing at
all, when lights.hasShadow is false. Call once per viewport, beside the
ambient and directional uploads.
The sampler unit is uploaded lazily, on the first view that actually has a shadow, exactly as the albedo sampler is: a pipeline that never shades a shadowed frame never mentions the unit.
StaticresolveLooks the six locations up on a linked program, throwing the §89
SHADER_COMPILATION_FAILED requireUniform throws if one is missing.
the pipeline name used in the failure message
One shaded pipeline's shadow uniforms: the six locations, the sampler-unit upload, and the CPU mirror that keeps a frame with no casting light emitting no GL call at all (§69, R-18).
Shared by LitProgram and
gl-standard.ts'sStandardProgramfor PunctualLightUniforms' reason: the two stages consume the identicalSceneLightsfields through the identical GLSL chunk, and a class each would be two places for the skip rule to drift apart.The skip rule, and why it is byte-identity rather than an optimisation
useShadowis abooluniform whose CPU mirror starts atfalse, which is what GL initializes abooluniform to. A frame in which no light casts therefore uploads nothing at all — not the matrix, not the biases, not the sampler, not the switch — so a scene lit the way every scene was lit before §69 shipped issues byte-for-byte the GL sequence it always did. The mirror-at-GL-initial-0 technique on its fourth recorded use (R-15'sboolencode switch, R-38's permissive layer mask, R-17's light count).The pixel half of that claim lives in the two shaded fragment stages, and is kept the way R-17 kept it: the shadow term multiplies the existing directional expression inside an
if (useShadow), so with the switch off the arithmetic is the arithmetic those stages performed before, operation for operation. Nothing is re-associated.The split between the two methods is the split between per-view state (the matrix and the biases, which belong to the light) and per-draw state (§49's
receiveShadow, which belongs to the node).