mcpField
T
threejs-r3f

threejs-r3f

github.com/athevonデザイン・UI6981.0k 回インストール3 週間前に更新
リポジトリ

threejs-r3f について

Three.js と React Three Fiber で 3D コンテンツを作る開発者向けのクリエイティブコーディングスキルです。シーン構築、アセット読み込み、アニメーション、パフォーマンス最適化を扱い、React の有無に応じた選択も示します。

主な機能

  1. 01Three.js と R3F のシーン構築
  2. 02Drei コンポーネントとアセット読み込み
  3. 03アニメーションループとフックの使い方
  4. 04モデルとテクスチャの最適化
  5. 05GPU リソースの解放方法

活用シーン

  1. 01React プロジェクトでの 3D シーン構築
  2. 02GLTF モデルの読み込みと表示
  3. 03静的または大規模な 3D シーンの最適化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/athevon/genjutsu --skill threejs-r3f

インストール後、Claude Code で/threejs-r3fを入力して読み込まれたか確認します。

詳細

バージョン依存の情報です。 以下のすべての API 名、SDK の要件、ブラウザー対応に関する記述は、 2026-09-08 に一次資料に基づいて検証されています。何をいつ検証したかは _jutsu/VERSIONS.md を参照してください。この日付が古い場合は、バージョン番号に基づいて作業する前に再確認してください。

Three.js と React Three Fiber

Web 上の 3D。Three.js はエンジン、R3F は React のレンダラーです。 ここでは簡潔なルールを紹介します。詳細は references/ を参照してください。

バージョン: three r185(0.185.x)・@react-three/fiber 9.x・@react-three/drei 10.x・@react-three/postprocessing 3.x。 R3F 9 は React 19 専用です。宣言されているピア依存関係の範囲は react / react-dom >=19 <19.3 です(drei 10 は ^19 を要求します)。React 18 のプロジェクトでは、R3F 8 と drei 9 を使用してください。足場を作る前に、インストール済みの React のメジャーバージョンを確認してください。 レンダラー: WebGLRenderer は引き続き R3F のデフォルトです。WebGPURenderer と TSL は正式にリリースされており(フラグなしで利用可能)、WebGL 2 に自動フォールバックします。ただし、Three.js のドキュメントでは「WebGLRenderer の新しい代替」とされており、デフォルトではありません。非同期の gl コールバックでオプトインします:

import * as THREE from 'three/webgpu'
<Canvas gl={async (props) => { const r = new THREE.WebGPURenderer(props as any); await r.init(); return r }} />

用途に応じた選択

必要なものツール理由
フル 3D シーン(モデル、ライト、物理演算)R3F + drei宣言的で、React と親和性が高く、エコシステムも充実
バニラな 3D(React なし)Three.js を直接使用軽量で、React のオーバーヘッドがありません
UI 上のシンプルな 3D 変換CSS transform3dGPU で合成され、WebGL コンテキストが不要です
2D パーティクル/ジェネレーティブ表現Canvas 2DAPI がシンプルで、GPU のオーバーヘッドも小さくなります
シーングラフを使わないシェーダーのみのビジュアルRaw WebGL / ShaderMaterial最大限の制御が可能で、抽象化を最小限に抑えられます

シーンのセットアップパターン

import { Canvas } from '@react-three/fiber'
import { Environment, OrbitControls } from '@react-three/drei'
import { Suspense } from 'react'

<Canvas camera={{ position: [0, 2, 5], fov: 45 }} dpr={[1, 2]} gl={{ antialias: true }}>
  <Suspense fallback={null}>
    <Environment preset="studio" />
    <OrbitControls makeDefault />
    <Scene />
  </Suspense>
</Canvas>

ルール:

  • シーンのコンテンツは必ず <Suspense> でラップしてください。ローダー(GLTF、テクスチャ、HDRI)で必要になります
  • ピクセル比を制限するため、dpr={[1, 2]} を設定してください(GPU に過度な負荷をかけずに Retina に対応できます)
  • Canvas の親コンポーネントは最小限にしてください。再レンダリングがシーンに伝播します

R3F フック

フック目的注意点
useFrame((state, delta) => {})フレームごとの処理(アニメーション、物理演算)内部で setState を呼び出さないでください
useThree()gl、scene、camera、size、viewport、pointer へのアクセス必要なものだけを分割代入してください
useLoader(TextureLoader, url)任意の Three.js リソースを読み込む親を Suspense でラップしてください
useGraph(scene)読み込んだシーンからノード/マテリアルを抽出useGLTF の後に便利です
useFrame のヒント
useFrame((state, delta) => {
  // Use delta for framerate-independent animation
  meshRef.current.rotation.y += delta * 0.5
  // Access clock for time-based effects
  material.uniforms.uTime.value = state.clock.elapsedTime
})

Drei の基本コンポーネント

コンポーネント用途
EnvironmentHDRI ライティング(プリセット:studio、sunset、city、forest、dawn)
Floatアイドル時の浮遊アニメーション(speed、rotationIntensity、floatIntensity)
Text3D押し出し加工された 3D テキスト(Facetype.js の JSON フォントが必要です)
useGLTF.glb/.gltf モデルを読み込む({ nodes, materials, scene } を返します)
useGLTF.preload(url)コンポーネントのマウント前にモデルをプリロード
MeshTransmissionMaterialガラス/水晶/液体の屈折効果
PresentationControls製品紹介でドラッグして回転
Centerメッシュのグループを自動的に中央揃え
DetailedLOD — カメラとの距離に応じてジオメトリを切り替え
useTextureSuspense に対応したテクスチャの読み込み
Instances繰り返し使うメッシュを宣言的にインスタンス化

