WebGPU + Three.js 移行ガイド(2026年版)

ルカム・ジョスラン

ルカム・ジョスラン

代表取締役、Utsubo株式会社

2026年1月21日·14分で読めます
WebGPU + Three.js 移行ガイド(2026年版)

Table of Contents

WebGPUは本番環境対応済み。すべての主要ブラウザがサポート。Three.jsでの切り替えは驚くほど簡単です。

それでも、ほとんどのThree.jsプロジェクトは未だにWebGLで動いています。

この記事は、移行を検討しているチームのための技術的ロードマップです。判断基準、ステップバイステップの移行プロセス、React Three Fiberとの統合、そして多くの人がつまずくエッジケースまでカバーします。

この記事の対象者: WebGPU移行を計画しているThree.js開発者、技術リード、React Three FiberでWebGPUサポートを検討しているチーム。


要点まとめ

  • 移行は多くの場合1行の変更WebGLRendererWebGPURendererに置き換えるだけで、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 / Edgev113以降(2023年5月)完全サポート
Firefoxv141以降(Windows)、v145以降(macOS)デフォルトで有効
Safariv26以降(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/postprocessingthree/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コンピュートシェーダーサポートを確認
SafarimacOSと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,0001,000,000以上
物理ボディ約1,000100,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デバッグ

  1. DevTools → パフォーマンスタブを開く
  2. キャプチャ設定で「GPU」をチェック
  3. セッションを記録
  4. 確認ポイント:
    • 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向けハードウェア選定

インスタレーションではハードウェアが重要:

GPUWebGPUパフォーマンス推奨
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体験を。大阪・心斎橋発。記憶に残るWeb体験を。

ストーリー×先端技術で惹きつけ、成果につながる導線まで一貫して設計します。

詳しく見る