threejs-impl-drei について
React Three Fiber 開発者向けの Drei 実装リファレンススキルです。カメラ操作、環境、影、テキスト、マテリアル、モデル読み込み用のコンポーネントとフックをまとめ、インスタンス化や性能支援、シーン配置の機能も扱います。
主な機能
- 01カメラ操作とシーン構成コンポーネント
- 02環境、ライティング、影のツール
- 03テキスト、HTML、マテリアルのコンポーネント
- 04モデル、テクスチャ、アニメーション用フック
- 05インスタンス化とパフォーマンス支援
活用シーン
- 01製品ビューアーや建築ウォークスルーの構築
- 02GLTF モデルの読み込みとアニメーション再生
- 033D シーンへのテキストや HUD の追加
- 04多数のメッシュや複雑なモデルの描画最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ three.js-claude-skill-package --skill threejs-impl-dreiインストール後、Claude Code で/threejs-impl-dreiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/anti-patterns.mdexamples.mdmethods.md詳細
threejs-impl-drei
クイックリファレンス
インストール
npm install @react-three/drei @react-three/fiber three
重要な警告
ローダーフック(useGLTF、useTexture、useFBX、useKTX2、useFont)を使用するコンポーネントは、必ず <Suspense fallback={...}> でラップしてください。Suspense を省略すると、React ツリー全体がクラッシュします。
プライマリカメラコントロールには、必ず makeDefault を追加してください(<OrbitControls makeDefault />)。makeDefault がない場合、Drei のコントロールは R3F のイベントシステムと統合されず、ポインターイベントが機能しなくなります。
無効な Environment プリセット名は絶対に使用しないでください。有効なプリセットは次のもののみです:apartment、city、dawn、forest、lobby、night、park、studio、sunset、warehouse。
重要なアセットの .preload() の呼び出しを絶対に忘れないでください。useGLTF.preload('/model.glb') をモジュールスコープで使うと、コンポーネントのマウント前に読み込みを開始できます。
同一のメッシュを 100 個以上描画する場合は、必ず <Instances> を使用してください。個々のメッシュはそれぞれドローコールを発生させますが、インスタンスを使えば 1 回にまとめられます。
コントロール
OrbitControls
最も一般的なカメラコントロールです。ターゲットの周りを回転、ズーム、パンできます。
import { OrbitControls } from '@react-three/drei'
<OrbitControls
makeDefault // ALWAYS add — integrates with R3F events
enableDamping // smooth movement
dampingFactor={0.05}
minDistance={2}
maxDistance={20}
minPolarAngle={0}
maxPolarAngle={Math.PI / 2} // prevent going below ground
/>
その他のコントロール
| コンポーネント | 使用例 |
|---|---|
CameraControls | 多機能カメラ(複雑なシーンにおすすめ) |
MapControls | 上から見たマップのナビゲーション(回転は垂直軸に制限) |
PresentationControls | ドラッグで回転する、ばね物理を使ったコントロール(製品ビューアー) |
ScrollControls | スクロール駆動アニメーション(pages プロパティでスクロールの長さを設定) |
TransformControls | 選択したオブジェクトの移動・回転・スケーリング用ギズモ |
DragControls | 3D 空間でのオブジェクトのドラッグ |
KeyboardControls | React コンテキストとしてのキーボード入力 |
FaceControls | 顔追跡によるカメラの移動 |
ScrollControls のパターン
import { ScrollControls, useScroll } from '@react-three/drei'
<ScrollControls pages={3} damping={0.1}>
<ScrollScene />
</ScrollControls>
function ScrollScene() {
const scroll = useScroll()
useFrame(() => {
const offset = scroll.offset // 0 to 1
})
return <mesh />
}
環境とステージング
Environment
リアルな反射とライティングのために、HDR 環境マップを読み込みます。
import { Environment } from '@react-three/drei'
// Preset (downloads from polyhaven CDN)
<Environment preset="city" background blur={0.5} />
// Custom HDR file
<Environment files="/env.hdr" background />
// Custom environment with Lightformers
<Environment background>
<Lightformer form="rect" intensity={2} position={[0, 5, -5]} scale={[10, 5, 1]} />
</Environment>
有効なプリセット: apartment、city、dawn、forest、lobby、night、park、studio、sunset、warehouse。
Stage
ライティングとシャドウを 1 つのコンポーネントで設定できます。製品ビューアーに最適です。
import { Stage } from '@react-three/drei'
<Stage preset="rembrandt" intensity={0.5} environment="city" adjustCamera>
<Model />
</Stage>
シャドウコンポーネント
| コンポーネント | 使用例 | 主なプロパティ |
|---|---|---|
ContactShadows | 柔らかな接地影(ライト不要) | opacity、scale、blur、far、resolution、color |
AccumulativeShadows | 高品質なベイク済みの柔らかな影 | frames、alphaTest、scale、opacity |
RandomizedLight | AccumulativeShadows の子要素 | amount、radius、intensity、position |
BakeShadows | シャドウマップを一度ベイクして、更新を停止 | — |
SoftShadows | リアルタイムライト用の PCSS ソフトシャドウ | — |
AccumulativeShadows のパターン
<AccumulativeShadows temporal frames={100} scale={10} position={[0, -0.5, 0]}>
<RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
</AccumulativeShadows>
大気
| コンポーネント | 目的 | 主なプロパティ |
|---|---|---|
Sky | プロシージャルなスカイドーム | sunPosition、turbidity、rayleigh |
Stars | 星のパーティクルフィールド | radius、count、factor、fade |
Sparkles | 浮遊するパーティクル | count、size、speed、color |
Cloud | ボリュームクラウド | opacity、speed、segments、bounds |
テキストと HTML
Text(SDF)
troika-three-text を通じて、符号付き距離場を使用して描画する高品質な 2D テキストです。
import { Text } from '@react-three/drei'
<Text
fontSize={0.5}
color="white"
anchorX="center"
anchorY="middle"
maxWidth={2}
font="/fonts/Inter-Bold.woff"
>
Hello World
</Text>
Text3D
押し出し加工された 3D ジオメトリのテキストです。JSON フォントファイルが必要です(変換には facetype.js を使用してください)。
import { Text3D, Center } from '@react-three/drei'
<Center>
<Text3D font="/fonts/Inter_Bold.json" size={0.75} height={0.2} bevelEnabled bevelSize={0.02}>
Hello
<meshStandardMaterial color="orange" />
</Text3D>
</Center>
Html
3D 空間内に配置された DOM 要素を描画します。
import { Html } from '@react-three/drei'
<mesh position={[0, 2, 0]}>
<Html
transform // transforms with 3D position
distanceFactor={10} // scales with distance
occlude // hides behind 3D objects
center // centers the HTML element
className="label"
>
<div style={{ color: 'white' }}>Annotation</div>
</Html>
</mesh>
Billboard
カメラの方向を常に向きます。ラベルやスプライトに使用します。
import { Billboard, Text } from '@react-three/drei'
<Billboard follow={true} lockX={false} lockY={false} lockZ={false}>
<Text fontSize={0.5}>Always Visible</Text>
</Billboard>
Hud
別の正投影シーンにヘッドアップディスプレイを描画します。
import { Hud, OrthographicCamera } from '@react-three/drei'
<Hud renderPriority={1}>
<OrthographicCamera makeDefault position={[0, 0, 5]} />
<Text position={[0, 0, 0]} fontSize={0.1}>HUD Text</Text>
</Hud>
マテリアル
| コンポーネント | 用途 |
|---|---|
MeshReflectorMaterial | ぼかし、歪み、解像度を設定できる反射床 |
MeshTransmissionMaterial | 色収差、歪み、厚みを設定できるガラス |
MeshRefractionMaterial | 環境キューブマップを使用した屈折 |
MeshWobbleMaterial | MeshStandardMaterial にアニメーション付きの揺らぎを加えます |
MeshDistortMaterial | MeshStandardMaterial にパーリンノイズによる歪みを加えます |
MeshDiscardMaterial | 何も描画しません(影のみのオブジェクト) |
shaderMaterial | カスタム ShaderMaterial を JSX として作成するヘルパー |
MeshReflectorMaterial の例
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
<planeGeometry args={[50, 50]} />
<MeshReflectorMaterial
blur={[300, 100]}
resolution={1024}
mixBlur={1}
mixStrength={50}
roughness={1}
depthScale={1.2}
minDepthThreshold={0.4}
maxDepthThreshold={1.4}
color="#151515"
metalness={0.5}
/>
</mesh>
shaderMaterial ヘルパー
import { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'
const WaveMaterial = shaderMaterial(
{ uTime: 0, uColor: new THREE.Color(0.2, 0.0, 0.1) },
/* vertex */ `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`,
/* fragment */ `uniform float uTime; uniform vec3 uColor; varying vec2 vUv; void main() { gl_FragColor = vec4(vUv * uColor, 1.0); }`
)
extend({ WaveMaterial })
// Usage: <waveMaterial uTime={clock.elapsedTime} />
ローダー
ローダーを使用するコンポーネントは、必ず<Suspense> でラップしてください。
| フック | 戻り値 | プリロード |
|---|---|---|
useGLTF(url) | { nodes, materials, scene, animations } | useGLTF.preload(url) |
useTexture(url) | THREE.Texture またはマップオブジェクト | useTexture.preload(url) |
useFBX(url) | THREE.Group | useFBX.preload(url) |
useKTX2(url) | 圧縮テクスチャ | useKTX2.preload(url) |
useFont(url) | Text3D 用のフォントデータ | useFont.preload(url) |
useAnimations(clips, ref) | { actions, names, mixer, ref } | — |
useVideoTexture(url) | THREE.VideoTexture | — |
useGLTF のパターン
import { useGLTF } from '@react-three/drei'
function Model(props) {
const { nodes, materials } = useGLTF('/model.glb')
return (
<group {...props}>
<mesh geometry={nodes.Body.geometry} material={materials.Metal} />
</group>
)
}
useGLTF.preload('/model.glb')
複数のマップを使った useTexture
const textures = useTexture({
map: '/color.jpg',
normalMap: '/normal.jpg',
roughnessMap: '/roughness.jpg',
aoMap: '/ao.jpg',
})
// Spread directly onto material
<meshStandardMaterial {...textures} />
useAnimations のパターン
function AnimatedModel() {
const group = useRef()
const { nodes, animations } = useGLTF('/character.glb')
const { actions } = useAnimations(animations, group)
useEffect(() => {
actions['Walk']?.play()
return () => actions['Walk']?.stop()
}, [actions])
return <group ref={group}><primitive object={nodes.Scene} /></group>
}
パフォーマンス
インスタンス
同一のメッシュが大量にある場合(100 個超)は、必ず使用してください。描画呼び出しを N 回から 1 回に削減します。
import { Instances, Instance } from '@react-three/drei'
<Instances limit={1000} range={1000}>
<boxGeometry />
<meshStandardMaterial />
{positions.map((pos, i) => (
<Instance key={i} position={pos} color="orange" />
))}
</Instances>
結合
異なるジオメトリを 1 回の描画呼び出しにまとめます。
import { Merged } from '@react-three/drei'
function Furniture({ nodes }) {
return (
<Merged meshes={[nodes.Chair, nodes.Table, nodes.Lamp]}>
{(Chair, Table, Lamp) => (
<>
<Chair position={[0, 0, 0]} />
<Table position={[2, 0, 0]} />
<Lamp position={[1, 1, 0]} />
</>
)}
</Merged>
)
}
パフォーマンス用ヘルパー
| コンポーネント | 用途 |
|---|---|
Detailed | LOD — カメラとの距離に応じてジオメトリを切り替えます |
BakeShadows | 影を一度だけベイクし、更新を停止します |
AdaptiveDpr | パフォーマンス低下時にデバイスのピクセル比を下げます |
AdaptiveEvents | パフォーマンス低下時にイベントの頻度を下げます |
PerformanceMonitor | FPS を監視し、回帰コールバックを呼び出します |
Bvh | 複雑なメッシュのレイキャスティングを BVH で高速化します |
meshBounds | 高速な境界ボックスによるレイキャスティング(ポリゴンごとの処理を置き換えます) |
PerformanceMonitor のパターン
<PerformanceMonitor
onIncline={() => setDpr(2)}
onDecline={() => setDpr(1)}
flipflops={3}
onFallback={() => setDpr(0.5)}
/>
ステージングとレイアウト
| コンポーネント | 用途 | 主な Props |
|---|---|---|
Center | 子要素を原点に配置します | top、right、bottom、left、front、back |
Float | 浮遊するホバーアニメーション | speed、rotationIntensity、floatIntensity |
Bounds | コンテンツに合わせてカメラを自動調整します | fit、clip、observe、margin |
Resize | 子要素を単位サイズに正規化します | width、height、depth |
抽象化とエフェクト
| コンポーネント | 用途 |
|---|---|
Edges | ワイヤーフレームのエッジを描画します |
Outlines | スクリーン空間のアウトライン |
Trail | オブジェクトの後ろにモーショントレイルを表示します |
Decal | テクスチャをメッシュ表面に投影します |
Splat | ガウススプラッティングのレンダラー |
Clone | ジオメトリとマテリアルを共有するディープクローン |
Image | シェーダーエフェクトを適用したテクスチャ付き平面 |
MeshPortalMaterial | ポータル — メッシュ表面の内側にシーンを描画します |
GradientTexture | プロシージャルなグラデーションテクスチャ |
ギズモ
| コンポーネント | 用途 |
|---|---|
GizmoHelper | ビューポートの向きを示すウィジェット |
PivotControls | インタラクティブなピボットギズモ(移動/回転/拡大縮小) |
TransformControls | Three.js の TransformControls ラッパー |
Grid | 無限に広がる、設定可能なグリッド平面 |
Helper / useHelper | ライトやカメラのヘルパーを視覚化します |
コンポーネント選択ガイド
| シナリオ | コンポーネント |
|---|---|
| 製品ビューアー | Stage + OrbitControls + Environment |
| 建築物のウォークスルー | CameraControls + Environment + ContactShadows |
| スクロール体験 | ScrollControls + useScroll |
| データ可視化 | Instances + Html + Billboard |
| 3D のテキストラベル | Text(2D)または Text3D(押し出し)+ Billboard |
| ガラス/透明なオブジェクト | MeshTransmissionMaterial + Environment |
| 反射する床 | MeshReflectorMaterial |
| 数の多い同一のメッシュ | Instances(>100)または Merged(異なるジオメトリ) |
| モデルの読み込み | useGLTF + Suspense + .preload() |
| HUD/オーバーレイ | Hud または fullscreen を指定した Html |
参考リンク
- references/methods.md -- 主要なコンポーネントのプロパティとフックのシグネチャ
- references/examples.md -- 完全に動作するサンプル
- references/anti-patterns.md -- よくある間違いと修正方法