Uploads the frame's point and spot lights (§68), or nothing at all — see the class header for when, and for why "nothing at all" is the contract rather than a shortcut. Call once per viewport, beside the ambient and directional uploads.
StaticresolveLooks the five locations up on a linked program, throwing the §89
SHADER_COMPILATION_FAILED requireUniform throws if a driver optimised
one away — which it cannot, since the loop bound is a uniform.
the pipeline name used in the failure message
One shaded pipeline's light-set uniforms: the five locations, and the CPU mirror that keeps a scene without point or spot lights emitting no GL call at all (R-17, 2026-08-09).
Shared by LitProgram and
gl-standard.ts'sStandardProgrambecause the upload is not a per-pipeline decision — the two stages consume the identicalSceneLightsarrays 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
#countstarts at0, which is what GL initializes anintuniform to. A frame whoseSceneLights.punctualCountis0while the mirror is0therefore uploads nothing — not the count, not the four arrays — so a scene lit by a directional light and an ambient term issues byte-for-byte the GL sequence it issued before this class existed. The same technique as R-15'sboolencode switch and R-38's permissive layer mask; the third confirmation that seeding a CPU mirror at GL's own initial value is how a feature is added to this backend for free.When the count is non-zero the whole array is uploaded, dead tail included, rather than a live sub-range:
uniform3fvover the record's ownFloat32Arraycopies nothing on the way (the reason@fourjs/renderpacks those arrays as typed arrays), and a sub-range upload would need thesrcOffset/srcLengthoverloads this backend's hand-written GL surface deliberately does not carry.