Shared scene

Two HTML anchors. Two objects. One scene and camera. This example uses only addScene; each world.track() positions an object in the same 3D world.

Scroll or resize. The purple cube is clipped to its dashed square. The orange cube is unclipped and can extend beyond its square.

Register one world

Start with an initialized alpha: truerenderer. The positioned container starts at the document’s top-left, as in the other demos. Both groups must be direct children of the scene.

import { ThreeDOM } from "portalgl/three"
import { ClippingGroup, Group, PerspectiveCamera, Scene } from "three/webgpu"

const dom = new ThreeDOM({ renderer, container })
const scene = new Scene()
const camera = new PerspectiveCamera(50, 1, 0.1, 100)
camera.position.z = 5

// purpleMesh and orangeMesh are your meshes; add lighting to the scene.
const purple = new ClippingGroup()
const orange = new Group()
purple.add(purpleMesh)
orange.add(orangeMesh)
scene.add(purple, orange)

const world = dom.addScene({ scene, camera })
world.track(purpleElement, purple, { fill: 0.85, clip: true })
world.track(orangeElement, orange, { fill: 0.85, clip: false })

renderer.setAnimationLoop(time => {
  dom.advance(time)
  // Animate child meshes; tracking owns the groups' position and scale.
  dom.render()
})

// On teardown:
renderer.setAnimationLoop(null)
dom.destroy() // Releases the shared scene and its bindings.
// Dispose your geometries, materials, and renderer too.

Shared scenes use a shared canvas on both WebGPU and WebGL2. This scene skips rendering when both cubes are outside the viewport. The purple cube uses a ClippingGroup with clipping enabled; the orange cube uses a Group with clip: false.

Scene and views

Combine addScene and addView on one renderer, with shared objects above independent views.

Just track it

Track an HTML element with a Three.js view using React.

Preparing 3D views…