React Three Fiber

repository·master·Indexed 11 days ago

https://github.com/pmndrs/react-three-fiber

A React renderer for Three.js that allows building 3D scenes declaratively using reusable components. It provides full feature parity with Three.js, expressing elements in JSX, and includes a supporting ecosystem with @react-three/eslint-plugin for performance linting and @react-three/test-renderer for testing scene graphs in Node environments. Compatible with React 18 (@react-three/fiber@8) and React 19 (@react-three/fiber@9).

Tokens
43.2K
Snippets
148
Records
170
Agent score
97%

What's inside React Three Fiber

  1. What is @react-three/fiber?

    master

    react-three-fiber is a React renderer for Three.js. It allows you to build Three.js scenes declaratively using reusable, self-contained components that react to state and participate in the React ecosystem.

    Key Characteristics:

    • No Limitations: Everything that works in Three.js works in react-three-fiber.
    • Performance: There is no overhead compared to plain Three.js; components render outside of React, and it can outperform Three.js in scale due to React's scheduling abilities.
    • Feature Parity: It expresses Three.js in JSX (e.g., <mesh /> becomes new THREE.Mesh()), meaning new Three.js features are available immediately without waiting for library updates.
  2. Discover community React Three Fiber components

    master

    This documentation provides a curated list of React Three Fiber (R3F) community components that are not part of the official @react-three/drei collection or other core pmndrs projects. These components cover various categories including data sources, renderers, materials, and utilities.

    Categories of Community Components

    Data Sources

    • 3DTilesRendererJS: NASA-AMMOS implementation for 3D Tiles.
    • Luma Labs Gaussian Splats: Renderer for Gaussian Splatting.
    • three-loader-3dtiles: NYTimes implementation for 3D Tiles.

    Renderers & Frameworks

    • three-geospatial: Takram's geospatial tools (includes clouds and atmosphere).
    • Looking Glass: Support for Looking Glass spatial displays.
    • Theatre-js: A professional animation toolset.

    Materials

    • CustomShaderMaterial: Custom shader material implementation.
    • THREE.MeshLine: A specialized line renderer.
    • R3F-Ultimate-Lens-Flare: High-quality lens flare effects.
    • troika-three-text: Advanced text rendering.

    Utilities

    • r3f-perf: Performance monitoring for R3F applications.
  3. Explore the @react-three ecosystem

    master

    React-three-fiber has a large ecosystem of specialized libraries for common 3D tasks. Key libraries include:

    Core Helpers & Utilities

    • @react-three/drei: A collection of useful helpers and abstractions.
    • @react-three/gltfjsx: A tool to transform GLTF models into reusable JSX components.
    • maath: A library of math helpers for 3D development.
    • leva: A GUI control library to create adjustable parameters in your scene quickly.

    Physics & Geometry

    • @react-three/rapier: 3D physics engine using Rapier.
    • @react-three/cannon: 3D physics engine using Cannon.
    • @react-three/p2: 2D physics engine using P2.
    • @react-three/csg: Constructive Solid Geometry for 3D modeling.

    Visuals & Effects

    • @react-three/postprocessing: Post-processing effects for your scene.
    • @react-three/gpu-pathtracer: Realistic path tracing.
    • lamina: Layer-based shader materials.
    • composer-suite: Tools for composing shaders, particles, and effects.

    UI, Interaction & Animation

    • @react-three/uikit: WebGL-rendered UI components.
    • @react-three/flex: Flexbox implementation for 3D layouts.
    • @react-three/xr: VR/AR controllers and event handling.
    • react-spring: Spring-physics-based animation.
    • framer-motion-3d: 3D support for Framer Motion.
    • use-gesture: Support for mouse and touch gestures.

    State Management & Architecture

    • zustand: Flux-based state management.
    • jotai: Atom-based state management.
    • valtio: Proxy-based state management.
    • miniplex: Entity Management System (ECS).

    Testing & Development

    • @react-three/test-renderer: For performing unit tests in Node environments.
    • @react-three/offscreen: Offscreen/worker canvas support.
    • triplex: A visual editor for react-three-fiber.
  4. What is @react-three/test-renderer?

    master
    Standard React testing tools like react-dom cannot test Three.js elements because @react-three/fiber renders to a different React root using its own reconciler. @react-three/test-renderer solves this by providing a specialized renderer that captures a snapshot of the Three.js Scene Graph, making it possible to perform assertions on your 3D components in a non-browser environment.
  5. Implement Movement Regression for Performance Scaling

    master

    Movement regression allows your application to maintain a fluid framerate by reducing visual quality (e.g., lowering resolution, disabling shadows, or skipping post-processing) when the scene is active or moving.

    React Three Fiber provides a performance object in the state to manage this. You must implement two parts:

    1. Triggering: Call regress() when movement is detected (e.g., on mouse move or camera control changes).
    2. Responding: Listen to the performance.current value to scale your visual settings. A value of 1 is full quality; a value less than 1 (down to your configured min) indicates a request to scale down.

    Note: Simply calling regress() does nothing by itself; your components must explicitly react to the current value.

    // 1. Configure the Canvas with a performance floor
    <Canvas performance={{ min: 0.5 }}>
      {/* 2. A component that responds to the regression
          It scales the pixel ratio based on the 'current' factor
      */}
      <AdaptivePixelRatio />
      <Scene />
    </Canvas>
    
    // Example of the Adaptive component
    function AdaptivePixelRatio() {
      const current = useThree((state) => state.performance.current)
      const setPixelRatio = useThree((state) => state.setDpr)
      
      useEffect(() => {
        setPixelRatio(window.devicePixelRatio * current)
      }, [current])
      
      return null
    }
    
    // Example of triggering regression via controls
    function Scene() {
      const regress = useThree((state) => state.performance.regress)
      const controls = useRef()
    
      useEffect(() => {
        // Call regress whenever the controls change (e.g., user is rotating the camera)
        controls.current?.addEventListener('change', regress)
        return () => controls.current?.removeEventListener('change', regress)
      }, [regress])
    
      return <OrbitControls ref={controls} />
    }
  6. Inspect scene children using allChildren

    master

    When inspecting the scene graph, use the allChildren property on a node to retrieve its geometry and materials. While a children property exists, it is intended for structural elements like Group and may not return the underlying geometry or materials required for assertions.

    // Accessing the first child of the scene and its geometry/materials
    const meshChildren = renderer.scene.children[0].allChildren
    
    // Assertion example
    expect(meshChildren.length).toBe(2)
  7. How React Three Fiber works as a renderer

    master

    React Three Fiber is a React renderer for three.js. Instead of rendering DOM elements, each Fiber component instantiates a corresponding THREE object and manages its lifecycle within a scene graph.

    When you use the <Canvas /> component, Fiber:

    • Creates a new THREE.Scene.
    • Sets up a default perspective camera at [0, 0, 0].
    • Initializes a render loop using setAnimationLoop for automatic rendering.
    • Configures pointer events via raycasting for objects with onPointer props.
    • Handles tone mapping and window resizing automatically.
    import { Canvas } from '@react-three/fiber'
    
    function MyApp() {
      return (
        <Canvas>
          <group>
            <mesh>
              <meshNormalMaterial />
              <boxGeometry args={[2, 2, 2]} />
            </mesh>
          </group>
        </Canvas>
      )
    }
  8. Perform transient updates using Refs and `useFrame`

    master

    For continuous, high-frequency updates (known as transient updates), you should avoid using React state (setState) to drive animations, as this triggers a React re-render every frame.

    Instead, use a React useRef to get a direct reference to the Three.js object and mutate its properties directly inside the useFrame loop. This bypasss the React render cycle for the specific property being changed, leading to much better performance.

    import React from 'react'
    import { useFrame } from '@react-three/fiber'
    
    function MyAnimatedBox() {
      const myMesh = React.useRef()
    
      useFrame(({ clock }) => {
        // Directly mutate the Three.js object property
        if (myMesh.current) {
          myMesh.current.rotation.x = clock.elapsedTime
        }
      })
    
      return (
        <mesh ref={myMesh}>
          <boxGeometry />
          <meshBasicMaterial color="royalblue" />
        </mesh>
      )
    }
  9. Use Three.js objects as native JSX elements

    master

    In React Three Fiber, all Three.js objects are available as native JSX elements using their camel-case names. You do not need to import them manually. For example, THREE.Mesh becomes <mesh /> and THREE.BoxGeometry becomes <boxGeometry />.

    Automatic Attachment: Child elements (like geometries and materials) automatically attach to their parent element (like a mesh) in the Three.js scene graph.

    <Canvas>
      <mesh>
        <boxGeometry />
        <meshStandardMaterial />
      </mesh>
    </Canvas>
  10. Map React props to Three.js properties

    master

    React props on a Fiber component map directly to properties on the underlying Three.js instance. For example, setting <ambientLight intensity={0.1} /> is equivalent to light.intensity = 0.1.

    Shortcuts for .set() methods: For properties that use a .set() method in Three.js (such as colors or vectors), you can pass the value directly as a prop. Fiber will handle the conversion.

    • Vectors: position={[0, 0, 5]} is equivalent to object.position.set(0, 0, 5).
    • Colors: color="red" is equivalent to object.color.set('red').
    <directionalLight position={[0, 0, 5]} color="red" />
  11. How event propagation and bubbling work

    master

    Event propagation in React Three Fiber differs from the DOM because objects can occlude each other in 3D space.

    1. The Intersections Array: The event.intersections array includes all objects intersecting the ray, not just the nearest one.
    2. Bubbling Order: The event is delivered to the object nearest the camera first, then bubbles up through its ancestors. After that, it is delivered to the next nearest object in the intersection list, and its ancestors, and so on.
    3. Blocking Events: By default, objects are transparent to pointer events. To make an object block pointer events from objects behind it, you must call e.stopPropagation() in an event handler (like onPointerOver), even if you don't intend to use the event logic itself.

    Warning: When calling stopPropagation(), pointerout events for objects behind the current one will trigger immediately during the call.

    // Example: Blocking pointer events from reaching objects behind this mesh
    <mesh
      onPointerOver={(e) => {
        e.stopPropagation();
        // ... handle logic
      }}
    />
  12. Understanding the Render Loop

    master

    Fiber manages a render loop using setAnimationLoop. Every frame follows this execution order:

    1. Global before effects are executed.
    2. Clock delta is saved (ensuring all useFrame calls in a single frame share the same delta).
    3. useFrame callbacks are executed in order.
    4. renderer.render(scene, camera) is called to draw the scene.
    5. Global after effects are executed.