Stores per-mesh attributes shared across views — tile + geometry indices, Cook-Torrance material parameters, and one UV transform per PBR-map type.

Three texels per mesh, twelve u32 slots total (linearised — base is itemIndex * elementsPerItem):

  • base + 0 tileIndex
  • base + 1 geometryIndex
  • base + 2 PBR material + hatch slot — bits 0-7 are roughness (u8), bits 8-15 are metallic (u8), bits 16-31 are hatchPatternSlot (0 = no hatch, > 0 = index into the per-batch "./HatchPatternTexture".HatchPatternTexture)
  • base + 3 alpha + line-pattern slot — bits 0-7 are alphaMode (0 = OPAQUE, 1 = MASK, 2 = BLEND), bits 8-15 are alphaCutoff (u8 normalised to [0, 255]), and bits 16-31 are linePatternSlot (0 = no per-mesh pattern, fall back to the View's linesMaterial.linePattern; > 0 = index into the per-batch "./LinePatternTexture".LinePatternTexture where the material's pattern entries are written)
  • base + 4 packed albedo (uOffset, vOffset) — two u16s, R = lo
  • base + 5 packed albedo (uScale, vScale) — two u16s, R = lo
  • base + 6 packed metallic-roughness (uOffset, vOffset)
  • base + 7 packed metallic-roughness (uScale, vScale)
  • base + 8 packed normal-map (uOffset, vOffset)
  • base + 9 packed normal-map (uScale, vScale)
  • base + 10 triplanar repeat distance — Float32 bit pattern reinterpret (read in the shader via uintBitsToFloat). Consumed only by the triplanar shader variant; UV-bearing batches ignore it.
  • base + 11 per-mesh line thickness in screen pixels — Float32 bit pattern reinterpret. Consumed by the thick-line draw technique; 0 falls back to the View's linesMaterial.lineWidth.

Each UV transform takes per-vertex vUV ∈ [0, 1] to atlas-space: atlasUV = vUV * (uScale, vScale) + (uOffset, vOffset). Different PBR maps live in separate per-batch atlases (different formats — sRGB for albedo, linear for MR / normals), so each map gets its own transform — artists can pack their textures independently. Untextured meshes write the relevant atlas's sentinel transform (scale = 0) so they collapse to a single sentinel texel without branching in the shader.

Per-material line-pattern entries live in a separate "./LinePatternTexture".LinePatternTexture indexed by linePatternSlot. Splitting them out keeps triangle / point batches from paying any storage for line-only data — a slot of 0 here means "no per-mesh pattern", so the renderer skips the pattern-table lookup entirely.

Hierarchy (View Summary)

Constructors

Properties

buffer: any

CPU-side backing buffer used to populate this texture.

The concrete type depends on the implementation (e.g., Uint32Array, Float32Array, or a view over an ArrayBuffer). This buffer is uploaded to the GPU when updated.

bufferClass: any

The ArrayBufferView class used for the CPU-side buffer.

bytesPerTexel: number

Size in bytes of a single texel in the data texture.

debugging: boolean = true

Enables internal event emission for this data texture.

description: string = ""

Human-readable description of the data stored in this texture.

Intended for debugging UIs and diagnostics (e.g., displayed above inspectors). Subclasses or owners should populate this with a concise explanation of the layout and semantic meaning (e.g., “mesh matrices (Mat4, row-major), indexed by meshId”).

elementsPerItem: number

Number of individual elements (e.g., floats, uint32s) stored per logical item in this data texture.

elementsPerTexel: number

Number of individual elements (e.g., floats, uint32s) stored per texel in the data texture.

format: number

Texture format (e.g., gl.RGBA, gl.RGBA_INTEGER).

gl: WebGL2RenderingContext

The WebGL2 rendering context.

height: number

Texture height in texels.

internalFormat: number

Texture internal format (e.g., gl.RGBA8, gl.RGBA32UI, gl.RGBA32F).

itemSizeInBytes: number

Size in bytes of a single logical item stored in the data texture.

lastUploadTimeMS: number = 0

Duration (in milliseconds) of the last upload to GPU.

This value is 0 until the first upload occurs.

maxItems: number

Maximum number of logical items that can be stored in this texture.

The value of numItems never exceeds this limit.

onUpdated: EventEmitter<DataTexture, undefined> = ...

Emitted when the CPU-side buffer for this texture has changed and been uploaded to the GPU.

This event is intended for debugging tools and monitoring UIs; it is only emitted when debugging is enabled.

texelsPerItem: number

Number of texels occupied by a single logical item in the data texture.

texture: WebGLTexture

The underlying WebGL texture object.

This is the GPU resource that is bound and sampled/loaded by shaders.

type: number

Texture data type (e.g., gl.UNSIGNED_BYTE, gl.UNSIGNED_INT, gl.FLOAT).

useBuffer: boolean

Whether to use a CPU-side buffer for staging data before uploading to the GPU.

width: number

Texture width in texels.

itemSizeInBytes: 48

Accessors

Methods

  • Gets the item at the given index within its portion.

    Parameters

    • itemIndex: number

    Returns {
        albedoUVOffset: [number, number];
        albedoUVScale: [number, number];
        geometryIndex: number;
        metallic: number;
        metallicRoughnessUVOffset: [number, number];
        metallicRoughnessUVScale: [number, number];
        normalMapUVOffset: [number, number];
        normalMapUVScale: [number, number];
        roughness: number;
        tileIndex: number;
    }

  • Parameters

    • itemIndex: number
    • item: {
          albedoUVOffset?: [number, number];
          albedoUVScale?: [number, number];
          alphaCutoff?: number;
          alphaMode?: number;
          geometryIndex?: number;
          hatchPatternSlot?: number;
          linePatternSlot?: number;
          lineWidth?: number;
          metallic?: number;
          metallicRoughnessUVOffset?: [number, number];
          metallicRoughnessUVScale?: [number, number];
          normalMapUVOffset?: [number, number];
          normalMapUVScale?: [number, number];
          roughness?: number;
          tileIndex?: number;
          triplanarScale?: number;
      }

    Returns void

  • Uploads all dirty items to the GPU as efficiently as possible.

    Internal algorithm:

    • Dirty items are indices of items whose data has changed and needs to be uploaded to the GPU.
    • The method sorts all dirty indices and finds contiguous runs (sequences of adjacent indices).
    • For each run, it uploads the run in chunks, where each chunk fits within a row of the texture.
    • This minimizes the number of WebGL texSubImage2D calls by uploading as large a block as possible per call.
    • After all dirty items are uploaded, the dirty set is cleared, the texture is unbound, and update notifications are sent.

    Returns boolean

    True if any uploads occurred, false otherwise.