Skip to content

Drei Catalog

A Three.js guide for coding agents. Also covers drei, react-three-drei, drei helpers, r3f helpers, CameraControls, ScrollControls, and 18 more.

Show all 24 aliases

drei, react-three-drei, drei helpers, r3f helpers, CameraControls, ScrollControls, useScroll, Stage lighting, MeshTransmissionMaterial, MeshPortalMaterial, useTexture, Html in canvas, troika text, Float wobble, Billboard, Instances instancing, Detailed LOD, PerformanceMonitor, AdaptiveDpr, RenderTexture, View multiple scenes, Hud overlay, Sky Stars Sparkles, GizmoHelper viewport gizmo

@react-three/drei is the helper library for react-three-fiber: cameras, controls, staging, materials, loaders, and performance tools as ready-made components and hooks. This doc is a map of the surface, organized by category, so you can find the right helper fast. Everything here is a JSX component or hook used inside <Canvas> unless noted.

Install: npm i @react-three/drei (requires three and @react-three/fiber).

Cameras

  • PerspectiveCamera: declarative perspective camera. makeDefault makes it the active render camera. Accepts children, which move with the camera (good for camera-attached lights or HUD meshes).
  • OrthographicCamera: same idea for orthographic projection. Use zoom rather than position distance to frame the scene.
  • CubeCamera: renders its children into a cube render target and passes the resulting envMap texture via render prop, for live reflections on a specific mesh.
<PerspectiveCamera makeDefault position={[0, 2, 6]} fov={45} />

Controls

  • OrbitControls: the default orbit/pan/zoom camera control. makeDefault registers it so other helpers (Bounds, Gizmos, CameraControls interop) can temporarily disable it. Props: enablePan, enableZoom, autoRotate, minDistance, maxPolarAngle, target.
  • CameraControls: wrapper around the camera-controls library. Imperative API (ref.current.setLookAt(...), dolly, rotate) with smooth damped transitions. Prefer it over OrbitControls when you need programmatic camera moves.
  • PresentationControls: rotates the scene (not the camera) with spring physics, clamped to configurable polar/azimuth ranges and snapping back on release. Ideal for product showcases.
  • ScrollControls + useScroll: creates an HTML scroll container over the canvas and exposes scroll state to the scene. <Scroll> children translate with scroll; <Scroll html> scrolls DOM content; everything else stays fixed but can read useScroll.
  • FaceControls: drives the camera from webcam face tracking (via FaceLandmarker). Experimental, for face-following parallax effects.
  • KeyboardControls: context provider mapping named actions to keys, read with the useKeyboardControls hook or selector. Standard choice for WASD player movement.
  • Also available: TransformControls (translate/rotate/scale gizmo on an object), PivotControls (compact pivot gizmo), DragControls, MotionPathControls (camera along a curve).
<ScrollControls pages={3} damping={0.1}>
  <AnimatedThing />          {/* fixed, reads useScroll */}
  <Scroll>{/* 3D content that scrolls */}</Scroll>
  <Scroll html>{/* DOM that scrolls */}</Scroll>
</ScrollControls>

function AnimatedThing() {
  const scroll = useScroll()
  useFrame(() => {
    const t = scroll.range(0, 1 / 3)      // 0 to 1 over the first third
    const bell = scroll.curve(1 / 3, 1 / 3) // 0-1-0 bell in the middle third
    const shown = scroll.visible(2 / 3, 1 / 3) // boolean
  })
}

