R3f Fundamentals

enzed/r3f-skills/skills/r3f-fundamentals

作者 enzed4a11805f0973無授權條款128 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫5 週前更新

Set up React Three Fiber scenes, Canvas, typed JSX, hooks, and resource ownership. Use for scene architecture and render-loop setup, rather than detailed materials or effects.

AI 產生的概覽

指導 React Three Fiber 場景設定、Canvas 使用、具型別 JSX、鉤子、渲染迴圈與資源歸屬。

功能
此技能為設定 React Three Fiber 場景提供指引,包括選擇與版本相符的 API、組織 Canvas 元件,以及正確使用具型別 JSX 和鉤子。內容涵蓋渲染迴圈決策,例如 frameloop 模式、影格優先順序和 ref 變更,以及渲染器和資源歸屬的常見陷阱,如資源釋放和陰影設定。另包含驗證清單和渲染器選擇參考。
適用情境
在架構 React Three Fiber 場景或設定渲染迴圈時使用,尤其是在 React 狀態與 ref 變更之間做選擇,或在 always 與 demand 渲染之間做選擇時。它面向場景架構和渲染迴圈設定,而非詳細的材質或特效。
執行需求
需要一個已安裝 React 和 Three.js 的 React Three Fiber 專案;不附帶指令碼,僅為說明性內容。

React Three Fiber fundamentals

Choose the right baseline

  • Inspect the project's manifest and lockfile before selecting APIs. These examples target Fiber 9 / React 19; Fiber 8 pairs with React 18. Do not upgrade a project just to match a recipe.
  • Check installed Three.js and Drei versions too. Use released documentation matching those versions; if unavailable, state the uncertainty instead of inventing props.
  • Keep the existing renderer unless the task calls for changing it. For WebGPU, read renderer selection [blocked]; Fiber 10 alpha APIs are not Fiber 9 APIs.

Minimal scene

This example owns its Canvas. Its parent must have a nonzero height.

tsx
import { useRef } from 'react'import { Canvas, useFrame, type ThreeElements } from '@react-three/fiber'import type { Mesh } from 'three'
function RotatingBox(props: ThreeElements['mesh']) {  const mesh = useRef<Mesh>(null)  useFrame((_, delta) => {    if (mesh.current) mesh.current.rotation.y += delta * 0.5  })  return (    <mesh {...props} ref={mesh}>      <boxGeometry args={[1, 1, 1]} />      <meshStandardMaterial color="coral" />    </mesh>  )}
export default function Example() {  return (    <Canvas camera={{ position: [0, 0, 5] }} dpr={[1, 2]}>      <ambientLight intensity={0.5} />      <directionalLight position={[3, 4, 5]} intensity={2} />      <RotatingBox />    </Canvas>  )}

Scene and type boundaries

  • Call useThree, useFrame, and loader hooks in components beneath Canvas, never in the component creating that Canvas or inside an event callback.
  • Canvas children are Three.js objects. Place DOM UI outside it or use Drei Html. A Suspense fallback inside Canvas must obey the same rule.
  • Use ThreeElements['mesh'] for mesh props and useRef<Mesh>(null) for refs. Fiber 9 uses ThreeElement<typeof Class> for custom elements; do not use removed Object3DNode or global JSX.IntrinsicElements augmentation.
  • extend(Class) creates a locally typed component in Fiber 9. Use extend({ Class }) plus module augmentation of @react-three/fiber when a shared lowercase JSX element is actually needed.
  • args are constructor arguments: changing them reconstructs the object. Update ordinary props or refs for animation; retain expensive shapes, arrays, and materials when their inputs have not changed.
  • Geometry/material children attach automatically. Use explicit attach for other properties, e.g. attach="attributes-position" for a buffer attribute.
  • Three.js uses radians and local transforms. Convert world-space input into the object's parent space before assigning it to position.

Render-loop decisions

  • Use React state for discrete UI changes; mutate owned refs for per-frame motion. Reuse scratch vectors and use delta in seconds. Do not create a second animation loop for the same scene.
  • useThree(state => state.camera) subscribes to camera replacement, not mutations of camera.position. Read transient values inside useFrame; update the projection matrix after imperative camera projection changes.
  • Default frameloop="always" fits continuous animation. Use "demand" for scenes that can rest: imperative changes need invalidate(), and animations must keep invalidating until settled. Drei controls handle their own invalidation.
  • Negative frame priorities order updates without taking over rendering. A positive priority disables automatic rendering: its owner must render, and must coordinate with any composer. Callbacks run in ascending priority order.
  • Do not reset transforms in JSX and animate the same values from another owner. Visibility changes do not automatically stop callbacks or release GPU resources.

Renderer and ownership pitfalls

  • Default WebGL Canvas uses sRGB output and ACES filmic tone mapping. flat selects NoToneMapping; linear changes output color space. Neither is a generic fix for washed-out assets.
  • On Three.js r182+, use shadows="percentage" for PCF shadows. Bare shadows in Fiber 9 selects deprecated PCFSoftShadowMap on this baseline.
  • Start with defaults; add preserveDrawingBuffer, larger DPR, or extra render passes only for an actual requirement and measure their cost.
  • R3F disposes declaratively owned objects when unmounted. <primitive object={...}> does not dispose the supplied object. Cached loader assets and shared resources need an explicit owner; do not dispose them while another consumer uses them.
  • dispose={null} opts a subtree out of automatic disposal; it is not a general performance switch. Manually allocated resources outside R3F's ownership need cleanup.
  • Effects, subscriptions, and imperative registrations must survive Strict Mode setup/cleanup. Profile before adding memoization; ordinary React renders do not inherently restart useFrame animation.

Verify

Type-check, render in a browser, check the console, resize, and unmount/remount. For demand rendering, verify both waking and returning to idle.

Sources

來源與署名

來源:enzed/r3f-skills位於skills/r3f-fundamentals提交4a11805

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架