用途
React Three Fiber(R3F)是 Three.js 的 React 渲染器,用于以声明式、组件化的方式编写 3D 场景。它让你用 JSX 描述 Three.js 对象,并与 React 的状态管理和组件生态自然集成。本技能适用于在 React 应用中构建 3D 场景、3D 交互界面或混合 React UI 的 3D 应用。
主要能力
- 核心设置:通过
<Canvas>组件配置相机、WebGL 上下文、阴影、像素比、渲染循环等。 - 核心钩子:
useFrame用于动画循环,useThree访问相机、渲染器、场景、视口、指针等内部对象,useLoader加载模型与纹理资源。 - JSX 映射:Three.js 类名转为 camelCase JSX 元素,构造参数通过
args数组传入,属性作为 props,嵌套属性使用短横线记法,attach用于挂载到父级属性。 - Drei 辅助组件:提供 OrbitControls、Environment、useGLTF、useTexture、Text、Html、Float、Stage、ContactShadows 等生产级抽象。
- 事件处理:网格支持 onClick、onPointerOver、onPointerOut、onPointerMove、onPointerDown、onPointerUp、onDoubleClick、onContextMenu,事件对象包含 point、face、faceIndex、distance、object、eventObject、camera、ray。
- 状态管理:推荐使用 Zustand,也可使用 React Context 或 useReducer。
- 性能模式:实例化(Instances/Instance)、按需渲染(frameloop="demand" 配合 invalidate)、记忆化、自适应性能(PerformanceMonitor、AdaptiveDpr、AdaptiveEvents)。
使用方式
安装 Drei:@react-three/drei。基础用法示例:
import { Canvas } from '@react-three/fiber'
function App() {
return (
<Canvas
camera={{ position: [0, 0, 5], fov: 75 }}
gl={{ antialias: true }}
shadows
>
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} castShadow />
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
</Canvas>
)
}
动画循环示例:
import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'
function SpinningBox() {
const meshRef = useRef()
useFrame((state, delta) => {
meshRef.current.rotation.y += delta
meshRef.current.position.y = Math.sin(state.clock.elapsedTime)
})
return (
<mesh ref={meshRef}>
<boxGeometry />
<meshStandardMaterial />
</mesh>
)
}
资源加载示例:
import { useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
function Model() {
const gltf = useLoader(GLTFLoader, '/model.glb')
return <primitive object={gltf.scene} />
}
Drei 常用组件示例:
import { OrbitControls, Environment, useGLTF, Text, Html, Float, Stage, ContactShadows } from '@react-three/drei'
<OrbitControls enableDamping dampingFactor={0.05} />
<Environment preset="sunset" background />
const { scene, nodes, materials } = useGLTF('/model.glb')
useGLTF.preload('/model.glb')
<Text fontSize={1} color="white" anchorX="center" anchorY="middle">Hello World</Text>
<Html position={[0, 2, 0]} center transform occlude><div className="label">Click me</div></Html>
<Float speed={2} rotationIntensity={0.5} floatIntensity={1}><mesh>...</mesh></Float>
<Stage environment="city" intensity={0.5}><Model /></Stage>
<ContactShadows position={[0, -0.5, 0]} opacity={0.5} blur={2} />
Zustand 状态管理示例:
import { create } from 'zustand'
const useStore = create((set) => ({
score: 0,
gameState: 'idle',
addScore: (points) => set((state) => ({ score: state.score + points })),
startGame: () => set({ gameState: 'playing' }),
}))
实例化示例:
import { Instances, Instance } from '@react-three/drei'
function Boxes({ count = 1000 }) {
return (
<Instances limit={count}>
<boxGeometry />
<meshStandardMaterial />
{Array.from({ length: count }, (_, i) => (
<Instance key={i} position={[Math.random() * 100, Math.random() * 100, Math.random() * 100]} color={`hsl(${Math.random() * 360}, 50%, 50%)`} />
))}
</Instances>
)
}
自适应性能示例:
import { PerformanceMonitor, AdaptiveDpr, AdaptiveEvents } from '@react-three/drei'
<Canvas>
<PerformanceMonitor onDecline={() => setQuality('low')} onIncline={() => setQuality('high')}>
<AdaptiveDpr pixelated />
<AdaptiveEvents />
<Scene quality={quality} />
</PerformanceMonitor>
</Canvas>
适用场景
- 应用本身基于 React,需要自然集成 3D 场景。
- 需要 React 状态管理(如选中对象、分数、库存、设置等)。
- 3D 场景与 React UI 混合使用。
- 需要相机控制、环境光照、文本、HTML 叠加、加载进度等常见 3D 功能。
- 需要实例化大量对象、按需渲染或自适应性能优化。
限制
- 若应用不是 React 基础,可考虑原生 Three.js。
- 若 3D 场景是整个应用且对性能极度敏感(如数百万对象),可考虑原生 Three.js 以获得最大控制权;R3F 对 99% 的用例足够。
- 资料中未提供收费、价格、平台支持范围等具体信息。
相关技能
- 需要原生 Three.js(无 React)时使用 threejs 技能。
- 需要在加载前优化资源时使用 asset-pipeline-3d 技能。
- 需要调试视觉或性能问题时使用 graphics-troubleshooting 技能。
参考文件
- references/drei.md - 完整的 Drei 组件参考
- references/physics.md - @react-three/rapier 集成
- references/postprocessing.md - @react-three/postprocessing 效果
- references/state.md - R3F 的 Zustand 模式