ポストプロセッシング

import { EffectComposer, Bloom, ChromaticAberration } from '@react-three/postprocessing'
import { BlendFunction } from 'postprocessing'

<EffectComposer>
  <Bloom
    luminanceThreshold={1}
    luminanceSmoothing={0.4}
    intensity={0.6}
  />
  <ChromaticAberration
    blendFunction={BlendFunction.NORMAL}
    offset={[0.002, 0.002]}
  />
</EffectComposer>

ルール:

  • Bloom はデフォルトで選択的に適用されます。発光させるには、マテリアルの色/emissive を 1.0 より大きくしてください
  • luminanceThreshold={1} を設定すると、明示的に発光させない限り何も光りません
  • EffectComposer 内の順序が重要です
  • エフェクトは単一のパスに統合されます(パフォーマンスを考慮した設計です)

パフォーマンスパターン

パターン使用場面
<Instances> / InstancedMesh同一メッシュが100個以上ある場合(パーティクル、木々、群衆)
<Detailed distances={[0, 50, 100]}>LOD:距離に応じて高/低詳細モデルを切り替えます
<primitive> の dispose={null}共有ジオメトリの再利用時に自動破棄を防ぎます
useGLTF + Draco.glb モデルを圧縮します(サイズを70~90%削減)
useTexture + KTX2GPU テクスチャを圧縮します(VRAM を1/4に削減)
Canvas の frameloop="demand"変更がある場合にのみレンダリングします(静的なシーン向け)
useThree の invalidate()demand モードでレンダリングを開始します
<AdaptiveDpr pixelated /> + <AdaptiveEvents />(drei)カメラの移動中は解像度とレイキャストの精度を下げ、停止後に元に戻します
<Bvh>(drei)高速なレイキャスト/ホバー選択が必要な高負荷シーン向け

目標指標: ドローコール100未満、三角形数100万未満、ミドルレンジ GPU で60fps。 監視には stats-gl または r3f-perf を使用します。


禁止事項

1. useFrame 内で絶対に setState しない

毎秒60回の React 全体の再レンダリングが発生します。ref を直接変更してください。

// BAD
useFrame(() => {
  setRotation(prev => prev + 0.01) // React re-render every frame
})

// GOOD
useFrame((_, delta) => {
  meshRef.current.rotation.y += delta * 0.5 // Direct mutation, zero re-renders
})
2. レンダーループ内で絶対にメモリを確保しない

フレームごとに new Vector3() を呼び出すと、GC の急増によってカクつきます。

// BAD
useFrame((state) => {
  const target = new THREE.Vector3(0, Math.sin(state.clock.elapsedTime), 0)
  meshRef.current.position.copy(target)
})

// GOOD
const _target = useMemo(() => new THREE.Vector3(), [])
useFrame((state) => {
  _target.set(0, Math.sin(state.clock.elapsedTime), 0)
  meshRef.current.position.copy(_target)
})
3. dispose を絶対に忘れない(メモリリーク)

Three.js のテクスチャ、ジオメトリ、マテリアルは GPU 上に保持されます。React コンポーネントをアンマウントしても、これらは解放されません。

// BAD -- texture stays in VRAM after unmount
const texture = useLoader(TextureLoader, '/big-texture.jpg')

// GOOD -- R3F auto-disposes when using JSX primitives
// For manual resources, dispose in cleanup:
useEffect(() => {
  return () => {
    texture.dispose()
    geometry.dispose()
    material.dispose()
  }
}, [])
4. Canvas の親コンポーネントを絶対に再レンダリングしない

親コンポーネントの状態が変化すると、Canvas 全体が再マウントされ、画面のちらつき、状態の消失、アセットの再読み込みが発生します。

// BAD
function App() {
  const [uiState, setUiState] = useState(false) // re-renders remount Canvas
  return (
    <>
      <button onClick={() => setUiState(!uiState)}>Toggle</button>
      <Canvas><Scene config={uiState} /></Canvas>
    </>
  )
}

// GOOD -- isolate Canvas in its own component
function App() {
  return (
    <>
      <UI />
      <SceneCanvas />
    </>
  )
}
5. Suspense なしで絶対にアセットを読み込まない

ローダー(useGLTF、useTexture、useLoader)は Promise をスローします。Suspense がないと、クラッシュが発生します。

// BAD
<Canvas>
  <Model /> {/* useGLTF inside -- will throw */}
</Canvas>

// GOOD
<Canvas>
  <Suspense fallback={<Loader />}>
    <Model />
  </Suspense>
</Canvas>

クイックリファレンス:サブリソースの読み込み

必要な情報参照先
シーンの基本構成、照明セットアップ、コントロールreferences/scene-setup.md
カスタムシェーダー、GLSL パターン、uniformreferences/shaders.md
アニメーションの原則、イージング、タイミング../motion-principles/SKILL.md
GSAP と Three.js の連携../gsap/SKILL.md

コメント