Three.jsでWebGPUを使う|WebGPURendererへの移行ガイド

約10分
Three.jsでWebGPUを使う|WebGPURendererへの移行ガイド

みなさんこんにちは。フロントエンドエンジニアのしゅん(@shun_webdesign)です。

前回、TSLとは?WebGPU時代の新しいシェーダーの書き方という記事で「これからはWebGPUの時代だよ」という話をしました。今回はその実践編として、Three.jsのプロジェクトを実際にWebGPUで動かすところを、コードを交えて見ていきます。

「WebGPUって全部書き直しになるんじゃ…」と身構えるかもしれませんが、結論から言うとそんなことはありません。Three.jsを使っていれば、移行は驚くほど小さな差分で済みます。この記事では、最小の変更点・対応確認のやり方・つまずきやすいポイントまで、ひととおりまとめます。

そもそもWebGPUに移行する意味は?

軽くおさらいです。WebGPUはWebGLの後継で、2026年に主要ブラウザすべてで標準搭載になりました。GPUをより直接的に扱えるので、ざっくりこんなメリットがあります。

  • 描画パフォーマンスが上がりやすい(特にオブジェクトが多いシーン)
  • コンピュートシェーダーが使える(GPUで大量の計算を回せる。パーティクルや物理表現に強い)
  • TSLという新しいシェーダーの書き方が使える(→ [TSLとは?])

これから新しく作るなら、WebGPU前提にしておくと将来的に得をします。

WebGPURendererとは

Three.jsでWebGPUを使う窓口になるのが WebGPURenderer です。これまで使ってきた WebGLRenderer の、WebGPU版だと思ってもらえればOKです。

うれしいのは、WebGPUに対応していない環境では自動的にWebGLにフォールバックしてくれること。つまり「対応ブラウザではWebGPUで、非対応なら従来のWebGLで」描画してくれます。ユーザーの環境を選ばずに出せるので、移行のリスクがかなり下がります。

【実践】小さなシーンを丸ごと移行してみる

言葉だけだとピンと来ないので、箱がくるくる回るだけの最小シーンを、WebGLからWebGPUに移してみましょう。

まず、これまで(WebGL)のコードです。

import * as THREE from "three";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 100);
camera.position.z = 3;

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(),
  new THREE.MeshNormalMaterial()
);
scene.add(cube);

renderer.setAnimationLoop(() => {
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
});

これをWebGPUに移すと、変わるのはたった2行です。

import * as THREE from "three";
import { WebGPURenderer } from "three/webgpu"; // ← 追加

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 100);
camera.position.z = 3;

const renderer = new WebGPURenderer({ antialias: true }); // ← ここだけ変更
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(),
  new THREE.MeshNormalMaterial()
);
scene.add(cube);

renderer.setAnimationLoop(() => {
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
});

差分は three/webgpu から WebGPURenderer を読み込む ことと、レンダラーの生成を差し替える ことだけ。SceneCameraMeshGeometry といった基本の登場人物はまるごとそのまま使えます。世界の作り方は変わらない——ここが「移行が小さく済む」最大の理由です。

async初期化のコツ

ひとつだけ気をつけたいのが、WebGPURendererは初期化が非同期(async)だという点です。

といっても難しくはなくて、上の例のように setAnimationLoop を使えば、中で初期化を待ってから描画を始めてくれます。普段づかいならこれで十分です。

一方、初期化のタイミングを自分で制御したいとき(最初の1フレームを手動で描きたい等)は、await で待ってから描く書き方になります。

const renderer = new WebGPURenderer({ antialias: true });
await renderer.init(); // 初期化を待つ
renderer.render(scene, camera); // ここで初めて手動描画してOK

このあたりの作法はバージョンで少し変わることがあるので、three.js公式のサンプル集(WebGPUのexample)を一度のぞいておくと安心です。

WebGPU対応の確認とフォールバック

