WebGPUは本番環境対応済み。すべての主要ブラウザがサポート。Three.jsでの切り替えは驚くほど簡単です。
それでも、ほとんどのThree.jsプロジェクトは未だにWebGLで動いています。
この記事は、移行を検討しているチームのための技術的ロードマップです。判断基準、ステップバイステップの移行プロセス、React Three Fiberとの統合、そして多くの人がつまずくエッジケースまでカバーします。
この記事の対象者: WebGPU移行を計画しているThree.js開発者、技術リード、React Three FiberでWebGPUサポートを検討しているチーム。
要点まとめ
- 移行は多くの場合1行の変更—
WebGLRendererをWebGPURendererに置き換えるだけで、Three.jsが残りを処理 - WebGL 2への自動フォールバックにより、今日WebGPUを出荷しても古いブラウザを壊さない
- React Three FiberはWebGPUをサポート—
glプロップのファクトリーパターンで対応 - **TSL(Three Shader Language)**でWGSLとGLSL両方にコンパイルされるシェーダーを記述可能
- コンピュートシェーダーで10〜100倍のパフォーマンス向上—パーティクルシステムや物理演算で威力を発揮
1. あなたのプロジェクトはWebGPUに移行すべきか?
すべてのプロジェクトにWebGPUが必要なわけではありません。判断基準を整理しましょう。
1-1. 移行判断マトリクス
| シナリオ | 推奨 |
|---|---|
| 新規プロジェクト、レガシー制約なし | WebGPUで開始 |
| パフォーマンスの壁にぶつかっている(5万パーティクル以上、高ドローコール) | 移行推奨 |
| 現在のアプリがスムーズに動作、新機能の予定なし | WebGLのまま |
| 重いカスタムGLSLシェーダーあり | TSLを先に検討 |
| キオスク/インスタレーション(ハードウェア固定環境) | 移行推奨 |
| 非常に古いブラウザのサポート必須(Chrome 113未満) | WebGLのまま |
1-2. ブラウザサポート状況(2026年1月時点)
WebGPUは重要なすべてのブラウザでサポートされています:
| ブラウザ | WebGPUサポート | 備考 |
|---|---|---|
| Chrome / Edge | v113以降(2023年5月) | 完全サポート |
| Firefox | v141以降(Windows)、v145以降(macOS) | デフォルトで有効 |
| Safari | v26以降(2025年9月) | macOS、iOS、iPadOS、visionOS |
グローバルカバレッジ: ユーザーの約95%がWebGPU対応ブラウザを使用。残りの5%はWebGL 2フォールバックで自動対応。
Three.jsの変化についての全体像はThree.js 2026年:何が変わったのか?をご覧ください。
1-3. WebGPUが真価を発揮するシナリオ
WebGPUは常に高速というわけではありません。特定のシナリオで威力を発揮します:
- 高ドローコール数: WebGPUのバインディングモデルでCPUオーバーヘッドを削減
- 計算集約型ワークロード: パーティクルシステム、物理シミュレーション、ML推論
- 複雑なポストプロセシング: ネイティブTSLエフェクトがWebGL同等機能を上回る
- 大規模インスタンスメッシュ: より効率的なバッファ管理
ボトルネックがテクスチャアップロード速度やシェーダーコンパイル時間の場合、WebGPUによる改善は限定的かもしれません。
2. 移行チェックリスト:WebGLからWebGPUへ
ステップバイステップのプロセスです。ほとんどのプロジェクトは数時間で完了できます。
2-1. ステップ1:現在のセットアップを監査
コードを触る前に、現状を把握しましょう:
# Three.jsバージョンを確認
npm list three
# WebGL固有の依存関係を確認
grep -r "WebGLRenderer" src/
grep -r "ShaderMaterial" src/
grep -r "RawShaderMaterial" src/
確認ポイント:
- Three.jsバージョン(設定不要WebGPUにはr171以上が必要)
- カスタムGLSLシェーダー(TSL変換が必要)
- ポストプロセシング(更新が必要な場合あり)
- サードパーティライブラリ(WebGPU互換性を確認)
2-2. ステップ2:Three.jsをr171以上に更新
古いバージョンを使っている場合:
npm install three@latest
注意すべき破壊的変更:
BufferGeometryが唯一のジオメトリタイプに- 一部の非推奨メソッドが削除
- 一部モジュールのインポートパスが変更
バージョンジャンプの詳細はThree.jsリリースノートを確認してください。
2-3. ステップ3:レンダラーのインポートを置き換え
これが核心の変更です:
// 変更前(WebGL)
import * as THREE from 'three';
const renderer = new THREE.WebGLRenderer({ antialias: true });
// 変更後(WebGPU)
import * as THREE from 'three/webgpu';
const renderer = new THREE.WebGPURenderer({ antialias: true });
これだけです。three/webgpuエントリポイントにはレンダラー、マテリアル、ライトすべてが含まれます。WebGPUが利用できない場合、WebGL 2に自動フォールバックします。
2-4. ステップ4:非同期初期化を処理
重要な違い: WebGPUの初期化は非同期です。
// WebGL(同期)
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
animate(); // すぐに呼び出せる
// WebGPU(非同期)
const renderer = new THREE.WebGPURenderer();
await renderer.init(); // 使用前に必ずawait
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
animate();
よくあるミス: await renderer.init()を忘れる。シーンは何も描画されず、エラーメッセージも出ません。
既存コードベースでのパターン:
async function initRenderer() {
const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init();
return renderer;
}
// メイン関数内で
const renderer = await initRenderer();
2-5. ステップ5:ポストプロセシングを更新
pmndrs/postprocessingやthree/examples/jsm/postprocessingを使用している場合:
オプションA: TSLネイティブエフェクトを使用(推奨)
import { bloom, pass } from 'three/tsl';
const postProcessing = new THREE.PostProcessing(renderer);
const scenePass = pass(scene, camera);
const bloomPass = bloom(scenePass, { threshold: 0.8, intensity: 1.5 });
postProcessing.outputNode = bloomPass;
オプションB: 既存のポストプロセシングを維持(互換性がある場合)
一部のEffectComposerパスはWebGPUで動作します。個別にテストしてください。
2-6. ステップ6:カスタムシェーダーをTSLに変換
カスタムGLSLシェーダーがある場合、2つのオプションがあります:
オプションA: TSL(Three Shader Language)を使用
TSLはノードベースのシステムで、WGSL(WebGPU)とGLSL(WebGL)両方にコンパイルします:
// GLSLバージョン
const material = new THREE.ShaderMaterial({
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
varying vec2 vUv;
void main() {
gl_FragColor = vec4(vUv, 0.5, 1.0);
}
`
});
// TSLバージョン
import { Fn, uv, vec4 } from 'three/tsl';
const colorNode = Fn(() => {
return vec4(uv(), 0.5, 1.0);
});
const material = new THREE.MeshBasicNodeMaterial();
material.colorNode = colorNode();
2-7. ステップ7:フォールバック検出を実装
グレースフルデグラデーションのために:
async function createRenderer() {
// まずWebGPUを試す
if (navigator.gpu) {
try {
const adapter = await navigator.gpu.requestAdapter();
if (adapter) {
const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init();
console.log('WebGPUを使用');
return renderer;
}
} catch (e) {
console.warn('WebGPU初期化失敗:', e);
}
}
// WebGL 2にフォールバック
console.log('WebGLにフォールバック');
return new THREE.WebGLRenderer({ antialias: true });
}
より簡単なアプローチ(Three.jsが処理):
import * as THREE from 'three/webgpu';
const renderer = new THREE.WebGPURenderer({
antialias: true,
forceWebGL: false // trueにするとWebGLフォールバックをテスト可能
});
await renderer.init();
// WebGPUが利用できない場合、自動的にWebGL 2を使用
2-8. ステップ8:クロスブラウザテスト
すべてのターゲットプラットフォームでテスト:
| ブラウザ | テストの焦点 |
|---|---|
| Chrome | ベースライン—最初に動作するはず |
| Firefox | コンピュートシェーダーサポートを確認 |
| Safari | macOSとiOSの両方で個別にテスト |
| Edge | 通常Chromeと同一 |
Safari固有の注意点:
- 一部のタイムスタンプクエリが未サポート
- テクスチャフォーマットの動作が若干異なる
- iOSでタッチインタラクションをテスト
3. React Three Fiber + WebGPU統合
React Three Fiber(R3F)はWebGPUをサポートしていますが、セットアップにはglプロップの理解が必要です。
3-1. R3F WebGPUサポート状況
R3F v9.x時点(2026年1月):
- WebGPUは非同期
glファクトリープロップで動作 - ほとんどのDreiヘルパーは変更なしで動作
- ポストプロセシングに一部エッジケースあり
3-2. R3FでWebGPURendererをセットアップ
キーは非同期glファクトリーです:
import { Canvas } from '@react-three/fiber';
import { WebGPURenderer } from 'three/webgpu';
function App() {
return (
<Canvas
gl={async (canvas) => {
const renderer = new WebGPURenderer({
canvas,
antialias: true
});
await renderer.init();
return renderer;
}}
>
<mesh>
<boxGeometry />
<meshStandardMaterial color="orange" />
</mesh>
</Canvas>
);
}
重要: glプロップはレンダラーに解決するPromiseを返す必要があります。
3-3. Dreiコンポーネントの互換性
ほとんどのDreiコンポーネントは変更なしで動作:
| コンポーネント | WebGPUステータス |
|---|---|
OrbitControls | 動作 |
Environment | 動作 |
useGLTF | 動作 |
Text | 動作 |
Html | 動作 |
EffectComposer(Dreiの) | 更新が必要な場合あり |
3-4. R3F + WebGPUでよくある落とし穴
落とし穴1: 非同期初期化を忘れる
// 間違い - レンダラーが初期化されていない
gl={(canvas) => new WebGPURenderer({ canvas })}
// 正解 - initをawait
gl={async (canvas) => {
const r = new WebGPURenderer({ canvas });
await r.init();
return r;
}}
落とし穴2: WebGL固有のフックを使用
// WebGPUでは動かない可能性あり
const { gl } = useThree();
gl.capabilities.isWebGL2; // WebGPUではundefined
// より良いアプローチ
const { gl } = useThree();
const isWebGPU = gl.isWebGPURenderer;
4. TSL(Three Shader Language)の基礎
TSLはThree.jsにおけるシェーダーの未来です。今から学んでおきましょう。
4-1. なぜ生のWGSLではなくTSLなのか
| アプローチ | メリット | デメリット |
|---|---|---|
| 生のWGSL | 最大限の制御 | WebGPU専用、冗長 |
| 生のGLSL | 馴染みのある構文 | WebGL専用 |
| TSL | クロスプラットフォーム、合成可能 | 学習コスト |
TSLはWGSL(WebGPU)とGLSL(WebGLフォールバック)両方にコンパイルします。一度書けば、どこでも動きます。
4-2. TSL構文の基礎
TSLは数学演算を伴うJavaScript風の構文を使用します:
import {
Fn, uv, sin, cos, time, vec3, vec4,
positionLocal, normalLocal
} from 'three/tsl';
// UVに基づくシンプルな色
const uvColor = Fn(() => {
const coords = uv();
return vec4(coords.x, coords.y, 0.5, 1.0);
});
// アニメーションする変位
const wobble = Fn(() => {
const t = time.mul(2.0);
const displacement = sin(positionLocal.x.mul(10.0).add(t)).mul(0.1);
return positionLocal.add(normalLocal.mul(displacement));
});
100以上のThree.js最適化パターンについてはThree.jsベストプラクティス100選をご覧ください。
5. コンピュートシェーダーパターン
コンピュートシェーダーはWebGPUの切り札機能です。WebGLでは不可能だったパフォーマンスを実現します。
5-1. コンピュートシェーダーを使うべき場面
| ユースケース | WebGLの限界 | WebGPU + コンピュート |
|---|---|---|
| パーティクル数 | 約50,000 | 1,000,000以上 |
| 物理ボディ | 約1,000 | 100,000以上 |
| データ処理 | CPUバウンド | GPU並列 |
5-2. GPUでのパーティクルシステム
import {
Fn, storage, instancedArray,
instanceIndex, vec3, time
} from 'three/tsl';
// 100万パーティクルの位置を保存
const particleCount = 1000000;
const positionBuffer = instancedArray(particleCount, 'vec3');
const velocityBuffer = instancedArray(particleCount, 'vec3');
// コンピュートシェーダー:位置を更新
const updateParticles = Fn(() => {
const i = instanceIndex;
const pos = positionBuffer.element(i);
const vel = velocityBuffer.element(i);
// シンプルな物理
const gravity = vec3(0, -9.8, 0);
vel.addAssign(gravity.mul(0.016)); // deltaTime
pos.addAssign(vel.mul(0.016));
// 地面との衝突
pos.y.assign(pos.y.max(0));
});
// 毎フレームコンピュートシェーダーを実行
renderer.computeAsync(updateParticles);
6. パフォーマンスプロファイリング
最適化の前に測定を。
6-1. stats-glのセットアップ
stats-glはWebGLとWebGPU両方で動作します:
import Stats from 'stats-gl';
const stats = new Stats({
trackGPU: true,
trackCPU: true,
trackHz: true
});
document.body.appendChild(stats.dom);
function animate() {
stats.begin();
renderer.render(scene, camera);
stats.end();
requestAnimationFrame(animate);
}
6-2. Chrome DevToolsでのGPUデバッグ
- DevTools → パフォーマンスタブを開く
- キャプチャ設定で「GPU」をチェック
- セッションを記録
- 確認ポイント:
- GPUタスクの所要時間
- フレームタイミング
- メモリ割り当てパターン
7. インスタレーション/キオスク向けの考慮事項
専用ハードウェアでThree.jsを実行する場合、WebGPUは特に威力を発揮します。
7-1. Electron設定
キオスクアプリの場合:
// main.js
const { app, BrowserWindow } = require('electron');
app.commandLine.appendSwitch('enable-features', 'Vulkan');
app.commandLine.appendSwitch('use-vulkan');
app.commandLine.appendSwitch('enable-unsafe-webgpu');
const win = new BrowserWindow({
fullscreen: true,
frame: false,
kiosk: true,
webPreferences: {
webgl: true,
webgpu: true
}
});
7-2. WebGPU向けハードウェア選定
インスタレーションではハードウェアが重要:
| GPU | WebGPUパフォーマンス | 推奨 |
|---|---|---|
| Intel内蔵 | 10万パーティクル未満なら十分 | 予算重視の選択肢 |
| NVIDIA RTX 3060以上 | 優秀 | 複雑なシーンに最適 |
| AMD RX 6600以上 | 優秀 | NVIDIAの代替 |
| Apple M1/M2/M3 | 非常に良い | macOSインスタレーション |
ヒント: 24時間稼働のインスタレーションには、コンシューマーカードよりNVIDIA Quadro/RTXシリーズの方が安定性とドライバーサポートに優れています。
100万パーティクルを実行する実際のWebGPUインスタレーションについては北斎インスタレーション事例をご覧ください。
8. Utsuboについて
私たちはThree.jsとインタラクティブインスタレーションを専門とするクリエイティブテクノロジースタジオです。
チームにはRenaud Rohlingerが在籍しており、この記事で解説しているWebGPU統合の構築に貢献したThree.jsコアコントリビューターです。
大阪万博2025での100万パーティクルインスタレーションを含め、WebGPUを本番環境で出荷してきました。Segments.aiなどの企業がWebGPU移行で100倍のパフォーマンス向上を達成するお手伝いもしています。
Three.js Blocksは、Three.jsアプリケーションのプロトタイピング用WebGPUファーストツールキットです。
9. お問い合わせ
WebGPU移行を計画中ですか?パフォーマンス最適化や複雑なインスタレーションでお困りですか?
30分の無料相談を予約して、プロジェクトについてご相談ください。
移行チェックリスト
- 現在のThree.jsバージョンと依存関係を監査
- Three.jsをr171以上に更新
- レンダラーインポートを
three/webgpuに置き換え - レンダラー使用前に
await renderer.init()を追加 - ポストプロセシングをTSLに更新(該当する場合)
- カスタムGLSLシェーダーをTSLに変換(該当する場合)
- フォールバック検出を実装
- Chrome、Firefox、Safari(macOS + iOS)でテスト
- stats-glでプロファイリング
- リソースを適切にdispose
よくある質問
Three.jsはWebGPUをサポートしていますか?
はい。Three.js r171(2025年9月)以降、WebGPUは設定不要のインポートで本番環境対応しています。import * as THREE from 'three/webgpu'を使用するだけで、WebGPUレンダリングとWebGL 2への自動フォールバックが得られます。
React Three FiberはWebGPUをサポートしていますか?
はい。R3Fは非同期glプロップファクトリーを通じてWebGPUをサポートしています。WebGPURendererを作成・初期化する非同期関数を渡します。ほとんどのDreiコンポーネントは変更なしで動作します。
ブラウザがWebGPUをサポートしているか確認するには?
navigator.gpuをチェックし、アダプターのリクエストを試みます。three/webgpuインポートを使用する場合、Three.jsが自動的に処理し、WebGL 2への自動フォールバックを提供します。
WebGLとWebGPUの違いは何ですか?
WebGPUは3つの主要な利点を持つ現代的なグラフィックスAPIです:(1) 汎用GPUコンピューティング用のコンピュートシェーダー、(2) より良いパフォーマンスのための明示的なリソース管理、(3) GPUの実際の動作に合わせた現代的なアーキテクチャ。ドローコールの多いシーンでは2〜10倍のパフォーマンス向上が一般的です。
iOSのSafariはWebGPUをサポートしていますか?
はい、Safari 26(2025年9月)以降サポートしています。WebGPUはmacOS、iOS、iPadOS、visionOSでサポートされています。これがサポートを追加した最後の主要ブラウザでした—WebGPUは今やどこでも動作します。
GLSLシェーダーをWebGPUに変換するには?
生のWGSLではなくTSL(Three Shader Language)を使用します。TSLはWGSL(WebGPU)とGLSL(WebGL)両方にコンパイルするJavaScriptベースのシェーダーオーサリングシステムを提供します。これにより、両方のレンダラーで動作する単一のコードベースを維持できます。
TSL(Three Shader Language)とは何ですか?
TSLはThree.jsのノードベースのマテリアルシステムです。シェーダーをGPUシェーダーコードにコンパイルするJavaScript関数の合成として記述します。クロスプラットフォーム(WGSL + GLSL)で、合成可能で、Three.jsのマテリアルシステムと統合されています。
WebGPU移行にはどのくらい時間がかかりますか?
シンプルなプロジェクト(標準マテリアル、カスタムシェーダーなし):1〜2時間。カスタムGLSLシェーダーがあるプロジェクト:TSL変換に1〜2日。複雑なポストプロセシングを持つ大規模アプリケーション:テストを含めて1〜2週間。

大阪・心斎橋発。記憶に残るWeb体験を。


