@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.
makeDefaultmakes 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
zoomrather 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.
makeDefaultregisters 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 readuseScroll. - 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
useKeyboardControlshook 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.
transformmode scales/rotates the DOM with the scene,occludehides 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
thicknessandcolor. 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.
presetnames (city, sunset, studio, dawn, forest, apartment, warehouse, park, lobby, night) orfilesfor your own HDR.backgroundshows 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;
sunPositiondrives 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;
useBoundsrefocuses 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
blendto 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
extendand 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:
useProgressreports 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,
distancespicks 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.
RenderCubeTextureis 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,useMaskapplies 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
| Intent | Reach for |
|---|---|
| Orbit the camera around a model | OrbitControls |
| Cinematic scripted camera moves | CameraControls, MotionPathControls |
| Scroll-driven storytelling page | ScrollControls + useScroll |
| Product spins in place with springs | PresentationControls |
| Good-looking lighting in one line | Environment preset, or Stage |
| Soft realistic ground shadow | AccumulativeShadows, or ContactShadows (cheap) |
| Glass, liquid, gems | MeshTransmissionMaterial, MeshRefractionMaterial |
| Reflective floor | MeshReflectorMaterial |
| Text in the scene | Text (flat, crisp), Text3D (extruded) |
| DOM UI pinned to 3D points | Html |
| Load a model | useGLTF or Gltf, wrap in Suspense, preload |
| Thousands of repeated meshes | Instances, Sampler for surface scatter |
| Keep fps stable on weak devices | PerformanceMonitor + AdaptiveDpr |
| Multiple 3D panels on one page | View |
| Scene inside a screen or mirror | RenderTexture, CubeCamera |
| Debug lights and bounds | useHelper, Grid, GizmoHelper, Stats |
Gotchas
- Loader hooks suspend: forgetting
<Suspense>around auseGLTFconsumer throws to the nearest boundary or crashes the canvas. makeDefaultmatters: 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
backgroundset: 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.