前述のとおりWebGPURendererは非対応環境で自動的にWebGLへフォールバックしますが、「今WebGPUで動いているのか、WebGLなのか」を自分で知りたいこともあります。

ざっくり確認するだけなら、ブラウザがWebGPUに対応しているかは navigator.gpu の有無で分かります。

if (navigator.gpu) {
  console.log("この環境はWebGPUに対応しています");
} else {
  console.log("WebGPU非対応 → WebGLで動きます");
}

逆に「検証のためにあえてWebGLで動かしたい」ときは、レンダラー生成時に forceWebGL を渡せば強制的にWebGLバックエンドになります。

const renderer = new WebGPURenderer({ forceWebGL: true });

このフォールバックの仕組みがあるおかげで、「WebGPUにしたら一部のユーザーで真っ白」みたいな事故を避けやすくなっています。

つまずきやすいポイント3つ

実際に移行するとき、僕がつまずいたポイントを3つ挙げておきます。

1. importのパスを間違える
WebGPURendererthree 本体ではなく three/webgpu から読み込みます。ここを three から読もうとして「無い」となるのが定番のつまずきです。

2. OrbitControlsなどのアドオンはそのまま使える
OrbitControls やローダー(GLTFLoader 等)といったアドオンは、これまでどおり three/addons/... から読み込んで普通に動きます。ここは安心してOKです。

3. ポストプロセスは「ノードベース」に変わる
ここが一番大きな違いです。WebGLでよく使う EffectComposer +各種Passという書き方ではなく、WebGPUでは ノードベースのポストプロセス(TSLで書くパス)に変わります。ブルームやグリッチなどエフェクトを多用しているプロジェクトは、ここだけ書き換えが必要になると思っておきましょう。

マテリアルとTSLの関係

WebGPURendererは、これまでの MeshStandardMaterial のような標準マテリアルもそのまま扱えます。なので「まず動かす」だけなら、マテリアル周りは気にしなくて大丈夫。

一方で、シェーダーで独自表現をしたくなったら、TSL(Three.js Shading Language) とノードマテリアル(MeshBasicNodeMaterial など)の出番です。WebGPURenderer + TSL の組み合わせが、これからの「自作シェーダー」のスタンダードになっていきます。詳しくは [TSLとは?] にまとめています。

移行の進め方(いきなり全部やらない)

最後に、実プロジェクトを移すときのおすすめの順番を。

  1. まずレンダラーだけ差し替えて、いつものシーンが表示されるか確認する
  2. 標準マテリアルのままで見た目が崩れていないかチェック
  3. ポストプロセスを使っていれば、そこをノードベースに置き換える
  4. 余裕が出たら、自作シェーダーをTSLに移していく

一気にやろうとすると詰まりやすいので、「動く状態をキープしながら一段ずつ」が安全です。

まとめ

  • WebGPUはWebGLの後継。Three.jsは WebGPURenderer で対応済み
  • 移行の基本は「three/webgpu から読み込んで、レンダラーを差し替えるだけ
  • Scene / Camera / Mesh はそのまま使える=既存知識がムダにならない
  • 非対応環境には自動でWebGLフォールバックnavigator.gpu で対応確認もできる
  • 注意は import元・ポストプロセスのノードベース化 の2つ
  • 独自表現をするなら TSL + ノードマテリアル

「WebGPU移行」と聞くと身構えますが、Three.jsを使っていれば入口はとても小さいです。まずはレンダラーを差し替えて、いつもの箱を回すところから試してみてください。

次は、TSLの土台になる [GLSL入門] や、全体像をつかむ Three.js入門ガイド もあわせてどうぞ。それでは、よいThree.jsライフを🌊

しゅん

しゅん

フロントエンドエンジニア / Webデザイナー。 アメリカ カリフォルニア州生まれ。 音楽、映画、芸術を中心としたサブカルが大好き。 お仕事のご相談は下記リンクのポートフォリオの連絡先からお願いします。

← 記事一覧に戻る