WebGLからWebGPUへの移行:ブラウザでの超高速3Dグラフィックスと計算
10年以上にわたり、WebGLはブラウザでハードウェアアクセラレーションによる3Dグラフィックスを実現する唯一の標準規格でした。OpenGL ESをベースにしたステートマシン型のAPIは、その時代においては有効でしたが、CPUオーバーヘッドが大きく、最新GPU機能への直接アクセスが欠けていました。そこで登場したのがWebGPU — モダンなGPUアーキテクチャに合わせてゼロから設計された次世代グラフィックス兼コンピュートAPIです。
WebGPUは単なる「WebGL 3.0」ではありません。Vulkan、Metal、DirectX 12を鏡写しにした低レベル・明示的APIであり、すべての主要プラットフォームで強力かつポータブルに動作します。
主要コンセプト:Adapter、Device、Queue、Shader
WebGPUは、WebGLの暗黙的なステートマシンに代わる4つの基本オブジェクトを導入します。
| 概念 | 役割 |
|---|---|
| Adapter | 物理GPU(内蔵・外部)を表現。最適なハードウェアを選択するためにアダプターを列挙する。 |
| Device | Adapterへの論理ハンドル。すべてのGPUリソース(バッファ、テクスチャ、パイプライン)はDeviceから生成する。 |
| Queue | エンコードされたコマンドをGPUに送信する。グラフィックスとコンピュートの両方で単一のキューを使用する。 |
| Shader | WGSLで記述し、パイプライン作成時にコンパイルされる。 |
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const queue = device.queue;
この明示的なモデルにより、ドライバのヒューリスティックによる隠れオーバーヘッドが排除され、予測可能なパフォーマンスが得られます。
WGSL:WebGPUシェーディング言語
WGSLはRustライクな構文を持つモダンなシェーダー言語で、安全で効率的なGPUプログラミングを実現します。GLSL(WebGLで使用)とは異なり、厳格な型付け、明示的なメモリレイアウト、組み込みの安全チェックを強制します。
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4f {
let positions = array(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(positions[in_vertex_index], 0.0, 1.0);
}
@fragment
fn fs_main() -> @location(0) vec4f {
return vec4f(1.0, 0.0, 0.0, 1.0);
}
WGSLはGPUの中間表現(VulkanではSPIR-V、AppleではMetal IR)に直接コンパイルされるため、実行時のシェーダーコンパイルオーバーヘッドが発生しません。
コンピュートシェーダー:グラフィックスを超えて
WebGPUの最も革新的な機能のひとつが、ネイティブのコンピュートシェーダーサポートです。WebGLが純粋にグラフィックス指向だったのに対し、WebGPUはブラウザ上で直接、汎用的なGPUコンピューティング(GPGPU)を実行できます。
コンピュートシェーダーの用途:
- 物理シミュレーション — パーティクルシステム、布のシミュレーション
- 画像処理 — リアルタイムフィルター、カラーグレーディング
- 機械学習推論 — ONNX Runtimeによる小規模モデルの実行
- データ解析 — JSON/CSVの並列処理
@compute @workgroup_size(64)
fn cs_main(@builtin(global_invocation_id) id: vec3u) {
let idx = id.x;
output_buffer[idx] = input_buffer[idx] * 2.0;
}
これにより、これまでネイティブアプリケーションが必要だったブラウザベースの科学計算が可能になります。
レンダリングパイプライン:明示的で効率的
WebGPUのレンダリングパイプラインは、モダンなバインドグループモデルに従います。すべてのリソース(バッファ、テクスチャ、サンプラー)は不変のバインドグループにまとめられ、パイプラインは固定構成でコンパイルされます。
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: {
module: shaderModule,
entryPoint: 'vs_main',
buffers: [vertexBufferLayout]
},
fragment: {
module: shaderModule,
entryPoint: 'fs_main',
targets: [{ format: 'bgra8unorm' }]
},
primitive: { topology: 'triangle-list' }
});
これにより、シェーダーやバッファレイアウトの切り替え時にドライバの再コンパイルが発生していたWebGLの高コストなステート変更がなくなります。
WebGLを超えるパフォーマンス
ベンチマークでは、WebGPUは描画コールの多いシナリオでWebGLを2〜5倍上回ります。主な改善点:
- 低CPUオーバーヘッド — 明示的なリソース管理でドライバの負荷を軽減
- 描画コールコストの削減 — モダンなパイプラインモデルで効率的なバッチ処理
- 非同期コンピュート — コンピュートとグラフィックス処理の重複実行
- シェーダー再コンパイルなし — 事前コンパイルされたWGSLでJITの停止を排除
- メモリ制御 — 明示的なバッファマッピングとアライメント
1万以上の描画コールがあるシーンでは、WebGLが1桁のフレームレートに落ちるところでも、WebGPUは安定したフレームレートを維持します。
ブラウザとライブラリのサポート状況
2026年現在、WebGPUはChrome、Edge、Firefox、Safari(実験的フラグ付き)で安定して利用できます。主要な3DライブラリもWebGPUへの対応を進めています。
- Three.js —
WebGPURenderer(r160以降) - Babylon.js — v7.0+ でWebGPUがデフォルトバックエンドに
- PlayCanvas — WebGPU実験的レンダラー
- wgpu-native — ネイティブアプリ向けRust実装
// Three.js WebGPU の例
import { WebGPURenderer } from 'three/examples/jsm/renderers/webgpu/WebGPURenderer.js';
const renderer = new WebGPURenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
WebGLからの移行戦略
既存のWebGLコードベースからは、段階的な移行が推奨されます。
- レンダリングをプロファイリング — WebGLのボトルネックを特定
- ライブラリを採用 — Three.jsやBabylon.jsがAPIの変更を抽象化
- コンピュートパスを試作 — 重いシミュレーションにWebGPUコンピュートを追加
- フォールバック — WebGPU対応を検出し、未対応デバイスではWebGLにフォールバック
if (typeof navigator.gpu !== 'undefined') {
// WebGPU レンダラーを使用
} else {
// WebGL にフォールバック
}
まとめ
WebGPUはブラウザグラフィックスにパラダイムシフトをもたらしました。低レベルで明示的な設計により、ネイティブクラスのパフォーマンスを実現しながら、あらゆるデバイスでポータブルに動作します。3D体験、データ可視化、ブラウザベースのコンピュートアプリケーションを構築する開発者にとって、WebGPUへの移行は単なる高速化ではなく、最新GPUのフル機能を活用するための必須のステップです。
ライブラリのサポートは成熟し、ブラウザのカバレッジもほぼユニバーサルになりつつあります。今こそ、次のグラフィックス集約型ウェブプロジェクトでWebGPUを採用する時です。
