r3f-fundamentals について
React Three Fiber 開発者向けの基礎スキルです。シーン構成、レンダーループ、型、リソース管理を扱い、導入済みバージョンに合う API の選択と描画・クリーンアップの確認を重視します。
主な機能
- 01シーンと Canvas の構成
- 02Fiber フックと型の境界
- 03レンダーループとオンデマンド描画
- 04レンダラー設定の注意点
- 05リソースの所有権とクリーンアップ
活用シーン
- 01基本的な R3F シーンの構築
- 02導入済みバージョンに応じた API の確認
- 03オンデマンド描画シーンの実装
- 04リソース破棄とアンマウントの確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ enzed/ r3f-skills --skill r3f-fundamentalsインストール後、Claude Code で/r3f-fundamentalsを入力して読み込まれたか確認します。
同梱ファイルreferences/renderers.md
詳細
React Three Fiber の基本
適切なベースラインを選ぶ
- API を選択する前に、プロジェクトのマニフェストとロックファイルを確認してください。これらの例は Fiber 9 / React 19 を対象としています。Fiber 8 は React 18 と組み合わせてください。レシピに合わせるためだけにプロジェクトをアップグレードしないでください。
- インストール済みの Three.js と Drei のバージョンも確認してください。それらのバージョンに対応する公開済みドキュメントを使用してください。入手できない場合は、プロパティをでっち上げず、不確実であることを明記してください。
- タスクで変更が求められていない限り、既存のレンダラーを維持してください。WebGPU については、レンダラーの選択を参照してください。Fiber 10 のアルファ版 API は Fiber 9 の API とは異なります。
最小限のシーン
この例では、独自の Canvas を所有します。親要素にはゼロ以外の高さが必要です。
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>
)
}
シーンと型の境界
useThree、useFrame、ローダーフックは Canvas の配下にあるコンポーネントで呼び出してください。Canvas を作成するコンポーネント内や、イベントコールバック内では呼び出さないでください。- Canvas の子要素は Three.js オブジェクトです。DOM UI は Canvas の外に配置するか、Drei の
Htmlを使用してください。Canvas 内の Suspense フォールバックも同じルールに従う必要があります。 - メッシュのプロパティには
ThreeElements['mesh']を、参照にはuseRef<Mesh>(null)を使用してください。Fiber 9 では、カスタム要素にThreeElement<typeof Class>を使用します。削除されたObject3DNodeや、グローバルなJSX.IntrinsicElementsの拡張は使用しないでください。 - Fiber 9 では、
extend(Class)により、ローカルで型付けされたコンポーネントが作成されます。共有の小文字 JSX 要素が実際に必要な場合は、extend({ Class })と@react-three/fiberのモジュール拡張を使用してください。 argsはコンストラクター引数です。変更するとオブジェクトが再構築されます。アニメーションには通常のプロパティまたは参照を更新してください。入力が変わっていない場合は、高コストなシェイプ、配列、マテリアルを再利用してください。- ジオメトリとマテリアルの子要素は自動的にアタッチされます。それ以外のプロパティには、たとえばバッファー属性に対する
attach="attributes-position"のように、明示的にattachを使用してください。 - Three.js はラジアンとローカルトランスフォームを使用します。ワールド空間の入力を
positionに設定する前に、オブジェクトの親空間に変換してください。
レンダーループの判断
- 離散的な UI の変更には React の状態を使用し、フレームごとの動きには所有する参照を変更してください。作業用ベクトルを再利用し、秒単位の
deltaを使用してください。同じシーンに対して 2 つ目のアニメーションループを作成しないでください。 useThree(state => state.camera)はカメラの置き換えをサブスクライブしますが、camera.positionの変更はサブスクライブしません。一時的な値はuseFrame内で読み取り、カメラの投影設定を命令的に変更した後は、投影行列を更新してください。- デフォルトの
frameloop="always"は、継続的なアニメーションに適しています。静止できるシーンには"demand"を使用してください。命令的な変更にはinvalidate()が必要で、アニメーションは落ち着くまで無効化を続ける必要があります。Drei のコントロールは独自に無効化を処理します。 - 負のフレーム優先度は、レンダリングを引き継ぐことなく更新の順序を決めます。正の優先度を指定すると自動レンダリングが無効になります。その所有者がレンダリングを行い、コンポーザーがある場合はその処理も調整する必要があります。コールバックは優先度の昇順で実行されます。
- JSX でトランスフォームをリセットし、別の所有者から同じ値をアニメーションさせないでください。可視性を変更しても、コールバックが自動的に停止したり、GPU リソースが解放されたりすることはありません。
レンダラーと所有権に関する注意点
- デフォルトの WebGL Canvas は、sRGB 出力と ACES フィルミックトーンマッピングを使用します。
flatはNoToneMappingを選択し、linearは出力色空間を変更します。どちらも、色あせたアセットを汎用的に修正する方法ではありません。 - Three.js r182 以降で PCF シャドウを使用するには、
shadows="percentage"を指定してください。このベースラインでは、Fiber 9 のshadowsのみの指定は、非推奨のPCFSoftShadowMapを選択します。 - まずはデフォルト設定を使用してください。
preserveDrawingBuffer、より大きな DPR、または追加のレンダーパスは、実際に必要な場合にのみ追加し、そのコストを測定してください。 - R3F は、宣言的に所有するオブジェクトがアンマウントされると破棄します。
<primitive object={...}>は、渡されたオブジェクトを破棄しません。キャッシュされたローダーのアセットや共有リソースには、明示的な所有者が必要です。別の利用者が使用中のリソースは破棄しないでください。 dispose={null}は、サブツリーを自動破棄の対象外にします。これは汎用的なパフォーマンス切り替えではありません。R3F の所有権の範囲外で手動割り当てしたリソースは、クリーンアップが必要です。- エフェクト、サブスクリプション、命令型の登録は、Strict Mode のセットアップとクリーンアップを経ても正常に動作する必要があります。メモ化を追加する前にプロファイリングしてください。通常の React のレンダーによって、
useFrameのアニメーションが自動的に再開されるわけではありません。
検証
型チェックを行い、ブラウザーでレンダリングして、コンソールを確認し、リサイズとアンマウント/再マウントを試してください。需要時レンダリングでは、起動時とアイドル状態への復帰時の両方を確認してください。
参考資料
- Fiber 9 の移行 — バージョンによって異なる型とレンダラーの設定。
- Canvas、オブジェクトと破棄、フック。
- パフォーマンスに関する注意点、オンデマンドレンダリング。
コメント
Markdown 対応