Upload the decoded texture into the material, once the data has arrived.
Separate from node creation because a texture is DATA: createEmptyMeshNode runs
before any fetch, so the material is built with a blank placeholder and the real
image is installed here, on the commit that carries it.
What is decided at CREATION and never here is the shader VARIANT — the define and
the uv attribute both key off attrs.has_texture, a per-node constant. That
split is the point: the variant is fixed from birth (WebGPU bakes the attribute
set into the pipeline at first draw), and only the texture's IDENTITY changes,
which on GLSL is a plain uniform write with no recompile.
Idempotent, so the steady state after the first commit costs nothing: the setter
compares the incoming texture against the bound one and only rebuilds the TSL
graph when they differ. That comparison is load-bearing on the TSL backend, where
texture() captures its Texture at construction — a slice move that re-installed
the same image would otherwise rebuild the graph on every frame of a scrub.
Upload the decoded texture into the material, once the data has arrived.
Separate from node creation because a texture is DATA:
createEmptyMeshNoderuns before any fetch, so the material is built with a blank placeholder and the real image is installed here, on the commit that carries it.What is decided at CREATION and never here is the shader VARIANT — the define and the
uvattribute both key offattrs.has_texture, a per-node constant. That split is the point: the variant is fixed from birth (WebGPU bakes the attribute set into the pipeline at first draw), and only the texture's IDENTITY changes, which on GLSL is a plain uniform write with no recompile.Idempotent, so the steady state after the first commit costs nothing: the setter compares the incoming texture against the bound one and only rebuilds the TSL graph when they differ. That comparison is load-bearing on the TSL backend, where
texture()captures its Texture at construction — a slice move that re-installed the same image would otherwise rebuild the graph on every frame of a scrub.