@motion-script/core / Graphics3D
Class: Graphics3D
Defined in: render3d/graphics3d.ts:247
A renderer-agnostic, chainable 3D scene builder — the Graphics of 3D.
Records an ordered op list describing an object graph, plus scene-level
settings (camera, fog, background, environment, shadows, tone mapping, post
chain) held as fields and read back through query methods, exactly as
Graphics holds opacity/rotation/scale. Nothing here touches a renderer:
a built Graphics3D is handed to a Graphics via g.view3D(g3, state), and
the backend replays it.
const g3 = new Graphics3D() .perspective({ position: [0, 2, 6], lookAt: 0, fov: 45 }) .background("#0b0d12") .ambient({ intensity: 0.35 }) .directional({ intensity: 2.4, position: [4, 6, 3], castShadow: true }) .box({ width: 2, height: 2, depth: 2, color: "#e0533d", roughness: 0.3 }) .group({ position: [3, 0, 0] }, g => g.sphere({ radius: 0.8, color: "cyan" }) .torus({ radius: 1.4, tube: 0.08, unlit: true, color: "white" }));
── Angles are DEGREES ────────────────────────────────────────────────────────
Every angle here — Euler rotations, spot cone angles, sweep arcs, UV rotation —
is in degrees, matching motion-script's 2D rotation. The renderer converts.
── Animation ─────────────────────────────────────────────────────────────────
A Graphics3D is rebuilt from scratch every frame, so animation is just
reading signals while building:
const spin = createSignal(0); const pos = createSignal({ x: 0, y: 0, z: 0 }, lerpVector3); // in the builder: .box({ rotation: [0, spin(), 0], position: pos() }) yield* spin(360, 2, easeInOut());
Note the second argument to createSignal. A signal holding a non-number needs
an explicit lerp (lerpVector3, lerpEuler3, slerpQuaternion) or it will
snap at the end of the tween instead of interpolating — the same trap as an
object node attribute declared without a tween function.
── Reconciliation identity ───────────────────────────────────────────────────
The renderer caches one live 3D object per op and mutates it between frames
rather than rebuilding. Identity is the op's structural path: its group()
nesting plus its index within that group. That is stable for a builder emitting
the same ops in the same order every frame, which is the normal case. When a
builder emits ops conditionally, set key on the transform so identity
follows the logical object rather than the slot — otherwise inserting an op
renumbers every later slot and rebuilds the tail.
── What is cheap to animate ──────────────────────────────────────────────────
Transforms and most material/light values are in-place writes, so they cost
nothing per frame. Geometry parameters are not — three geometries are
immutable, so tweening .box({ width: signal() }) reallocates the mesh every
frame. Scale the object instead: .box({ width: 1, scale: [signal(), 1, 1] }).
The fields marked "structural" on MaterialCommon3D recompile the shader
program and should be set once, not tweened.
Constructors
Constructor
new Graphics3D():
Graphics3D
Returns
Graphics3D
Methods
ambient()
ambient(
options?):this
Defined in: render3d/graphics3d.ts:397
Parameters
options?
ParamsOf<AmbientLight3D> & Transform3D
Returns
this
assertBalanced()
assertBalanced():
void
Defined in: render3d/graphics3d.ts:657
Throw if push and pop are unbalanced. Called once by the consumer before
replay, so a mismatched group fails loudly at the source rather than
silently reparenting everything after it.
Returns
void
background()
background(
background):this
Defined in: render3d/graphics3d.ts:578
Set what fills the uncovered pixels. Defaults to transparent, so the 2D scene behind the node shows through. A bare Color is a solid clear.
Parameters
background
Background3D | null
Returns
this
backgroundDescriptor()
backgroundDescriptor():
Background3D|null
Defined in: render3d/graphics3d.ts:628
Returns
Background3D | null
box()
box(
options?):this
Defined in: render3d/graphics3d.ts:330
Parameters
options?
ParamsOf<BoxGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
camera()
camera(
camera):this
Defined in: render3d/graphics3d.ts:547
Set the camera from an explicit descriptor.
Parameters
camera
Returns
this
cameraDescriptor()
cameraDescriptor():
Camera3D|null
Defined in: render3d/graphics3d.ts:622
The camera, or null to let the renderer supply a default framing.
Returns
Camera3D | null
capsule()
capsule(
options?):this
Defined in: render3d/graphics3d.ts:357
Parameters
options?
ParamsOf<CapsuleGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
circle()
circle(
options?):this
Defined in: render3d/graphics3d.ts:351
Parameters
options?
ParamsOf<CircleGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
cone()
cone(
options?):this
Defined in: render3d/graphics3d.ts:342
Parameters
options?
ParamsOf<ConeGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
cylinder()
cylinder(
options?):this
Defined in: render3d/graphics3d.ts:339
Parameters
options?
ParamsOf<CylinderGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
directional()
directional(
options?):this
Defined in: render3d/graphics3d.ts:403
Parameters
options?
ParamsOf<DirectionalLight3D> & Transform3D
Returns
this
environment()
environment(
environment):this
Defined in: render3d/graphics3d.ts:588
Light the scene with an environment image. Needed for metals to read as
metal — without something to reflect, a metallic surface renders black.
{ type: "room" } needs no asset and is the quickest fix.
Parameters
environment
Environment3D | null
Returns
this
environmentDescriptor()
environmentDescriptor():
Environment3D|null
Defined in: render3d/graphics3d.ts:631
Returns
Environment3D | null
extrude()
extrude(
options):this
Defined in: render3d/graphics3d.ts:363
Parameters
options
ParamsOf<ExtrudeGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
fog()
fog(
fog):this
Defined in: render3d/graphics3d.ts:563
Set depth fog. A bare Color is sugar for linear fog in that colour.
Parameters
fog
Returns
this
fogDescriptor()
fogDescriptor():
Fog3D|null
Defined in: render3d/graphics3d.ts:625
Returns
Fog3D | null
group()
Call Signature
group(
transform,build):this
Defined in: render3d/graphics3d.ts:286
Record a nested group — push, run build, pop. The preferred form: the
nesting is visible in the source and can't be left open.
g.group({ position: [0, 2, 0] }, g => g.sphere({ radius: 0.5 }))
Parameters
transform
build
(g) => unknown
Returns
this
Call Signature
group(
build):this
Defined in: render3d/graphics3d.ts:287
Record a nested group — push, run build, pop. The preferred form: the
nesting is visible in the source and can't be left open.
g.group({ position: [0, 2, 0] }, g => g.sphere({ radius: 0.5 }))
Parameters
build
(g) => unknown
Returns
this
hemisphere()
hemisphere(
options?):this
Defined in: render3d/graphics3d.ts:400
Parameters
options?
ParamsOf<HemisphereLight3D> & Transform3D
Returns
this
instances()
instances(
geometry,material,instances,options?):this
Defined in: render3d/graphics3d.ts:425
Record many copies of one geometry in a single draw call. The way to put
thousands of objects on screen — a plain mesh per copy would not keep up.
g.instances(Geo.box({ width: 0.2 }), Mat.standard({ color: "cyan" }), positions.map(p => ({ position: p })))
Parameters
geometry
material
instances
readonly Transform3D[]
options?
colors?
readonly Color[]
transform?
Returns
this
isEmpty()
isEmpty():
boolean
Defined in: render3d/graphics3d.ts:648
True when nothing would be drawn — no mesh, light or other drawable. The node skips the whole 3D pass (and the WebGL context entirely) in that case.
Returns
boolean
lathe()
lathe(
options):this
Defined in: render3d/graphics3d.ts:366
Parameters
options
ParamsOf<LatheGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
light()
light(
light,transform?):this
Defined in: render3d/graphics3d.ts:376
Record a light from an explicit descriptor.
Parameters
light
transform?
Returns
this
line()
line(
options):this
Defined in: render3d/graphics3d.ts:464
Record a line. Give it either explicit points or a geometry (typically
Geo.edges(...) for a wireframe outline).
mode — "strip" (default) connects the points in order, "segments"
treats them as disjoint pairs, "loop" closes back to the start.
Parameters
options
object & Transform3D
Returns
this
mesh()
mesh(
geometry,material?,transform?):this
Defined in: render3d/graphics3d.ts:306
Record a mesh from an explicit geometry and material. The geometry sugar methods below all funnel here.
Parameters
geometry
material?
Material3D | readonly Material3D[]
transform?
Returns
this
model()
model(
options):this
Defined in: render3d/graphics3d.ts:522
Record a loaded model (glTF/GLB, OBJ).
Baked animation is sampled by explicit time, never advanced by a delta, so
a model stays frame-identical under scrubbing.
Parameters
options
object & Transform3D
Returns
this
ops()
ops(): readonly
Graphics3DOp[]
Defined in: render3d/graphics3d.ts:617
The recorded ops, in order. Replayed by the renderer.
Returns
readonly Graphics3DOp[]
orthographic()
orthographic(
options?):this
Defined in: render3d/graphics3d.ts:558
Set an orthographic camera — parallel projection, for isometric looks.
Parameters
options?
ParamsOf<OrthographicCamera3D>
Returns
this
perspective()
perspective(
options?):this
Defined in: render3d/graphics3d.ts:553
Set a perspective camera. The usual choice.
Parameters
options?
ParamsOf<PerspectiveCamera3D>
Returns
this
plane()
plane(
options?):this
Defined in: render3d/graphics3d.ts:336
Parameters
options?
ParamsOf<PlaneGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
point()
point(
options?):this
Defined in: render3d/graphics3d.ts:406
Parameters
options?
ParamsOf<PointLight3D> & Transform3D
Returns
this
points()
points(
geometry,material?,transform?):this
Defined in: render3d/graphics3d.ts:443
Record a point cloud — one sprite-like dot per vertex of geometry.
Parameters
geometry
material?
transform?
Returns
this
polyhedron()
polyhedron(
options):this
Defined in: render3d/graphics3d.ts:360
Parameters
options
ParamsOf<PolyhedronGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
pop()
pop():
this
Defined in: render3d/graphics3d.ts:274
Close the group opened by the matching push.
Returns
this
post()
post(
effects):this
Defined in: render3d/graphics3d.ts:608
Append post-processing passes, applied in order after the scene renders.
Parameters
effects
PostEffect3D | readonly PostEffect3D[]
Returns
this
postEffects()
postEffects(): readonly
PostEffect3D[]
Defined in: render3d/graphics3d.ts:640
Returns
readonly PostEffect3D[]
push()
push(
transform?):this
Defined in: render3d/graphics3d.ts:267
Open a child group. Everything recorded until the matching pop is
nested inside it and inherits transform.
Prefer the callback form of group, which cannot be left unbalanced.
Parameters
transform?
Returns
this
rectArea()
rectArea(
options?):this
Defined in: render3d/graphics3d.ts:412
Parameters
options?
ParamsOf<RectAreaLight3D> & Transform3D
Returns
this
ring()
ring(
options?):this
Defined in: render3d/graphics3d.ts:354
Parameters
options?
ParamsOf<RingGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
shadows()
shadows(
settings?):this
Defined in: render3d/graphics3d.ts:594
Enable and configure shadow mapping. true is shorthand for { enabled: true }.
Parameters
settings?
boolean | ShadowSettings3D
Returns
this
shadowSettings()
shadowSettings():
ShadowSettings3D|null
Defined in: render3d/graphics3d.ts:634
Returns
ShadowSettings3D | null
sphere()
sphere(
options?):this
Defined in: render3d/graphics3d.ts:333
Parameters
options?
ParamsOf<SphereGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
spot()
spot(
options?):this
Defined in: render3d/graphics3d.ts:409
Parameters
options?
ParamsOf<SpotLight3D> & Transform3D
Returns
this
sprite()
sprite(
options):this
Defined in: render3d/graphics3d.ts:500
Record a camera-facing textured quad.
Parameters
options
object & Transform3D
Returns
this
tone()
tone(
settings):this
Defined in: render3d/graphics3d.ts:602
Set tone mapping and exposure.
Parameters
settings
Returns
this
toneSettings()
toneSettings():
ToneMapping3D|null
Defined in: render3d/graphics3d.ts:637
Returns
ToneMapping3D | null
torus()
torus(
options?):this
Defined in: render3d/graphics3d.ts:345
Parameters
options?
ParamsOf<TorusGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
torusKnot()
torusKnot(
options?):this
Defined in: render3d/graphics3d.ts:348
Parameters
options?
ParamsOf<TorusKnotGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this
tube()
tube(
options):this
Defined in: render3d/graphics3d.ts:369
Parameters
options
ParamsOf<TubeGeometry3D> & Transform3D & MaterialShorthand3D
Returns
this