--- name: r3f-fundamentals description: React Three Fiber core setup, Canvas configuration, scene hierarchy, camera systems, lighting, render loop, and React integration patterns. Use when setting up a new R3F project, configuring the Canvas component, managing scene structure, or understanding the declarative Three.js-in-React paradigm. The foundational skill that all other R3F skills depend on. --- # React Three Fiber Fundamentals Declarative Three.js via React components. R3F maps Three.js objects to JSX elements with automatic disposal, reactive updates, and React lifecycle integration. ## Quick Start ```tsx import { Canvas } from '@react-three/fiber'; function App() { return ( ); } ``` ## Core Principle: Declarative Scene Graph R3F converts Three.js imperative API to React's declarative model: | Three.js (Imperative) | R3F (Declarative) | |----------------------|-------------------| | `new THREE.Mesh()` | `` | | `mesh.position.set(1, 2, 3)` | `` | | `scene.add(mesh)` | JSX nesting handles hierarchy | | `mesh.geometry.dispose()` | Automatic on unmount | ## Canvas Configuration ```tsx import { Canvas } from '@react-three/fiber'; { // Access Three.js objects after mount }} // Sizing style={{ width: '100vw', height: '100vh' }} /> ``` ### Frameloop Modes | Mode | When to Use | |------|-------------| | `always` | Continuous animation (games, simulations) | | `demand` | Static scenes, only re-render on state change | | `never` | Manual control via `invalidate()` | ```tsx // Demand mode with manual invalidation import { useThree } from '@react-three/fiber'; function Controls() { const invalidate = useThree(state => state.invalidate); const handleDrag = () => { // Update state... invalidate(); // Request re-render }; } ``` ## Scene Hierarchy JSX nesting = Three.js parent-child relationships: ```tsx {/* Children inherit parent transforms */} ``` ### Common Container Components ```tsx // Group: Transform container (no rendering) // Object3D: Base class, rarely used directly // Scene: Usually implicit (Canvas creates one) ``` ## Camera Systems ### Default Perspective Camera ```tsx ``` ### Custom Camera Component ```tsx import { PerspectiveCamera } from '@react-three/drei'; function Scene() { return ( <> {/* Scene contents */} ); } ``` ### Camera Access ```tsx import { useThree } from '@react-three/fiber'; function CameraController() { const { camera } = useThree(); useEffect(() => { camera.lookAt(0, 0, 0); }, [camera]); return null; } ``` ## Lighting ### Light Types ```tsx // Ambient: Uniform, directionless // Directional: Sun-like, parallel rays // Point: Radiates from position // Spot: Cone-shaped // Hemisphere: Sky/ground gradient ``` ### Shadow Setup ```tsx ``` ## Render Loop (useFrame) `useFrame` runs every frame (60fps target). This is where animation happens. ```tsx import { useFrame, useThree } from '@react-three/fiber'; import { useRef } from 'react'; function RotatingBox() { const meshRef = useRef(null!); useFrame((state, delta) => { // state: R3F state (camera, scene, clock, etc.) // delta: Time since last frame (seconds) meshRef.current.rotation.x += delta; meshRef.current.rotation.y += delta * 0.5; }); return ( ); } ``` ### useFrame State Object ```tsx useFrame((state) => { state.clock // THREE.Clock state.clock.elapsedTime // Total time (seconds) state.camera // Active camera state.scene // Scene object state.gl // WebGLRenderer state.size // { width, height } state.viewport // { width, height, factor, distance } state.mouse // Normalized mouse position [-1, 1] state.raycaster // THREE.Raycaster }); ``` ### Render Priority ```tsx // Lower priority runs first, higher runs later // Default is 0 useFrame(() => { // Update physics }, -1); // Runs before default useFrame(() => { // Update visuals }, 0); // Default useFrame(() => { // Post-processing / camera }, 1); // Runs after default ``` ## Accessing Three.js Objects ### useThree Hook ```tsx import { useThree } from '@react-three/fiber'; function SceneInfo() { const { gl, // WebGLRenderer scene, // THREE.Scene camera, // Active camera size, // Canvas dimensions viewport, // Viewport in Three.js units clock, // THREE.Clock set, // Update state get, // Get current state invalidate, // Request re-render (demand mode) advance, // Advance one frame (never mode) } = useThree(); return null; } ``` ### Refs for Direct Access ```tsx import { useRef } from 'react'; import * as THREE from 'three'; function DirectAccess() { const meshRef = useRef(null!); const materialRef = useRef(null!); useEffect(() => { // Direct Three.js API access meshRef.current.geometry.computeBoundingBox(); materialRef.current.needsUpdate = true; }, []); return ( ); } ``` ## Events R3F provides pointer events on meshes: ```tsx console.log('click', e.point)} onContextMenu={(e) => console.log('right click')} onDoubleClick={(e) => console.log('double click')} onPointerOver={(e) => console.log('hover')} onPointerOut={(e) => console.log('unhover')} onPointerDown={(e) => console.log('down')} onPointerUp={(e) => console.log('up')} onPointerMove={(e) => console.log('move')} > ``` ### Event Object ```tsx onClick={(e) => { e.stopPropagation(); // Stop event bubbling e.point // THREE.Vector3 intersection point e.distance // Distance from camera e.object // Intersected object e.face // Intersected face e.faceIndex // Face index e.uv // UV coordinates e.camera // Camera used for raycasting e.delta // Distance from last event }} ``` ## Suspense & Loading R3F integrates with React Suspense for async loading: ```tsx import { Suspense } from 'react'; import { useLoader } from '@react-three/fiber'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; function Model() { const gltf = useLoader(GLTFLoader, '/model.glb'); return ; } function App() { return ( }> ); } function LoadingSpinner() { const meshRef = useRef(null!); useFrame((_, delta) => { meshRef.current.rotation.z += delta * 2; }); return ( ); } ``` ## Dependencies ```json { "dependencies": { "@react-three/fiber": "^8.15.0", "three": "^0.160.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { "@types/three": "^0.160.0" } } ``` ## File Structure ``` r3f-fundamentals/ ├── SKILL.md ├── references/ │ ├── canvas-props.md # Complete Canvas prop reference │ ├── hooks-api.md # useThree, useFrame, useLoader │ └── event-system.md # Event handling deep-dive └── scripts/ ├── templates/ │ ├── basic-scene.tsx # Minimal starter │ ├── lit-scene.tsx # With proper lighting │ └── interactive.tsx # With events and animation └── utils/ └── canvas-config.ts # Preset configurations ``` ## Reference - `references/canvas-props.md` — Complete Canvas configuration options - `references/hooks-api.md` — All R3F hooks with examples - `references/event-system.md` — Pointer events and raycasting