wgpu3d API reference
Everything the library exports, grouped by job. Distances are in metres, angles in radians unless a name says degrees, and colours are hex strings like "#ff8a3d" or linear [r, g, b] arrays.
Conventions
- Y is up. An object with
yaw = 0faces −Z, and positive yaw turns it to the left, as in City Drive. - Rotation is applied as roll (around Z), then pitch (around X), then yaw (around Y). Positive pitch lifts an object's nose.
- A behavior is either a function
(object, context) => {}or an object with anupdate(object, context)method. The context holdsapp,scene,input,camera,renderer,deltaSecondsandtimeSeconds.
createApp and App
await createApp({ canvas, environment, camera, renderer, input })
Creates the WebGPU device, a scene, a camera and keyboard and touch input for canvas, and returns an App. It throws if WebGPU is unavailable, so check isSupported() first if you want a fallback.
| Option | Default | Meaning |
|---|---|---|
environment | "noon" | A preset name or an object; see environment. |
camera | {} | Options for new Camera(). |
renderer.pixelRatio | device ratio, at most 2 | Lower it to trade sharpness for speed. |
renderer.sampleCount | 4 | Antialiasing samples: 1 or 4. |
renderer.shadows | true | Turns sun shadows on or off. |
renderer.shadowExtent | 40 | Half the width, in metres, of the shadowed area around the camera's target. |
renderer.shadowMapSize | 2048 | Shadow texture size in pixels. |
input.bindings | DEFAULT_BINDINGS | Map of action names to KeyboardEvent.code values. |
input.touchStick | true | Drag on the canvas to move, tap to jump. |
| App member | What it does |
|---|---|
app.scene, app.camera, app.input, app.renderer | The parts createApp made. |
app.add(...objects) | Adds objects to the scene. |
app.onUpdate(callback) | Runs callback(context) every frame after behaviors. Returns a function that removes it. |
app.follow(object, options) | Puts a ChaseCamera behind the object. |
app.orbit(options) | Puts an OrbitCamera on the canvas. With subject, it follows that object. |
app.start(), app.stop() | Starts and stops the frame loop. Frames are skipped while the canvas is scrolled out of view. |
app.step(seconds) | Advances and draws one frame by hand, for tests or recording. |
app.timeSeconds, app.framesPerSecond | Clock and smoothed frame rate. |
app.dispose() | Stops the loop and releases the GPU device and listeners. |
Scene and SceneObject
new SceneObject({ name, mesh, position, yaw, pitch, roll, scale, tint, glow, visible, castsShadow, collider, isSolid, tags })
Anything in the world. An object without a mesh is an invisible group that moves its children. scale may be a number or [x, y, z], tint multiplies the mesh colours and glow adds light. With a collider, the object blocks controllers unless isSolid is false.
| Member | What it does |
|---|---|
add(...children), remove(child), removeFromParent() | Build the hierarchy. Children move with their parent. |
addBehavior(behavior) | Runs every frame. Returns a function that removes it. |
forward(), worldPosition() | Facing direction from yaw, and position after parents are applied. |
traverse(visit) | Calls visit on the object and every descendant. |
parts | Named child objects that prefabs and controllers share, such as a car's body and wheels. |
speed | Set by controllers; the chase camera reads it. |
new Scene({ environment })
The root object. setEnvironment(preset) changes the lighting, find(name) and withTag(tag) look objects up, touching(object, { tag, radius, height }) lists objects whose colliders overlap a circle around another object, and solidColliders(except) returns the blocking shapes controllers use.
MeshBuilder, Mesh and material
material(color, { gloss, glow })
A surface. gloss from 0 to 1 adds highlights and sky reflections; glow makes the surface emit its colour and stay visible through fog. Anywhere a material is expected you can also pass just a colour.
new MeshBuilder()
Collects triangles. Every method returns the builder, so calls chain, and toMesh() finishes it. Shapes take center, optional yaw, pitch and roll, and a material.
| Method | Notes |
|---|---|
box({ size: [x, y, z] }) | Faces are shaded slightly differently, top lightest, so boxes read well without textures. |
cylinder({ radius, radiusTop, height, sides, axis }) | axis is "y", "x" or "z". |
cone({ radius, height, sides }) | A cylinder with no top. |
sphere({ radius, radii, sides, rings, isSmooth }) | radii makes an ellipsoid; isSmooth: false gives a faceted look. |
plane({ size: [w, d], tiles, alternateMaterial }) | A flat checkerboard on the XZ plane. |
loft(sections) | Joins rings of points into a closed tube. The City Drive car body is a loft. |
triangle(a, b, c, material), quad(a, b, c, d, material) | Raw faces; winding does not matter. |
withTransform({ position, yaw, pitch, roll, scale }, build) | Everything added inside build(builder) is moved by the transform. |
new Mesh(vertices) wraps a Float32Array of 12 floats per vertex (position, normal, colour, gloss, glow, occlusion). Call mesh.replaceVertices(array) to change a mesh after it is drawn; the GPU copy updates next frame.
Camera, ChaseCamera and OrbitCamera
new Camera({ position, target, up, fieldOfView, near, far })
fieldOfView is vertical, in degrees. yaw() returns the direction the camera faces, which the character controller uses to move relative to the view.
new ChaseCamera(camera, subject, { distance, height, lookAhead, lookHeight, stiffness, speedFieldOfView })
Trails behind the subject's yaw with springy smoothing. speedFieldOfView widens the view by that many degrees at speed.
new OrbitCamera(camera, element, { target, subject, distance, yaw, pitch, minDistance, maxDistance, autoRotateSpeed, ignoreTouch })
Drag to rotate, scroll or pinch to zoom. With subject it orbits a moving object.
Input
The app's input listens on the canvas, so keys only count while the canvas has focus and the page does not scroll when you press the arrow keys.
| Member | What it does |
|---|---|
isDown(action) | True while a key for the action is held. |
wasPressed(action) | True only in the frame the action started, including touch taps for jump and action. |
axis(negative, positive) | −1, 0 or 1 from two actions. |
moveVector() | { x, y } from the movement keys and the touch stick, length at most 1. |
press(action) | Triggers an action from your own buttons. |
The default actions are forward, backward, left, right (WASD and arrows), jump and brake (Space), run (Shift), action (E, Enter) and camera (C).
Controllers and behaviors
new VehicleController({ maxSpeed, maxReverseSpeed, acceleration, braking, coastDrag, handbrakeDrag, steering, collisionRadius, bounce, wheelRadius, groundHeight, bounds })
Arcade driving from City Drive: throttle that fades near top speed, braking, coasting drag, a handbrake, steering that softens with speed, a bounce on head-on hits and scraping along walls. It tilts parts.body under acceleration and in turns, spins parts.wheels and steers the ones tagged "front-wheel". bounds is { minX, maxX, minZ, maxZ }, and groundHeight(x, z) lets the vehicle follow terrain.
new CharacterController({ walkSpeed, runSpeed, acceleration, jumpSpeed, gravity, radius, height, stepHeight, turnRate, groundHeight })
Moves relative to the camera, runs with Shift, jumps, lands on top of solid boxes, slides along walls and swings parts.leftLeg, rightLeg, leftArm and rightArm while walking. isGrounded and jumpCount, the number of jumps so far, are readable.
spin(radiansPerSecond), bob({ height, speed })
Small behaviors for pickups and decoration.
Collisions
boxCollider([width, height, depth]) and sphereCollider(radius) describe shapes centred on the object; add offset: [x, y, z] to move them. Boxes turn with the object's yaw. worldCollider(object), circleOverlapsCollider(x, z, radius, collider) and resolveCircleAgainstColliders(position, radius, colliders, { bottom, top }) are the building blocks the controllers use, if you write your own.
Prefabs
| Function | Main options |
|---|---|
createCar() | paint. Has parts.body, parts.wheels and brake lights for VehicleController. |
createCharacter() | shirt, pants, skin. Has limb parts for CharacterController. |
createTree() | seed, height, kind ("round" or "pine"), foliage, trunk, position. |
createBuilding() | seed, width, depth, height, color, litShare (share of glowing windows), position, yaw. |
createGround() | size, tiles, color, alternateColor. |
createRoad() | length, width, yaw, height (raise crossing roads so they sit on top). |
createCrate(), createCoin(), createLampPost() | position, plus size, color or glow. Coins are tagged "coin" and do not block movement. |
Environment presets
Pass a name, "morning", "noon", "sunset", "dusk" or "night", or an object that overrides a preset: { preset: "noon", sunDirection: [1, 0.5, 0], fogEnd: 500 }. The fields are skyTop, skyHorizon, groundColor, sunColor, sunDirection (pointing toward the sun), sunIntensity, ambientIntensity, fogStart, fogEnd and exposure. Shadows switch off when the sun is near or below the horizon.
Math helpers
clamp, lerp, damp(current, target, rate, seconds) for frame-rate-independent smoothing, dampAngle, wrapAngle, degreesToRadians, forwardFromYaw, and createRandom(seed), a seeded generator with range(min, max), integer(min, max) and pick(items).