Skip to content

ForwardPlusLighting

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:124

Forward+ tiled light culler for 2D scenes.

Subdivides the screen into TILE_SIZE-pixel tiles and assigns each light to every tile its bounding box overlaps. Per-fragment shading then iterates only the lights bound to its tile (capped at MAX_LIGHTS_PER_TILE) instead of every light in the scene — the cost flips from O(total_lights) to O(lights_per_tile).

Tile data is uploaded each frame via a single DataTexture  (light indices + per-tile meta scalars). Sprite-friendly extras:

  • Reservoir eviction — when a tile saturates, lower-scored lights lose slots to higher-scored newcomers, keeping the visible set close to the “would-be-brightest-K” ideal.
  • Per-category fill quotas — castsShadow: false lights compete only within their own Light2D.category bucket, so a thousand cosmetic slime glows can’t drown out hero torches. Tunable per-bucket via setFillQuota / getFillQuota / resetFillQuotas.
  • Importance bias — Light2D.importance multiplies the tile-rank score, letting hero lights resist eviction.

Owned by DefaultLightEffect (and other tiled-Forward+ effects); end users rarely instantiate this directly.

new ForwardPlusLighting(): ForwardPlusLighting

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:185

ForwardPlusLighting

readonly ambientNode: UniformNode <"vec3", Vector3 >

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:183


readonly screenSizeNode: UniformNode <"vec2", Vector2 >

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:180


readonly tileCountXNode: UniformNode <"int", number>

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:179


readonly worldOffsetNode: UniformNode <"vec2", Vector2 >

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:182


readonly worldSizeNode: UniformNode <"vec2", Vector2 >

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:181

get tileCountX(): number

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:204

number


get tileTexture(): DataTexture 

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:200

DataTexture 

createTileLookup(): (tileIndex, slotIndex) => VarNode <"int", ConvertNode <"int">>

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:602

(tileIndex, slotIndex) => VarNode <"int", ConvertNode <"int">>


dispose(): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:629

void


getFillQuota(category): number

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:315

Read the per-tile quota currently configured for a fill-light category. Mirrors setFillQuota — accepts either a string (hashed) or a raw bucket index.

string | number

number


init(screenWidth, screenHeight): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:208

number

number

void


resetFillQuotas(): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:306

Reset every per-bucket fill quota back to the default (MAX_FILL_LIGHTS_PER_TILE). Used by the declarative categoryQuotas prop on light effects so that removing a key from the prop record actually clears that bucket’s override (otherwise stale per-bucket values would linger across re-renders).

void


resize(screenWidth, screenHeight): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:253

number

number

void


setFillQuota(category, quota): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:291

Set the per-tile quota for a fill-light category. Lights in this bucket will be capped at quota concurrent slots per tile; the (quota + 1)-th and later in-range fills lose to score-based eviction (or get rejected if the tile is otherwise full).

Raising a quota lets more fills of that type contribute exact lighting in dense clusters at the cost of more shader-loop iterations per fragment in saturated tiles. Lowering tightens the cap (cheaper, dimmer dense areas). Setting to 0 disables fills in that bucket entirely.

string | number

Either a category string (hashed via the same djb2 used by Light2D.category) or a raw bucket index 0..3.

number

Slots per tile, clamped to [0, MAX_LIGHTS_PER_TILE].

void

forwardPlus.setFillQuota('slime', 4) // up to 4 slime fills per tile
forwardPlus.setFillQuota('water', 0) // disable water fills entirely

setWorldBounds(worldSize, worldOffset): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:262

Vector2 

Vector2 

void


update(lights, maxLights?): void

Defined in: packages/three-flatland/src/lights/ForwardPlusLighting.ts:321

Light2D[]

number = lights.length

void