Documentation
    Preparing search index...

    Interface RenderBatch

    One merged draw: items consecutive render items, concatenated into one interleaved vertex stream and one index stream.

    Pooled and rewritten. The record and both typed arrays belong to the RenderBatcher that produced them and are overwritten by its next RenderBatcher.next call. vertices and indices are the batcher's whole staging arrays, which may be longer than this batch needs — read vertexCount × floatsPerVertex floats and indexCount indices, and upload with the five-argument bufferSubData rather than taking a subarray (which would allocate a view per frame).

    interface RenderBatch {
        clip?: RenderItemClip | null;
        color: ColorRGBA;
        contentVersion?: number;
        floatsPerVertex: number;
        hasColors: boolean;
        hasUvs: boolean;
        indexCount: number;
        indices: Uint32Array;
        items: number;
        kind: "unlit" | "sprite";
        material: BatchableMaterial;
        mode: GeometryDrawMode;
        opacity: number;
        scissor?: ScissorRect | null;
        texture: MaterialTexture | null;
        vertexCount: number;
        vertices: Float32Array;
    }
    Index
    clip?: RenderItemClip | null

    §67's clip, shared by every merged item, or null where none of them is clipped (R-23, 2026-08-21).

    A run breaks where the record changes, so this is one value for the whole batch exactly as the material is: the same material under two different clips is two different draws, and merging them would let one scroll view's content escape into another's. A backend applies it exactly as it applies a single item's.

    Never a mask pass: every clip owns its own bit plane and emits exactly one mask draw, so two consecutive mask items never share a record and a run of them never forms.

    Optional for RenderItem.clip's reason — a hand-built batch predating §67 must still typecheck, and undefined reads as "unclipped" — but the batcher itself always writes it.

    color: ColorRGBA

    The RGBA the whole batch is tinted by — an unlit material's color or a sprite material's tint, the same live array the material owns (copy it if you need to keep it).

    One value for the batch because "same material instance" is the batching rule: §55's tint and §57's colour are material state, so merging never needs them per vertex. That is also why a sprite batch carries no colour stream (see RenderBatch.hasColors).

    contentVersion?: number

    Change-detection stamp for §65 / §86's idle batch cache (R-8 follow-up).

    A non-zero value is an FNV-1a mix of each merged item's geometry version, transform version, and world-matrix elements. The WebGL uploader skips bufferSubData when this stamp and the vertex/index counts match the last upload into the same layout slot.

    0 means "versions unavailable — always re-upload." That is today's default: a hand-built item with no transformVersion, or any run that includes one, keeps the pre-cache upload path so a scene that never opted into versioning is bit-identical.

    floatsPerVertex: number

    Floats per vertex in the interleaved stream: position (3), then uv (2) when RenderBatch.hasUvs, then colour (4) when RenderBatch.hasColors, in that order.

    hasColors: boolean

    Whether the stream carries per-vertex colour, i.e. whether the material declares §53's vertexColors (R-19). Always false for a sprite batch: §55's tint is material state, shared by the run by construction.

    hasUvs: boolean

    Whether the stream carries uv, i.e. whether the material samples a texture. Always true for a sprite batch (§55's quad is a texture map by definition).

    indexCount: number

    Indices in RenderBatch.indices; the draw's element count.

    indices: Uint32Array

    Indices into RenderBatch.vertices, already offset per item.

    items: number

    How many consecutive render items this batch consumed. Always ≥ 2 — a run of one is not a batch (see the module header).

    kind: "unlit" | "sprite"

    Which pipeline draws it (§64, §66 key 3) — the merged items' kind.

    The one material every merged item carries — the same object, not an equal one. Every piece of §57 render state the draw needs is read off it.

    The merged items' shared draw mode (§53).

    opacity: number

    §57's opacity for the shared material, multiplying the alpha above.

    scissor?: ScissorRect | null

    §67 rectangular scissor, shared by every merged item, or null where none of them names one (2026-09-06).

    A run breaks where the rectangle changes, so this is one value for the whole batch: two same-material draws under different scissors are two different draws. undefined reads as "no per-item scissor", matching RenderItem.scissor.

    texture: MaterialTexture | null

    The texture the batch samples — a sprite material's texture (§55) or an unlit material's map (§57, R-19) — or null when it samples none.

    Resolved here rather than by the backend so the draw path reads one field instead of asking which kind of material this is; the same reason RenderItem snapshots transparent and materialId rather than chasing the material per comparison. A backend still resolves it to a GPU handle through its own cache, and a batch whose texture resolves to nothing is skipped or drawn untextured by exactly the rule that backend applies to a single item.

    vertexCount: number

    Vertices in RenderBatch.vertices.

    vertices: Float32Array

    Interleaved vertex data, world-space positions. See the interface note.