Documentation
    Preparing search index...

    Class StencilState

    §57's stencil member: the stencil test a material's draws run under, and what they write back (§67).

    // Pass 1 — punch the mask. Writes 1 wherever this shape covers, and no colour.
    const write = new UnlitMaterial({
    color: [0, 0, 0, 0],
    colorWrite: false,
    depthWrite: false,
    stencil: { func: "always", ref: 1, passOp: "replace" },
    });

    // Pass 2 — draw only inside it. Tests, never writes.
    const inside = new UnlitMaterial({
    color: [0.9, 0.3, 0.2, 1],
    stencil: { func: "equal", ref: 1, writeMask: 0 },
    });

    A material that declares no stencil leaves the stencil test disabled, which is GL's initial state and the state every frame this engine drew before this class existed ran in. That is the byte-identity guarantee, and it is the property that let this land under the pixel-golden gate.

    new StencilState() is always/ref 0/0xff/0xff/keep/keep/keep — a stencil test that is enabled and passes everything, changing no stored value. It is a no-op with a cost, and that is the point: the only thing a bare StencilState changes is that enable(STENCIL_TEST) is issued, so a material that opts in and then names nothing gets the same picture, and every field it does name is the only thing that moved.

    Every property below is an accessor applying the same rule the constructor applies. The backend maps these names through a fixed table and passes the numbers to stencilFunc, stencilOp, and stencilMask; §61 forbids throwing inside a frame, so the assignment is where a bad value has to fail. A rejected write leaves the previous value in place.

    Mutating a StencilState does not announce anything to a material's version counter, for the reason §57's other render state does not: a backend reads render state per draw and caches none of it.

    Index
    • get readMask(): number

      The bits of the reference and the stored value the test looks at; 0xff (all eight) by default.

      This is the bit-plane selector nested clipping needs: a clip that owns bit 2 tests with readMask: 0b100 and is blind to every other level's bits.

      Returns number

    • set readMask(value: number): void

      Parameters

      • value: number

      Returns void

    • An independent copy. Materials share a StencilState by reference — like every other resource in §83's model — so this is how a caller derives a second pass from a first without editing the first.

      Returns StencilState