Semantic Clarifications
This page documents behavior that is easy to misread when jumping between Hydra-style signal chains and Three.js scene APIs.
Rotation units
rotate(angle, speed)in the GLSL coord chain uses degrees forangle(legacy behavior).rotateDeg(angle, speed)is an explicit degrees version (same behavior asrotate).rotateRad(angle, speed)is an explicit radians version (no degree conversion).rotateandrotateDegconvertangleto radians internally before applying rotation.speedis added as a time term in shader space (ang + speed * time) and is treated as radians-per-time-unit.- Three.js object rotations (for example
mesh.rotation.x += ...) use radians. - Calling
rotate(...)emits a one-time compatibility warning that points torotateDeg(...)/rotateRad(...).
Rule of thumb: use rotateDeg(...) for degree-based sketches, rotateRad(...) when matching Three.js radians, and reserve rotate(...) for legacy compatibility.
.tex() vs .texMat()
.tex(output?, options?)
- Ensures the current chain is compiled to an output. - Returns a THREE.Texture rendered from that output. - Use when you need a texture value to pass into materials, samplers, or additional texture utilities. - .texture(...) is an alias of .tex(...).
.texMat(output?, options?)
- Calls .tex(...) internally and returns a material with that texture set as map. - Material type follows current material mode: - .phong() -> MeshPhongMaterial - .lambert() -> MeshLambertMaterial - otherwise -> MeshBasicMaterial - Use when you want a direct texture-to-material bridge.
autoClear levels and precedence
autoClear can be configured at multiple levels:
- output level:
o0.autoClear(...) - pass/source level:
stage().clear(...),osc(...).clear(...)
Behavior:
- output-level
autoClearruns before pass execution for that output. - pass-level
autoClearapplies on each compiled pass. amount >= 1performs full clear.0 < amount < 1inserts fade accumulation behavior.- If both output and pass
autoClearare set, both effects are applied in sequence.
Render-target routing in .render(...)
render(...)/out(...) support both signatures:
- positional:
.render(output, options) - object:
.render({ to, target, css, fx, ... })
Mappings:
to-> outputtarget->renderTargetcss->cssRenderer
When renderTarget (or target in object form) is passed, the runtime assigns it to the terminal pass for the compiled chain:
- no FX chain: render target is applied to the scene/material pass.
- with FX chain: render target is moved to the final FX pass.
This preserves intermediate pass wiring while guaranteeing the final output target receives the result.
Public vs internal scene helpers
- Public instancing path:
stage().mesh(geometry, material, { instanced: count }) - Underscore-prefixed helpers (for example
_mesh) are internal and not part of the stable public API. - Calling underscore scene helpers directly emits a one-time compatibility warning with the public replacement.
Use public scene composition methods in docs, recipes, and production sketches.
Named reuse semantics
nameis descriptive by default; it does not imply reuse.- Use
reuse: truewhen you intentionally wantscene/group/mesh/...calls with the samenameto resolve an existing object. - Unkeyed calls in continuous mode receive source-based auto IDs to reduce reorder drift.
- For strongest live-coding identity guarantees across larger refactors, prefer explicit
key.
Global vs non-global runtime semantics
makeGlobal: trueinstalls helpers likeosc,stage, module namespaces, and math helpers into global scope for live-coding ergonomics.makeGlobal: falsekeeps APIs undertriode.synthfor host-safe embedding and multi-instance control.- Current constructor default is
makeGlobal: false; opt into globals explicitly with constructor config ortriode.synth.liveGlobals(true). legacy: truerestores compatibility constructor defaults (makeGlobal: true,liveMode: "restart") and suppresses compatibility warnings.
Prefer non-global mode for application integration, editor embedding, and test harnesses.