Phaser AE

3D Point and Spot Lights

Free packv3.0.0-33DLook

Point and spot lights as ordinary game objects. A light lives in a scene, can follow an object, is killed by a tag sweep and is tweened like anything else, so there is no separate light list to keep in step with the world.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 20, 2026

3D Point and Spot Lights: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

lighting3d

function lighting3d(opts: Lighting3dOptions = {}): Pack<{ lights: Lighting3dApi }>

The lighting-3d pack: point and spot lights as roster objects, packed into the buffer render-3d binds. Requires a 3D world; without render-3d the lights exist and simply light nothing.

Types

Light3dData

interface Light3dData

The light3d sub-object on a light's handle. Every field is live.

  • radius: number — How far the light reaches, world units. Beyond it, nothing.
  • color: string — Colour, css — the kernel packs and unpacks the column.
  • intensity: number — Brightness.
  • cone: number — Spot outer cone half-angle in radians; 0 or less makes it a point light.
  • innerCone: number — Full-brightness inner cone half-angle in radians; -1 derives legacy falloff.
  • dir: number — Spot direction yaw, radians.
  • pitch: number — Spot direction pitch, radians; positive points down.
  • on: number — 1 on, 0 off.
  • flicker: number — Flicker depth, 0..1 — a torch, a faulty lamp.
  • flickerSpeed: number — Flicker speed.

Light3dHandle

type Light3dHandle = Handle & { light3d: Light3dData }

A light is a roster object with a light3d sub-object.

Light3dSpec

interface Light3dSpec

What lights.add takes.

  • x?: number — World x.
  • y?: number — World y.
  • z?: number — World z.
  • radius?: number — Reach, world units. Default 12.
  • color?: string — Colour, css. Default warm white.
  • intensity?: number — Brightness. Default 1.
  • cone?: number — Make it a spot with this outer cone half-angle, degrees. Default none.
  • innerCone?: number — Full-brightness inner cone half-angle, degrees. Omit to preserve legacy falloff.
  • dir?: number — Spot yaw, degrees. Default 0.
  • pitch?: number — Spot pitch, degrees; positive points down. Default 90 (straight down).
  • flicker?: number — Flicker depth 0..1. Default 0.
  • flickerSpeed?: number — Flicker speed. Default 8.
  • follow?: Handle — Follow this object.
  • id?: string — Object id.
  • layer?: LayerName — Layer.
  • tags?: string[] — Tags.

Lighting3dApi

interface Lighting3dApi

game.lights.

  • add(spec?: Light3dSpec): Light3dHandle — Add a light.
  • readonly all: ReadonlyArray<Light3dHandle> — Every live light.
  • readonly active: number — How many were sent to the renderer last frame.
  • max: number — The cap; lights past it (the furthest from the camera) are dropped. Default 64, ceiling 256. It is a real cost, not a formality. Under 24 lights render-3d shades a FLAT LIST, so every lit fragment loops over every light sent; from 24 on (its default clustered: 'auto') it bins them into a froxel grid, and a fragment loops only the lights in its own cell. On WebGL2 the nearest eight are shaded, as a flat list. Raise it for a light show and watch the frame time.

Lighting3dOptions

interface Lighting3dOptions

Manifest options.

  • max?: number — Most lights sent to the renderer at once; the nearest win. Default 64, ceiling 256. What they cost depends on how render-3d shades them: see Lighting3dApi.max.