Abstractions

  • Text: SDF text via troika-three-text. Crisp at any scale, supports fonts, maxWidth, anchorX/anchorY, outlines. The default for readable text in 3D.
  • Text3D: extruded geometry text from a typeface.json font. Use for chunky dimensional lettering; heavier than Text.
  • Html: renders real DOM elements positioned in 3D space. transform mode scales/rotates the DOM with the scene, occlude hides it behind geometry. The bridge for labels, tooltips, forms.
  • Float: makes children gently hover and rotate. Props: speed, rotationIntensity, floatIntensity, floatingRange.
  • Billboard: rotates children to always face the camera. Combine with Text for labels.
  • Clone: declaratively re-renders an existing object graph (for example a loaded GLTF scene) multiple times with per-clone overrides.
  • Decal: projects a texture decal onto a mesh surface (stickers, bullet holes, logos).
  • Edges: draws the geometry's edge lines above a threshold angle. Good for technical or toon looks.
  • Outlines: inverted-hull outline around a mesh, with thickness and color. Selection highlighting.
  • Svg: loads and renders an SVG file as shapes in the scene.
  • Gltf: component form of useGLTF, <Gltf src="/model.glb" /> drops a model straight into the scene.
  • Sampler: distributes instances across a mesh surface using surface sampling (scatter grass, rocks, particles on a terrain). Hook form: useSurfaceSampler.
  • Instances / Merged: see Performance below.
  • Also: Image (plane with cover-fit texture and zoom/grayscale shader), Trail (motion trail behind a moving object), Billboard, PositionalAudio, useAnimations (GLTF animation clips as actions), MarchingCubes, AsciiRenderer, Splat (gaussian splats), GradientTexture, ScreenSpace, ScreenSizer.
<Html position={[0, 1, 0]} center occlude>
  <button>DOM inside the scene</button>
</Html>

<Float speed={2} rotationIntensity={0.5} floatIntensity={1}>
  <Text fontSize={0.5} color="black" anchorX="center" anchorY="middle">
    hello world
  </Text>
</Float>

Staging

Lighting, environment, shadows, and layout helpers. This is where most "make it look good" wins come from.

  • Environment: image-based lighting from an HDRI. preset names (city, sunset, studio, dawn, forest, apartment, warehouse, park, lobby, night) or files for your own HDR. background shows it behind the scene; without it the HDRI only lights/reflects. Can contain Lightformer children to build a custom light studio.
  • Stage: one-stop presentation rig: centers the model, adds environment lighting, contact shadows, and zoom-to-fit. Fastest path to a decent product shot.
  • Lightformer: emissive shape (rect, ring, circle) used inside a custom <Environment> to place studio lights precisely.
  • Sky: physical atmosphere shader; sunPosition drives time of day.
  • Stars: instanced starfield background with radius, depth, count, factor, fade.
  • Sparkles: floating glitter particles, cheap ambient magic. count, scale, size, speed.
  • Cloud / Clouds: billboarded volumetric-looking cloud puffs.
  • ContactShadows: fake soft blob shadow plane under objects. No real light needed, cheap, updates each frame unless frames={1}.
  • AccumulativeShadows + RandomizedLight: accumulates many jittered shadow passes into one soft, realistic ground shadow. Static scenes only (or re-trigger with frames). RandomizedLight children provide the jittered light source.
  • SoftShadows: patches the shadow shader for percent-closer soft shadows (PCSS) on real lights. Global effect, configure size, samples, focus.
  • BakeShadows: renders the shadow map once and freezes it. Big perf win for static lights.
  • Backdrop: curved studio sweep (floor bending into wall) to receive shadows.
  • Bounds: calculates children's bounding box and fits/zooms the camera to it; useBounds refocuses on click.
  • Center: centers children on chosen axes after measuring them. Use around loaded models with arbitrary origins.
  • Resize: scales children so their largest bounding dimension is 1, normalizing wildly sized models.
  • Grid: shader-based infinite ground grid with cells, sections, and distance fade.
  • GizmoHelper: viewport orientation gizmo (usually <GizmoViewport /> cube/axes in a corner), clicks tween the camera.
  • Also: CameraShake, Caustics, SpotLight (volumetric cone), Shadow (single blob), BBAnchor (anchor children to a bounding-box corner).
<Environment preset="city" background blur={0.6} />

<AccumulativeShadows temporal frames={100} scale={10} position={[0, -0.5, 0]}>
  <RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
</AccumulativeShadows>

Materials

  • MeshReflectorMaterial: plane material with real-time blurred reflections plus depth-based roughness. The standard reflective floor.
  • MeshTransmissionMaterial: physical transmission on steroids: refraction, chromatic aberration, roughness blur, backside rendering. The glass material.
  • MeshDistortMaterial: standard material whose vertices wobble with a noise distortion. distort, speed.
  • MeshWobbleMaterial: simpler sine-based wobble. factor, speed.
  • MeshPortalMaterial: renders its children as a separate scene inside the mesh surface, a window into another world. Supports blend to walk through portals.
  • shaderMaterial: factory that builds a THREE.ShaderMaterial class from uniforms + vertex + fragment shaders, with auto-generated uniform setters as props. Register with extend and use as a JSX element.
  • PointMaterial: round, size-attenuated points material for particle clouds (pairs with <Points>).
  • Wireframe: shader wireframe over any geometry with stroke/fill controls, no extra geometry needed.
  • Also: MeshRefractionMaterial (diamond-style refraction from a CubeCamera envMap), MeshDiscardMaterial (renders nothing but keeps the mesh in the scene graph, useful under Outlines/shadows).
