Shared TSL helper functions used by the geometry-material factories.
sanitizeNonNegative reproduces the GLSL function of the same name —
guard against NaN/Inf produced by upstream data loaders and fall back to a
sensible scalar default. It is a pure TSL builder call, so the same body
works under any NodeBuilder (WebGL2 or WebGPU). (glsl-lib.ts also defines
a sanitizePositive; no TSL shader calls it, so there is no TSL mirror.)
proxyIUniform bridges the THREE IUniform-shaped public API
(material.uniforms.uX.value = Y) directly onto a TSL
UniformNode.value getter/setter. It replaces the old
uniform(value).onUpdate(() => iuniform.value, 'render') bridge,
which read the host IUniform's value into the node before every
render. That callback was structural noise — the IUniform record
could be the node, just dressed in the IUniform shape. The proxy
forwards reads and writes directly to the node so there is no
per-frame callback overhead and no two-source-of-truth class.
Shared TSL helper functions used by the geometry-material factories.
sanitizeNonNegativereproduces the GLSL function of the same name — guard against NaN/Inf produced by upstream data loaders and fall back to a sensible scalar default. It is a pure TSL builder call, so the same body works under any NodeBuilder (WebGL2 or WebGPU). (glsl-lib.tsalso defines asanitizePositive; no TSL shader calls it, so there is no TSL mirror.)proxyIUniformbridges the THREEIUniform-shaped public API (material.uniforms.uX.value = Y) directly onto a TSLUniformNode.valuegetter/setter. It replaces the olduniform(value).onUpdate(() => iuniform.value, 'render')bridge, which read the host IUniform's value into the node before every render. That callback was structural noise — the IUniform record could be the node, just dressed in the IUniform shape. The proxy forwards reads and writes directly to the node so there is no per-frame callback overhead and no two-source-of-truth class.