Renderer · const

MAX_POINT_LIGHTS

How many point lights the shading pass shades against at once.

Explained in Hello world.

const MAX_POINT_LIGHTS = 16
import { MAX_POINT_LIGHTS } from '@driftengine/core';

In depth

It was eight, and eight is what an ordinary lamp-lit courtyard broke over: six lamps and a brazier inside 8.7 m take seven of them, so a gate's two lights — equidistant by construction, both 12.52 m out — contended for the one remaining slot and only ever one of them was rendered. More slots do not make the budget unbounded, and they are not what fixes contention; CONTENTION_BAND_M in pointLightSelection.ts is, by making the trade continuous. They buy the room that stops a scene this ordinary from having to make the trade at all.

It was ten, and ten was a texture-unit limit that no longer exists. The comment here used to say that raising it "costs a texture unit and a pool slot each" and that eleven "would spend the last guaranteed unit, so this is the end of the road". That was true while each light's shadow was its own samplerCube. Every point shadow is now one layer of one TEXTURE_2D_ARRAY — see pointShadowArray.ts — so a light costs a layer and a pool slot, and no bindings at all.

Sixteen because that is what costs nothing. A cube at face 512 was 6.29 MB and the pool plus the two live maps was sixteen of them, 100.7 MB. An octahedral layer at 1024 is 4.19 MB, so sixteen lights is a pool of twenty plus two live, twenty-two layers, 92.3 MB — less than the storage it replaces, with six more shadowed lights. Eighteen is where the memory exactly equals what the cubes cost, which is the number to reach for if a scene ever wants more, and the arithmetic is written down here so nobody has to re-derive it.

What limits it now is the shader rather than the bindings: every one of these is a slot in five uniform arrays and an iteration of the light loop in the widest permutation of the largest shader in the engine.