<mesh>
  <sphereGeometry args={[1, 64, 64]} />
  <MeshTransmissionMaterial
    transmission={1} thickness={0.5} roughness={0}
    chromaticAberration={0.03} anisotropicBlur={0.1} backside
  />
</mesh>

const WaveMaterial = shaderMaterial(
  { uTime: 0, uColor: new THREE.Color(0.2, 0.0, 0.1) },
  vertexShader,
  fragmentShader,
)
extend({ WaveMaterial })
// <waveMaterial uTime={clock.elapsedTime} uColor="hotpink" />

Loaders and asset hooks

All loader hooks suspend, so wrap consumers in <Suspense>. Most expose .preload(url) to start fetching early.

  • useGLTF: loads GLTF/GLB with Draco and meshopt decoding built in. Returns { scene, nodes, materials, animations }. useGLTF.preload(url) for eager loading.
  • useTexture: loads one texture, an array, or a named map object ({ map, normalMap, roughnessMap }) ready to spread onto a material.
  • useFBX: loads FBX files.
  • useKTX2: loads GPU-compressed KTX2 textures.
  • useProgress + Loader: useProgress reports global loading state (progress, active, item); <Loader /> is a ready-made DOM loading overlay outside the canvas built on it.
  • useMatcapTexture / useNormalTexture: fetches matcap or normal-map textures by id from public CDN libraries. Prototyping only, repos may move; self-host for production.
  • useVideoTexture: video element as a texture, autoplaying and suspense-ready. Also supports webcam streams via srcObject.
  • useCubeTexture: loads six images as a cube map ({ path, files }).
  • useEnvironment: loads an environment map (preset name or files) without applying it, so you can pass it to specific materials.
  • useFont: loads typeface.json fonts for Text3D, with .preload.
  • Also: useTrailTexture (pointer-trail fading texture), useSpriteLoader, useDetectGPU (GPU tier detection for quality switching).
const { scene, nodes, materials } = useGLTF('/models/robot.glb')
useGLTF.preload('/models/robot.glb')

const props = useTexture({ map: '/diffuse.jpg', normalMap: '/normal.jpg' })
<meshStandardMaterial {...props} />

Performance

  • Instances / Instance: declarative instanced rendering. One <Instances> parent holds geometry + material; each <Instance> child gets its own position/rotation/scale/color but the whole set is one draw call. Reach for this whenever the same mesh repeats more than a handful of times.
  • Merged: like Instances but instantiates from existing meshes (for example GLTF nodes), render-prop style.
  • Detailed: THREE.LOD as JSX: children are detail levels, distances picks which renders per camera distance.
  • Preload: compiles and uploads everything in the scene (or all) up front, preventing first-view jank when objects appear.
  • AdaptiveDpr: drops device pixel ratio while the camera moves (during "regress") and restores it after. Pair with <Canvas dpr={[1, 2]}>.
  • AdaptiveEvents: disables pointer events during regress for the same reason.
  • PerformanceMonitor: samples fps over time and fires onIncline / onDecline / onChange, letting you scale quality (dpr, effects, shadow resolution) to the device's actual headroom.
  • meshBounds: cheaper raycast function using bounding sphere only: <mesh raycast={meshBounds} />. Fine for rough hit areas on complex meshes.
  • Bvh: wraps children with three-mesh-bvh accelerated raycasting. The opposite trade: precise raycasts on heavy geometry, fast.
  • Also: Points / Point (declarative point clouds), Segments (instanced line segments), BakeShadows (listed under Staging, equally a perf tool).
<Instances limit={1000}>
  <boxGeometry />
  <meshStandardMaterial />
  {data.map((d, i) => (
    <Instance key={i} position={d.position} color={d.color} />
  ))}
</Instances>

