Get to know MDN better
このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental: これは実験的な機能です。
本番で使用する前にブラウザー互換性一覧表をチェックしてください。
安全なコンテキスト用: この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。
WebGPU API は、ウェブ開発者が下層のシステムの GPU (Graphics Processing Unit) を使用し、高効率の計算をしたり、ブラウザーでレンダーできる複雑な画像を描画したりすることを可能にします。
WebGPU は WebGL の後継で、最近の GPU とのより良い互換性を提供し、汎用 GPU 計算に対応し、操作を速くし、さらに高度な GPU の機能へのアクセスを可能にします。
2011 年頃に最初に登場した後、WebGL がグラフィックの能力の面でウェブに革命を起こしたといえます。WebGL は OpenGL ES 2.0 グラフィックライブラリーの JavaScript への移植であり、ウェブページがレンダリング計算をデバイスの GPU に直接渡し、超高速で処理させ、結果を <canvas> 要素内に描画することを可能にします。
WebGL と WebGL シェーダーのコードを書くのに用いられる GLSL 言語は複雑なので、WebGL アプリケーションをより簡単に書けるようにするためにいくつかの WebGL ライブラリーが作られました。有名な例としては Three.js、Babylon.js、PlayCanvas などがあります。開発者はこれらのツールを用い、没入感のあるウェブベースの 3D ゲーム、ミュージックビデオ、訓練やモデリングのツール、VR や AR の体験、などを作ってきました。
しかし、WebGL には修正が必要な根本的な問題点がいくつかあります。
WebGPU は、最近の GPU API と互換性があり、より「webby」な感じがする新しい汎用アーキテクチャを提供し、これらの問題点を解決します。グラフィックのレンダリングに対応しているとともに、GPGPU 計算にもよく対応しています。CPU 側での個別のオブジェクトの描画は劇的に軽くなり、計算ベースのパーティクルや、色効果、鮮明化、被写界深度シミュレーションなどの後処理フィルターなどの最近の GPU のレンダリング機能にも対応します。さらに、カリングやスキン付きモデルの変換などの重い計算を直接 GPU で扱うことができます。
デバイスの GPU と WebGPU API を実行しているウェブブラウザーの間には、いくつかの抽象化レイヤーがあります。WebGPU の学習を開始する際、これらを理解することは有用です。
GPU がある物理デバイス。ほとんどのデバイスには GPU が 1 個だけありますが、複数あるデバイスもあります。以下の異なる GPU の種類が利用可能です。
メモ: 上記の図では、GPU が 1 個だけあるデバイスを仮定しています。
OS の一部であるネイティブ GPU API (たとえば macOS 上の Metal) は、ネイティブアプリケーションが GPU の機能を用いることができるプログラミングインターフェイスです。API 命令がドライバーを通じて GPU に送られ、結果を受け取ります。上記の図ではネイティブ API およびドライバーが 1 個だけあるデバイスを仮定していますが、システムが GPU とやり取りするための複数のネイティブ OS API やドライバーを持つことも可能です。
ブラウザーの WebGPU 実装は、ネイティブ GPU API ドライバーを通じた GPU とのやり取りを扱います。WebGPU のアダプターが、あなたのコード上で下層のシステムで利用可能な物理 GPU とドライバーを効率よく表します。
論理デバイスは、単一のウェブアプリケーションが分離された方法で GPU の機能にアクセスできるようにする抽象化です。論理デバイスは、多重化の機能を提供する必要があります。物理デバイスの GPU は多くのアプリケーションで用いられ、並行で処理を行います。この中には多くのウェブアプリケーションが含まれる可能性があります。それぞれのウェブアプリケーションは、セキュリティおよびロジック上の理由で、隔離された状態で WebGPU にアクセスできる必要があります。
論理デバイスは、GPUDevice オブジェクトインスタンスで表され、ウェブアプリケーションが WebGPU のすべての機能にアクセスする基礎となります。デバイスへのアクセスは、以下の手順で行われます。
これらにいくつかの機能検出チェックを加えると、上記の手順は以下のようにして実現できます。
パイプラインは、プログラムの処理を実現するために実行するプログラマブルなステージが入る論理的な構造です。現在、WebGPU では以下の 2 種類のパイプラインを扱うことができます。
レンダーパイプラインはグラフィックをレンダリングします。<canvas> 要素に描画することが多いですが、オフスクリーンでグラフィックをレンダリングすることもできます。これには以下の 2 個のメインステージがあります。
バーテックスステージ: バーテックスシェーダーが GPU に渡された位置データを受け取り、回転、変換、射影などの指定の効果を適用することで 3D 空間内の頂点群の位置を決定します。そして、頂点は三角形 (レンダリングされるグラフィックの基礎となる部品) などのプリミティブに組み立てられ、GPU によって描画を行うキャンバスのどのピクセルをカバーするかを特定するためにラスタライズされます。
: フラグメントステージ: バーテックスシェーダーによって生成されたプリミティブでカバーされた各ピクセルの色をフラグメントシェーダーが計算します。これらの計算には、表面の詳細を提供する (テクスチャ形式の) 画像や、仮想光源の位置や色などの入力がよく用いられます。
コンピュートパイプラインは一般の計算用です。コンピュートパイプラインは 1 個の計算ステージからなります。このステージでは、コンピュートシェーダーが一般のデータを受け取り、指定の数のワークグループで並列計算を行い、結果を 1 個以上のバッファーで返します。バッファーには任意の種類のデータを置けます。
上記で言及されたシェーダーは、GPU で処理される命令の集合です。WebGPU のシェーダーは WebGPU Shader Language (WGSL) と呼ばれる Rust 風の低レベルの言語で書かれます。
WebGPU アプリケーションを構築するにはいくつかの異なる方法がありますが、このプロセスはおそらく以下の手順を含むでしょう。
以下の節では、レンダーパイプラインの基本デモを解析し、必要なものを探索できるようにします。その後、コンピュートパイプラインの基本の例も解析し、レンダーパイプラインとの違いに注目します。
レンダリング基本デモでは、<canvas> 要素に青一色の背景を用意し、その上に三角形を描画します。
ここでは以下のシェーダーコードを用います。バーテックスシェーダーステージ (@vertex ブロック) は、位置と色が格納されたデータのチャンクを受け取り、位置に基づいて頂点を配置し、色を補間し、これらのデータをフラグメントシェーダーステージに渡します。フラグメントシェーダーステージ (@fragment ブロック) は、バーテックスシェーダーステージからデータを受け取り、指定の色に基づいて頂点の色を決定します。
メモ: ここでのデモではシェーダーコードをテンプレートリテラルに格納していますが、WebGPU プログラムに渡すテキストとして取得しやすい場所ならどこに格納することもできます。たとえば、シェーダーを <script> 要素の中に格納し、Node.textContent を用いて内容を取り出す方法もよく用いられます。WGSL 用の正しい MIME タイプは text/wgsl です。
シェーダーコードを WebGPU で利用できるようにするには、シェーダーコードをディスクリプターオブジェクトのプロパティとして GPUDevice.createShaderModule() に渡し、GPUShaderModule の中に格納する必要があります。これは、たとえば以下のように行います。
レンダーパイプラインでは、グラフィックのレンダリング先を指定する必要があります。ここでは、画面上の <canvas> 要素への参照を取得し、引数 webgpu を HTMLCanvasElement.getContext() に渡すことで、GPU コンテキスト (GPUCanvasContext のインスタンス) を返してもらいます。
そして、レンダリング情報の取得元となる GPUDevice、テクスチャーの形式、半透明のテクスチャーをレンダリングする際に用いるアルファモードが格納されたオプションオブジェクトを GPUCanvasContext.configure() に渡すことで、コンテキストを設定します。
メモ: 使用するテクスチャーの形式を決めるベストプラクティスは、GPU.getPreferredCanvasFormat() メソッドを用いることです。これは、ユーザーのデバイス用の最も効率的な形式 (bgra8unorm または rgba8unorm) を選択します。
次に、WebGPU が利用できる形式で、WebGPU にデータを提供します。データは最初 Float32Array で提供され、ここには三角形の各頂点について 8 個のデータ (位置の X, Y, Z, W および色の R, G, B, A) が格納されています。
しかし、ここで問題に直面します。データを GPUBuffer に格納する必要があります。裏側では、この種類のバッファーは GPU のコアに非常に密接に統合されたメモリーに保存され、期待される高効率の処理を可能にします。副作用として、このメモリーはブラウザーなどのホストシステム上で実行されているプロセスからはアクセスできません。
GPUBuffer は GPUDevice.createBuffer() を呼び出すことにより生成できます。すべてのデータを格納できるよう、配列 vertices の長さと同じサイズを指定します。さらに、バッファーを頂点バッファーとして、およびコピー先として用いることを示す VERTEX および COPY_DST 使用法フラグを指定します。
コンピュートパイプラインの例でデータを GPU から JavaScript に読み戻すために用いるようなマッピング操作を用いてデータを GPUBuffer に乗せることもできます。しかし、ここでは使いやすい GPUQueue.writeBuffer() メソッドを用います。このメソッドは、書き込み先のバッファー、書き込み元のデータソース、それぞれのオフセット値、そして書き込むデータのサイズ (ここでは配列全体の長さを指定した) を引数としてとります。すると、ブラウザーは最も効率のよい方法でデータの書き込みを処理します。
これでデータをバッファーに配置できました。準備の次のパートは、レンダリングに用いることができるパイプラインを実際に生成することです。
まず最初に、頂点データで必要なレイアウトを記述するオブジェクトを生成します。これは以前に配列 vertices およびバーテックスシェーダーステージで見たものを完全に記述します。すなわち、各頂点が位置と色のデータを持ちます。どちらも (WGSL の vec4<f32> 型に対応する) float32x4 形式でフォーマットされ、色データは各頂点で 16 バイトのオフセットから始まります。arrayStride はストライド、すなわち各頂点を構成するバイト数を指定し、stepMode はデータを頂点ごとに読み取るべきであることを指定します。
次に、レンダーパイプラインステージの構成を指定するディスクリプターオブジェクトを生成します。両方のシェーダーステージで関係するコードがある GPUShaderModule (shaderModule)、および各ステージのエントリーポイントとなる関数の名前を指定します。
さらに、バーテックスシェーダーステージでは頂点データに求める状態を提供する vertexBuffers オブジェクトを提供し、フラグメントシェーダーステージでは (以前キャンバスコンテキストの設定で指定した形式と一致する) 指定のレンダリング形式を表す色ターゲットの状態の配列を提供します。
さらに、primitive 状態も指定します。これは今回は単に描画するプリミティブの種類を表します。さらに、layout を auto に設定します。layout プロパティはパイプラインの実行中に用いるすべての GPU リソース (バッファーやテクスチャーなど) のレイアウト (構造、用途、種類) を定義します。より複雑なアプリケーションでは、これは GPUPipelineLayout オブジェクトの形式になるでしょう。これは GPUDevice.createPipelineLayout() を用いて生成でき (コンピュートパイプラインの基本で例を見ることができます)、GPU がどうすればパイプラインを最も効率よく実行できるかを事前に決定できるようにします。しかし、ここでは値 auto を指定し、パイプラインにシェーダーコードで定義されたバインディングに基づいて暗黙のバインドグループレイアウトを生成させます。
最後に、pipelineDescriptor オブジェクトを引数として GPUDevice.createRenderPipeline() メソッドを呼び出すことで、これに基づいて GPURenderPipeline を生成できます。
これですべての準備が完了したので、レンダリングパスを実際に実行し、<canvas> への描画を行うことができます。後で GPU に発行するコマンドをエンコードするには、GPUCommandEncoder インスタンスを生成する必要があります。これは GPUDevice.createCommandEncoder() を呼び出すことで生成できます。
次に、GPUCommandEncoder.beginRenderPass() を呼び出して GPURenderPassEncoder インスタンスを生成することで、レンダリングパスの実行を開始します。このメソッドはディスクリプターオブジェクトを引数にとります。このオブジェクトの唯一の必須プロパティは配列 colorAttachments です。ここでは、以下を指定します。
すると、三角形を描画するためにレンダリングパスエンコーダーのメソッドを呼び出すことができるようになります。
コマンド列のエンコードを完了して GPU に発行するために、あと 3 個の手順が必要です。
これらの 3 個の手順は以下の 2 行で実現できます。
計算基本デモでは、GPU にある値を計算させ、それらを出力バッファーに書き込み、そのデータをステージングバッファーにコピーし、JavaScript からデータを読み取ってコンソールに記録できるようにステージングバッファーをマップします。
このアプリケーションは、レンダリング基本デモに似た構造をなぞります。以前と同様に GPUDevice の参照を生成し、GPUDevice.createShaderModule() の呼び出しによりシェーダーコードを GPUShaderModule にカプセル化します。ここでの違いは、シェーダーコードに @compute ステージという 1 個のシェーダーステージしか無いことです。
この例では、データを扱うために 2 個の GPUBuffer インスタンスを生成します。GPU での計算結果を高速で書き込む output バッファーと、output の内容をコピーして JavaScript から値にアクセスできるようにマップできる stagingBuffer です。
パイプラインの生成時、そのパイプラインで使用するバインドグループを指定します。このためには、まずこのパイプラインで用いるバッファーなどの GPU リソースの構造と目的を定義する GPUBindGroupLayout を (GPUDevice.createBindGroupLayout() を呼び出すことにより) 生成します。このレイアウトは、バインドグループが従うテンプレートとして用いられます。ここでは、パイプラインがバインディングスロット 0 (シェーダーコードの関連するバインディング番号 @binding(0) に対応します) に結びつき、パイプラインのコンピュートステージで使用でき、バッファーの目的が storage と定義された 1 個のメモリーバッファーにアクセスできるようにします。
次に、GPUDevice.createBindGroup() を呼び出すことにより、GPUBindGroup を生成します。このメソッドに、バインドグループのベースとなるバインドグループレイアウトを指定するディスクリプターオブジェクトと、このレイアウトで定義されたスロットにバインドする変数の詳細を渡します。ここでは、バインディング 0 を宣言し、前に定義した output バッファーをそれにバインドするよう指定します。
メモ: GPUComputePipeline.getBindGroupLayout() メソッドを呼び出すことで、バインドグループの生成時に使用される暗黙のレイアウトを取得できます。さらに、レンダーパイプラインで利用可能なバージョンもあります。GPURenderPipeline.getBindGroupLayout() を参照してください。
上記すべてを用意したら、パイプラインディスクリプターオブジェクトを渡して GPUDevice.createComputePipeline() を呼び出すことで、コンピュートパイプラインを生成できます。これは、レンダーパイプラインの生成と似た方法です。コンピュートシェーダーを記述し、コードを探すモジュールとエントリーポイントを指定します。さらに、パイプラインの layout も指定します。ここでは、GPUDevice.createPipelineLayout() を呼び出し、前に定義した bindGroupLayout をベースにレイアウトを生成します。
ここでのレンダーパイプラインのレイアウトとの違いの一つは、何も描画を行わないので、プリミティブの種類を指定していないことです。
コンピュートパスの実行はレンダリングパスの実行と構造は似ており、別のコマンドを用います。まず、GPUCommandEncoder.beginComputePass() によりパスエンコーダーを生成します。
コマンドの発行には、以前と同様に GPUComputePassEncoder.setPipeline() を用いてパイプラインを指定します。しかし、その後は、GPUComputePassEncoder.setBindGroup() を用いて計算に用いるデータの指定に bindGroup を用いることを指定し、GPUComputePassEncoder.dispatchWorkgroups() を用いて計算の実行に用いる GPU ワークグループの数を指定します。
そして、GPURenderPassEncoder.end() を用いてレンダーパスのコマンドリストの終端を示します。
GPUQueue.submit() を用いてエンコードされたコマンドを実行用に GPU に送信する前に、GPUCommandEncoder.copyBufferToBuffer() を用いて output バッファーの中身を stagingBuffer バッファーにコピーします。
出力データが stagingBuffer で参照可能になったら、GPUBuffer.mapAsync() メソッドを用いてデータを中間メモリーにマップし、GPUBuffer.getMappedRange() を用いてマップされた範囲への参照を取得し、データを JavaScript にコピーし、コンソールに記録します。さらに、処理が完了したら stagingBuffer のマップを解除します。
WebGPU の呼び出しは、GPU 処理の中で非同期で検証されます。エラーが検出された場合は、プログラムの呼び出しが GPU 側で無効とマークされます。無効になった呼び出しの返り値に依存する他の呼び出しが行われた場合は、このオブジェクトも無効とマークされ、その先も同様です。このため、WebGPU におけるエラーは「感染性」といわれます。
それぞれの GPUDevice のインスタンスは、各自のエラースコープスタックを管理します。このスタックは最初は空で、特定の種類のエラーをキャプチャするため GPUDevice.pushErrorScope() を呼び出してスタックにエラースコープをプッシュできます。
エラーのキャプチャが完了したら、GPUDevice.popErrorScope() を呼び出すことでキャプチャを終了できます。これは、スタックからスコープをポップし、スコープで最初にキャプチャされたエラーを表現するオブジェクト (GPUInternalError または GPUOutOfMemoryError または GPUValidationError) か、エラーがキャプチャされていない場合は null で解決する Promise を返します。
適する場合は、WebGPU のコードでなぜエラーが発生しているのかを理解する助けとなる有用な情報を「バリデーション」節で提供することを試みました。この節では、エラーを回避するために満たすべき基準を列挙しています。例として、GPUDevice.createBindGroup() のバリデーション節を参照してください。この情報には複雑なものもあります。仕様を繰り返すのではなく、以下の性質を持つエラーの基準のみを列挙することにしました。
explainer で、WebGPU のエラー処理についての詳細情報を得ることができます。Object validity and destroyed-ness および Errors を参照してください。WebGPU Error Handling best practices には有用な実世界での例やアドバイスがあります。
メモ: WebGL でエラーを処理する歴史上の方法は、エラーの情報を返す getError() メソッドを提供することです。これはエラーを同期式で返し、効率がよくないという問題があります。これを呼び出すごとに GPU との往復のやりとりを行い、これまで発行した処理がすべて完了するまで待つ必要があります。さらに、状態モデルはフラット、すなわち関係ないコードの間でエラーが漏れる可能性があります。WebGPU の作者はこれらの点を改善することにしました。
この API のエントリーポイントです。現在のコンテキスト用の GPU オブジェクトを返します。
GPUWebGPU を用いるための出発点です。GPUAdapter を得るのに用いることができます。
GPUAdapterGPU アダプターを表します。これを用いて GPUDevice、アダプターの情報、機能、制限を要求できます。
GPUAdapterInfoアダプターについての特定用の情報を保持します。
論理 GPU デバイスを表します。これは WebGPU の機能の大半へのアクセスに用いるメインインターフェイスです。
GPUSupportedFeaturesGPUAdapter や GPUDevice が対応している追加の機能を表す Set 風オブジェクトです。
GPUSupportedLimitsGPUAdapter や GPUDevice が対応している制限を表します。
"webgpu" contextType を指定して getContext() を呼び出すと、GPUCanvasContext オブジェクトのインスタンスを返します。これは、GPUCanvasContext.configure() を用いて設定できます。
GPUCanvasContext<canvas> 要素の WebGPU レンダリングコンテキストを表します。
GPU での処理で用いる生データを格納できるメモリーのブロックを表します。
GPUExternalTextureGPU でのレンダリング処理でテクスチャーとして用いることができる HTMLVideoElement のスナップショットが格納されたラッパーオブジェクトです。
GPUSamplerシェーダーがテクスチャーのリソースデータの変換やフィルターを行う方法を制御します。
GPUShaderModule内部のシェーダーモジュールオブジェクトへの参照で、パイプラインにより実行用に GPU に送信できる WGSL のシェーダーコードのコンテナーです。
GPUTextureGPU でのレンダリング処理で使用する用の、画像などの 1 次元、2 次元、または 3 次元のデータの配列を格納するのに用いるコンテナーです。
GPUTextureView特定の GPUTexture で定義された、テクスチャーのサブリソースの部分のビューです。
GPUBindGroupLayout に基づき、GPUBindGroup はグループで一緒にバインドされるリソースの集合と、これらのリソースのシェーダーステージでの利用法を定義します。
GPUBindGroupLayoutパイプラインで用いられるバッファーなどの関連する GPU リソースの構造と目的を定義し、GPUBindGroup を生成する際のテンプレートとして用いられます。
GPUComputePipelineコンピュートシェーダーステージを制御し、GPUComputePassEncoder で使用できます。
GPUPipelineLayoutパイプラインで用いる GPUBindGroupLayout を定義します。コマンドのエンコード時にパイプラインとともに用いる GPUBindGroup は、互換性がある GPUBindGroupLayout を持っている必要があります。
GPURenderPipelineバーテックスシェーダーステージとフラグメントシェーダーステージを制御し、GPURenderPassEncoder や GPURenderBundleEncoder で使用できます。
実行用に GPUQueue に送信できる、記録した GPU コマンドのリストを表します。
GPUCommandEncoderコマンドエンコーダーを表します。GPU に発行するコマンドのエンコードに使用します。
GPUComputePassEncoderGPUComputePipeline が発行し、コンピュートシェーダーステージの制御に関するコマンドをエンコードします。GPUCommandEncoder による全体のエンコード処理の一部です。
GPUQueueGPU でのエンコードされたコマンドの実行を制御します。
GPURenderBundle事前に記録されたコマンド群のバンドル用のコンテナーです。(GPURenderBundleEncoder を参照してください)
GPURenderBundleEncoderコマンド群のバンドルを事前に記録するのに使用します。これらは、必要に応じて何度でも、executeBundles() メソッドにより GPURenderPassEncoder で再利用できます。
GPURenderPassEncoderGPURenderPipeline が発行し、バーテックスシェーダーステージとフラグメントシェーダーステージの制御に関するコマンドをエンコードします。GPUCommandEncoder による全体のエンコード処理の一部です。
オクルージョンやタイムスタンプのクエリーなど、パスにおけるクエリーの結果の記録に用います。
GPUCompilationMessage オブジェクトの配列です。シェーダーコードの問題の診断を助けるため、GPU シェーダーモジュールコンパイラーにより生成されます。
GPUCompilationMessageGPU シェーダーモジュールコンパイラーが生成した、1 個の情報、警告、もしくはエラーのメッセージを表します。
GPUDeviceLostInfoGPUDevice.lost Promise が解決する際に返され、デバイスがロストした原因の情報を提供します。
GPUErrorGPUDevice.popErrorScope および uncapturederror イベントで浮かび上がったエラー用のベースインターフェイスです。
GPUInternalErrorGPUDevice.popErrorScope および GPUDevice uncapturederror イベントで浮かび上がったエラーの型の一つです。バリデーションの要求がすべて満たされたにもかかわらずシステムまたは実装に固有の理由で処理に失敗したことを表します。
GPUOutOfMemoryErrorGPUDevice.popErrorScope および GPUDevice uncapturederror イベントで浮かび上がったエラーの型の一つです。要求された処理を完了するのに十分な空きメモリが無かったことを表します。
GPUPipelineErrorパイプラインの失敗を表現します。この値は GPUDevice.createComputePipelineAsync() や GPUDevice.createRenderPipelineAsync() から返された Promise が拒否されたとき渡されます。
GPUUncapturedErrorEventGPUDevice uncapturederror イベント用のイベントオブジェクトの型です。
GPUValidationErrorGPUDevice.popErrorScope および GPUDevice uncapturederror イベントで浮かび上がったエラーの型の一つです。操作が WebGPU API のバリデーションの制約を満たさなかったことを表すアプリケーションエラーを表現します。
この API 全体は保護されたコンテキストでのみ利用可能です。
| WebGPU # gpu-interface |
Enable JavaScript to view this browser compatibility table.
This page was last modified on 2025年12月3日 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.