MotionScript

@motion-script/core


@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

Camera3D

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

Color | Fog3D | null

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

Transform3D

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

Geometry3D

material

Material3D

instances

readonly Transform3D[]

options?
colors?

readonly Color[]

transform?

Transform3D

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

Light3D

transform?

Transform3D

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

Geometry3D

material?

Material3D | readonly Material3D[]

transform?

Transform3D

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

Geometry3D

material?

Material3D

transform?

Transform3D

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?

Transform3D

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

ToneMapping3D

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