Portals and scenes-in-scenes

  • RenderTexture: renders its children into a texture you can attach to any material map. A live TV screen inside the scene. RenderCubeTexture is the cube-map version.
  • View: renders multiple scenes into DOM-tracked viewport rectangles of a single shared canvas. The standard answer to "many small 3D views on one page" without paying for many canvases.
  • Hud: renders children as a heads-up overlay scene on top of the main scene with its own camera, cleared depth. For 3D UI that ignores the world camera.
  • Fisheye: wraps the scene in a cube-camera-based fisheye projection.
  • Mask: stencil-mask portal: meshes inside <Mask> define the stencil, useMask applies it to materials so content only shows through the mask shape.
  • MeshPortalMaterial: listed under Materials, belongs to this family conceptually.
<mesh>
  <planeGeometry />
  <meshStandardMaterial>
    <RenderTexture attach="map" anisotropy={16}>
      <PerspectiveCamera makeDefault position={[0, 0, 5]} />
      <color attach="background" args={['orange']} />
      <Text>inner scene</Text>
    </RenderTexture>
  </meshStandardMaterial>
</mesh>

Misc utilities

  • useCursor: sets the document cursor to pointer while an object is hovered: useCursor(hovered).
  • useHelper / Helper: attaches THREE helpers (BoxHelper, SpotLightHelper, camera helpers) to a ref for debugging.
  • Stats / StatsGl: fps meter overlays; StatsGl adds GPU timing.
  • useBoxProjectedEnv: box-projected environment mapping, makes an envMap reflect correctly inside a room-sized box (fake interior reflections).
  • CycleRaycast: cycles through all objects under the cursor on repeated clicks instead of always hitting the front-most one.
  • FaceLandmarker: provider loading the MediaPipe face landmark model, required by FaceControls and Facemesh.
  • Select / useSelect: click-selection groups, commonly paired with postprocessing outlines.
  • useIntersect: notifies when an object enters or leaves the view frustum.
  • useFBO: creates a managed WebGL render target for manual render passes.
  • useAspect: scales a plane to cover the viewport like CSS object-fit: cover.
  • useContextBridge: forwards React contexts across the Canvas renderer boundary (mostly superseded by fiber's automatic bridging, still useful for odd cases).
  • useDepthBuffer: shared depth texture for effects like drei's volumetric SpotLight.
  • Screenshots: drei ships no ScreenshotButton. Capture via gl.domElement.toDataURL() with <Canvas gl={{ preserveDrawingBuffer: true }}>, or render a frame right before capturing.

Choosing fast: common intents

IntentReach for
Orbit the camera around a modelOrbitControls
Cinematic scripted camera movesCameraControls, MotionPathControls
Scroll-driven storytelling pageScrollControls + useScroll
Product spins in place with springsPresentationControls
Good-looking lighting in one lineEnvironment preset, or Stage
Soft realistic ground shadowAccumulativeShadows, or ContactShadows (cheap)
Glass, liquid, gemsMeshTransmissionMaterial, MeshRefractionMaterial
Reflective floorMeshReflectorMaterial
Text in the sceneText (flat, crisp), Text3D (extruded)
DOM UI pinned to 3D pointsHtml
Load a modeluseGLTF or Gltf, wrap in Suspense, preload
Thousands of repeated meshesInstances, Sampler for surface scatter
Keep fps stable on weak devicesPerformanceMonitor + AdaptiveDpr
Multiple 3D panels on one pageView
Scene inside a screen or mirrorRenderTexture, CubeCamera
Debug lights and boundsuseHelper, Grid, GizmoHelper, Stats

Gotchas

  • Loader hooks suspend: forgetting <Suspense> around a useGLTF consumer throws to the nearest boundary or crashes the canvas.
  • makeDefault matters: controls and cameras cooperate through the default registration; helpers like Bounds and TransformControls disable the default control while dragging only if one is registered.
  • Environment lights without background set: the scene gets reflections and IBL but keeps your own background.
  • AccumulativeShadows assumes a static scene; moving objects smear until re-accumulated.
  • Many staging helpers (Center, Bounds, Resize) measure children on mount; remount or use their refs when swapping content.
  • Drei versions track fiber major versions; check the peer range when upgrading three or @react-three/fiber.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-three-js-guide({ topic: "drei-catalog" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems