← Back to Docs
  • index.html
  • Clayground
  • Clayground.World
  • LightLayer2d
  • Clayground 2026.8
  • LightLayer2d QML Type

    Lights a ClayWorld2d with coloured Light2d lights and wall shadows. More...

    Import Statement: import Clayground.World

    Properties

    Methods

    Detailed Description

    One full-viewport overlay darkens the world to ambient and lets the Light2d lights brighten and tint it again. Walls block light: hand the layer a grid (setOccluderGrid()) or a list of rectangles (setOccluderRects()) and every light that castsShadows throws soft shadows behind them.

    Walls themselves are lit on the side that faces a light and cast their shadow behind them: the part of a ray inside the wall the pixel belongs to does not count, nor the part inside a wall a torch is set into.

    Place it as a child of ClayWorld2d and set world. The layer moves itself into the world's canvas, so it stays locked to the viewport, sits above the world's content and below HUD items declared beside it - and a ScreenFx2d on the same world grades the lit picture, not the unlit one.

    ClayWorld2d {
        id: theWorld
        // ...
        LightLayer2d {
            id: lighting
            world: theWorld
            ambient: "#0b0a12"          // a dungeon; "#6a6a88" is dusk
        }
        Component.onCompleted: lighting.setOccluderGrid(
            cols, rows, cellSize, (cx, cy) => grid[cy][cx] === cellWall)
    }

    How it blends: Qt Quick composes premultiplied, so the layer writes the darkening into alpha and the colour of the light into rgb, and the screen shows glow + scene * (1 - darkness). The scene is scaled by the brightest channel of the light that reaches it; the part of the light that is colour rather than grey is added on top, scaled by glow. It is an approximation of multiplying the scene by the light colour - exact for white light, and warm light turns grey stone warm.

    At most 16 lights are drawn at once: the lights whose circle reaches into the viewport, the brightest and closest first.

    Cost: a pixel pays only for the lights that reach it, and a shadowed light marches two occluder samples per grid cell between light and pixel. resolutionScale renders the layer at a fraction of the viewport's resolution and scales it up.

    See also Light2d, ScreenFx2d, and AnchoredMask.

    Property Documentation

    active : bool

    When false the layer is not drawn at all.


    ambient : color

    Light level where no light reaches.

    Its brightest channel is how much of the scene is visible in the dark; its hue tints the dark like a light's colour does. "#000000" is pitch black, "#ffffff" switches darkness off.


    bands : int

    Quantises the light level into this many steps, for a retro look; 0 (default) is a smooth falloff.


    dither : real

    Ordered (Bayer 4x4) dither amount in 0..1.

    With bands it breaks the band edges into a pattern; without, it hides the 8-bit steps of long gradients.


    emissive : Item [read-only]

    Parent for things that give off light themselves.

    Items parented here are drawn above the darkness, so a flame, a spark or a pair of eyes in the dark keeps its full colour where the floor around it is black. The item scrolls with the world and has the size of world.room, so children place themselves exactly as they would in the room (y: parent.height - yWu * pixelPerUnit). It is hidden together with the layer, and it does not cast or receive light - pair a glowing thing with a Light2d if it should light its surroundings.


    falloff : real

    How fast light fades with distance: the light at a fraction x of the radius is (1 - x)^falloff. 2 (default) pools light around its source, 1 fills the circle more evenly.


    glow : real

    How strongly the colour of a light is added on top of the brightened scene (0 = lights only brighten).


    lightCount : int [read-only]

    How many lights were drawn in the last frame.


    maxLights : int [read-only]

    How many lights the shader takes at once.


    resolutionScale : real

    Renders the lighting at this fraction of the viewport's resolution (0.25..1) and scales it up linearly.

    Light is smooth, so 0.5 is hard to tell apart from 1 and costs a quarter of the fragment work. The dither and band edges get coarser.


    shadowHardness : real

    How much wall a ray must cross to be fully blocked, as 1 / cells. The default 2.5 blocks behind 0.4 cells of wall; lower values let light seep through thin walls.


    world : var

    The ClayWorld2d to light.


    Method Documentation

    object clayInspect()

    Reports the layer's settings, lights and occluder grid as plain JSON, for tooling. Pull-only and side-effect free.


    void clearOccluders()

    Removes all occluders; lights no longer cast shadows.


    bool isOccluded(real xWu, real yWu)

    Whether the occluder grid blocks light at this world position.


    void setOccluderCell(int cx, int cy, bool solid)

    Changes one cell of the current occluder grid - a door opens, a wall crumbles.


    void setOccluderGrid(int cols, int rows, real cellSizeWu, var isSolid, real originXWu, real originYWu)

    Makes the cells of a grid block light.

    isSolid is called as isSolid(cx, cy) for every cell and returns true for a wall. Cell (0, 0) is the lower-left one; its lower-left corner is at originXWu / originYWu (optional, default: the world's minimum). One call for a whole level: the grid becomes a texture of one pixel per cell.


    void setOccluderRects(list rects, real cellSizeWu)

    Makes rectangles block light.

    Each entry has xWu, yWu (the top edge, as for a RectBoxBody), widthWu and heightWu - so a list of wall bodies can be passed as is. The rectangles are rasterised onto a grid over the world bounds with cellSizeWu cells (default 1); a cell blocks when a rectangle covers its centre.


    list visibleLights()

    The Light2d items drawn right now, brightest and closest first.