Three.js has transformed how developers create 3D content for the web, but integrating it with modern React applications has traditionally been complex. Enter React Three Fiber – a React renderer for Three.js that brings a declarative, component-based approach to 3D graphics development.
Table of Contents
- Introduction to React Three Fiber
- Interactive Examples
- Getting Started with React Three Fiber
- Creating Basic 3D Elements
- Animations and Interactions
- Lighting and Materials
- Camera Controls
- Performance Optimization
- Advanced Techniques
- Conclusion
Introduction to React Three Fiber
React Three Fiber (R3F) is a React renderer for Three.js that allows you to create 3D scenes using React's component-based architecture. It bridges the gap between React's declarative programming model and Three.js's imperative 3D graphics API.
Why Use React Three Fiber?
- Declarative Syntax: Define 3D scenes using JSX for better readability and maintainability
- React Integration: Seamlessly blend 3D elements with your React application
- Reconciliation: Automatic handling of scene graph updates
- Hooks: Use React hooks for animations, interactions, and state management
- Ecosystem: Access to a growing collection of tools and extensions like drei
Example Scene
Inspired by Pink Floyd's "Wish You Were Here", I "vibe coded" a simple Fishbowl scene for this article. No imported models, the entire scene was generated with code using React Fiber.
View Source on CodeSandbox
How I wish, how I wish you were here,
We're just two lost souls swimming in a fishbowl, year after year.
Runnin' over the same old ground, what have we found?
the same old fears, wish you were here …
Interactive Scene Example
This example shows two simple 3D shapes that rotate continuously. Click on a shape to increase its size, or click and drag to control the camera.
Core Concepts
React Three Fiber translates React components into Three.js objects:
// React Three Fiber component
<mesh position={[0, 0, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="hotpink" />
</mesh>;
// Equivalent Three.js code
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 'hotpink' });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
Getting Started with React Three Fiber
Installation
To get started with React Three Fiber, you'll need to install the necessary packages:
npm install three @react-three/fiber @react-three/drei
Basic Setup
Creating a 3D scene requires a canvas element where Three.js can render:
import { Canvas } from '@react-three/fiber';
function App() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<mesh>
<boxGeometry />
<meshStandardMaterial color="orange" />
</mesh>
</Canvas>
);
}
The Canvas
component sets up the Three.js renderer, scene, and camera, providing a foundation for your 3D content.
Creating Basic 3D Elements
Primitives
React Three Fiber provides primitives that map directly to Three.js objects:
// Basic shapes
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="red" />
</mesh>
<mesh position={[2, 0, 0]}>
<sphereGeometry args={[0.5, 32, 32]} />
<meshStandardMaterial color="blue" />
</mesh>
<mesh position={[-2, 0, 0]}>
<cylinderGeometry args={[0.5, 0.5, 1, 32]} />
<meshStandardMaterial color="green" />
</mesh>
Positioning and Transformations
You can position and transform objects using props:
<mesh
position={[x, y, z]}
rotation={[rotX, rotY, rotZ]}
scale={[scaleX, scaleY, scaleZ]}
>
{/* geometry and material */}
</mesh>
Animations and Interactions
React Three Fiber provides hooks for creating animations and handling interactions.
useFrame for Animations
The useFrame
hook gives you access to the animation loop:
import { useFrame } from '@react-three/fiber';
import { useRef } from 'react';
function RotatingBox() {
const meshRef = useRef();
useFrame((state, delta) => {
meshRef.current.rotation.x += delta;
meshRef.current.rotation.y += delta * 0.5;
});
return (
<mesh ref={meshRef}>
<boxGeometry />
<meshNormalMaterial />
</mesh>
);
}
Handling Interactions
You can use standard React event handlers for interactions:
function InteractiveCube() {
const [active, setActive] = useState(false);
const [hovered, setHovered] = useState(false);
return (
<mesh
onClick={() => setActive(!active)}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
scale={active ? 1.5 : 1}
>
<boxGeometry />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
);
}
Lighting and Materials
Lighting
React Three Fiber provides components for various light types:
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} intensity={1} />
<directionalLight position={[0, 5, 5]} intensity={1.5} castShadow />
<spotLight position={[0, 5, 0]} angle={0.3} penumbra={1} intensity={2} castShadow />
Materials
You can use any Three.js material:
// Basic material
<meshBasicMaterial color="red" wireframe />
// Standard material (with light reactions)
<meshStandardMaterial
color="blue"
roughness={0.5}
metalness={0.5}
/>
// Physical material (more parameters)
<meshPhysicalMaterial
color="green"
roughness={0.1}
metalness={0.8}
clearcoat={1}
clearcoatRoughness={0.2}
/>
Camera Controls
The @react-three/drei
package provides helpful controls:
import { OrbitControls } from '@react-three/drei';
function Scene() {
return (
<Canvas>
<OrbitControls enableZoom={true} enablePan={true} enableRotate={true} />
{/* Your 3D objects */}
</Canvas>
);
}
Other camera controls include:
TrackballControls
FlyControls
PointerLockControls
FirstPersonControls
Performance Optimization
Instance Meshes
For rendering many similar objects:
import { Instance, Instances } from '@react-three/drei';
function ManyBoxes() {
return (
<Instances limit={1000}>
<boxGeometry />
<meshStandardMaterial color="red" />
{Array.from({ length: 100 }, (_, i) => (
<Instance
key={i}
position={[
Math.random() * 10 - 5,
Math.random() * 10 - 5,
Math.random() * 10 - 5,
]}
/>
))}
</Instances>
);
}
Using the useMemo Hook
Optimize geometry and material creation:
function OptimizedBoxes() {
const geometry = useMemo(() => new THREE.BoxGeometry(1, 1, 1), []);
const material = useMemo(
() => new THREE.MeshStandardMaterial({ color: 'hotpink' }),
[],
);
return (
<>
<mesh geometry={geometry} material={material} position={[0, 0, 0]} />
<mesh geometry={geometry} material={material} position={[2, 0, 0]} />
<mesh geometry={geometry} material={material} position={[-2, 0, 0]} />
</>
);
}
Advanced Techniques
Post-Processing Effects
Using the @react-three/postprocessing
package:
import {
EffectComposer,
Bloom,
ChromaticAberration,
} from '@react-three/postprocessing';
function Scene() {
return (
<Canvas>
{/* Your 3D objects */}
<EffectComposer>
<Bloom intensity={1.0} luminanceThreshold={0.5} />
<ChromaticAberration offset={[0.005, 0.005]} />
</EffectComposer>
</Canvas>
);
}
Loading 3D Models
You can load 3D models using the useLoader
hook:
import { useLoader } from '@react-three/fiber';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
function Model() {
const gltf = useLoader(GLTFLoader, '/path/to/model.gltf');
return (
<primitive object={gltf.scene} position={[0, 0, 0]} scale={[1, 1, 1]} />
);
}
Or with the simplified useGLTF
hook from drei:
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/path/to/model.gltf');
return <primitive object={scene} />;
}
Conclusion
React Three Fiber brings the power of Three.js to React applications in an elegant, declarative way. By leveraging React's component model and state management, it makes 3D web development more accessible and maintainable.
Here's a recap of the key benefits:
- Declarative approach to 3D scenes using familiar React patterns
- Simplified state management using React hooks and context
- Automatic optimization through React's reconciliation
- Seamless integration with your React application
- Rich ecosystem of helpers and extensions
Whether you're building immersive product configurators, data visualizations, games, or artistic experiences, React Three Fiber provides a solid foundation for creating compelling 3D content on the web.
Next Steps
To continue learning about React Three Fiber:
- Explore more complex animations using react-spring
- Learn about physics simulations with @react-three/cannon
- Dive into shaders for custom visual effects
- Experiment with VR and AR using @react-three/xr
The combination of React's component model with Three.js's rendering capabilities opens up endless possibilities for creating engaging 3D experiences on the web.