Luxar Viewer API Documentation - v2026.10.19
    Preparing search index...

    Module rendering/materials/_shared/shared-graph-tsl

    One TSL node graph per material CONFIGURATION, shared by every material of that configuration.

    three's WebGPU renderer caches a node build (NodeManager.getForRender → NodeBuilder.build, 11–28 ms for a gsplat graph) under a key that hashes every node of the material's graph by its id. A wrapper that builds its own graph over its own uniform() / texture() leaves therefore never shares a build, so N materials of one configuration cost N builds — 92 of them in a 6 s playback pass of a 50-timepoint partition (#2956's gating activates each timepoint's parts on first visit). WebGL caches programs by source and never paid this.

    Here the graph is built ONCE per configuration key, over FORWARDING leaves: each forwarding leaf is a fresh uniform() / texture() of the same type whose updateBefore (object granularity — run for every draw, before the draw's bindings upload) copies the value of the same-named leaf of the material being drawn. The wrapper keeps its own leaves as plain value holders, so its uniforms proxies, clone and setter paths are unchanged; the cached NodeBuilderState (whose bindings point at the shared forwarding leaves) is then valid for every material of the key, and each draw still uploads its own material's values into its own per-object binding clone. This is the pattern three's built-in node materials use for map / color (materialReference), done generically over a whole leaf set so it also covers .load() texture fetches, which a ReferenceNode cannot express.

    The graph slots shared are vertexNode, colorNode and depthNode (the last written only by the pick factories).

    Contract for a caller:

    • Everything the factory reads at graph-construction OR build time that selects code must be in key (flags, the baked element-texture width, …). Leaf presence and each leaf's type (texture type/format) are added automatically.
    • The factory must read leaf VALUES only through the graph (never bake a .value into code) except through key.
    • Material state the factory tail writes (blending, toneMapped) is per-material and must be re-applied by the caller — the factory runs against a scratch material, once per key.
    • Two texture leaves of one material must never hold the same texture. three merges texture nodes of one texture into one binding at build time, and a build three repeats for another render context sees the values the forwarding leaves last held: the two leaves would then share one binding for every material of the key. No wrapper does this today (each has at most an element/base-colour texture and a colormap).

    Kept out of tsl-helpers.ts (it needs three/webgpu; see live-texture-tsl.ts for the import-cone reason).

    SharedTSLGraph
    TSLLeafSet
    sharedTSLGraphKey
    forwardTSLLeaves
    applySharedTSLGraph
    sharedTSLGraphCount
    getSharedTSLGraph