Render quality

Lighting

  • Image-based lighting must be configured; AmbientLight alone is not acceptable. The recommended setup is the built-in procedural interior — no asset files, no network request, nothing for CSP to block:
    const pmrem = new THREE.PMREMGenerator(renderer)
    const envRT = pmrem.fromScene(new RoomEnvironment()) // keep envRT — it is disposed on unmount, see Rebuild on change
    scene.environment = envRT.texture
    
  • Keep the environment dim (scene.environmentIntensity ≈ 0.4 as a reference; a lower envMapIntensity on dark parts) to hold contrast, and add one soft directional light so the lighting has a direction.

Tone mapping

ACES tone mapping must be enabled:

renderer.toneMapping = THREE.ACESFilmicToneMapping

It makes a visible difference to how MeshStandardMaterial / MeshPhysicalMaterial read.

Materials

  • You should generate a procedural noise texture on a canvas and use it as both map and bumpMap — a cheap way to get a physical material read. Build it once and reuse it across rebuilds; Rebuild on change covers when to dispose it.
  • ExtrudeGeometry UVs are world coordinates in mm, so texture.repeat must be derived from physical size: pick how many mm one tile of the texture should span, and set repeat = 1 / tile_mm (a 45mm wood grain gives 1/45). Hardcode a repeat count instead and the grain changes size whenever the part does.
  • The procedural material SVG used by the 2D canvas can be rendered to a canvas and reused in 3D as a CanvasTexture, keeping 2D and 3D materials consistent. For the top face — assuming the model is centred on the origin, so world coordinates run from −R to +R — repeat = 1/(2R) and offset = 0.5 map that span onto 0–1.
  • You should split materials per face group, [faceMat, sideMat] (group 0 top and bottom, group 1 sides), with the sides a shade darker to read as solid.

HDRI environment (optional)

For a more convincing environment, ship a small CC0-licensed 1k .hdr (around 1.5MB): run it through PMREM for scene.environment, use the raw equirect texture as scene.background with a moderate backgroundBlurriness, and fall back to RoomEnvironment as an instant placeholder while it loads.

Two things to watch for:

  • A downward-tilted camera looks at the panorama's zenith or ground — the flattest part of it — and the background collapses into one blurred colour. Rotate the horizon behind the subject with backgroundRotation and environmentRotation, and start the camera at a shallower angle.
  • Keep the background clearly darker than the subject, so the model's silhouette and its holes stay readable.
Esc
Search all docs · to navigate · to open