View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

WWDC25に戻る

  • 概要
  • トランスクリプト
  • WebGPUでGPUコンピューティングのパワーを最大化

    WebGPU APIを使用して、グラフィックスや一般的な演算でGPUデバイスに安全にアクセスする方法を学びましょう。WGSLシェーディング言語を使ってGPUプログラムを作成する方法についても説明します。すべてのデスクトップとモバイルデバイスの電力消費を最小限に抑えつつ最適なパフォーマンスを実現するためのベストプラクティスも紹介します。

    関連する章

    • 0:00 - イントロダクション
    • 2:14 - WebGPU APIの詳細
    • 9:54 - シェーダの開発
    • 13:57 - パフォーマンスの最適化

    リソース

    • babylon.js – webGL and WebXR library
    • Metal Performance Shaders
    • three.js – webGL and WebXR library
    • Transformers.js - Huggingface
    • WebGPU - W3C
    • WebGPU Samples - github.io
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • SafariとWebKitの新機能
    • SwiftUI向けWebKitの紹介

    WWDC20

    • Apple GPUとMetalの併用
    • Metal PerformanceをApple Silicon Macに最適化する
  • このビデオを検索

    こんにちは Safari Teamのエンジニア Mikeです 本日はWebGPUを使って WebからGPU上の並列演算を 実現する方法について説明します WebGPUは3Dグラフィックスに関して WebGLと同じことができますが パフォーマンスと柔軟性は はるかに優れています Web上のグラフィックスに最適です また ブラウザを使いGPU上で 汎用的な演算を行う 唯一の方法でもあります Metalに詳しい方であれば すぐに馴染めるはずです ほとんどの呼び出しはMetalフレームワーク 呼び出しと1対1の対応関係があります 実際にはMac、iPhone iPad、Vision Proなど Metalに対応するすべての プラットフォームでサポートされています Web APIであるため WebGPUを使う WebサイトやWeアプリは 対応する環境であれば どこでも動作します Apple以外のシステムでは WebGPUは Metalに似たAPIで実装されます 低レベルのグラフィックスプログラミングに 詳しくなくても WebGPUをサポートする多くの グラフィックスライブラリを使えば WebGPUが提供する パフォーマンスや機能をすべて 利用できます WebGPUを内部で実行する threeJSを使えば これらの美しい3Dクラゲをリアルタイムで アニメーション化できます これは素晴らしい例です Safariで非常にスムーズに動作します 最新ハードウェアを最大限に 活用できるように WebGPUが 一から構築されているためです まずAPIを調べ WebGPUとMetalとの対応を確認します ここではWebGPUアプリに必要な多くの コードについて順を追って説明します 次に GPU上で直接実行されるコード WebGPUシェーダプログラムの 作成方法を説明します シェーディング言語とWeb用に新しい 言語が 必要な理由について説明します

    基本を説明した後で APIで最高のパフォーマンスを 実現する方法を説明します すでにWebGPUに詳しい方であれば Appleプラットフォーム向けの特定の 最適化について説明しているので 特に興味深い内容となるでしょう ではグラフィックスパイプラインを 簡単に見ていきましょう

    パイプラインは左から右に流れると 考えることができます まずWebサイトやWebアプリで 画像 ビデオ バイナリデータなどの コンテンツを読み込みます

    そのコンテンツはWebKitに渡され そこでGPUで使えるように準備されます

    WebKitはMetalフレームワークを呼び出し 後でグラフィックスハードウェア上で直接 実行されるリソースやプログラムを 作成します

    では少し詳しく見ていきましょう WebGPUでは Metalは3種類のリソース バッファ テクスチャ サンプラを生成します これらのリソースはWebKitによって GPUバインドグループにまとめられます 基本的にはリソースをグループ化して GPUで効率的に使うための 構造化された方法です 内部的にはこれらのリソースはすべて 引数バッファにまとめられます このバッファは実際のGPUリソースへの 参照を保持するMetalバッファです プログラム自体はコードの文字列から 生成され 主に3つのタイプのプログラム 演算 頂点 フラグメントに コンパイルされます これらはGPU上で実行される 実際の命令であり 計算から画面上のピクセルの レンダリングまですべてを実行します そこでリソースとプログラムがパイプライン にどう組み込まれるかを十分理解した上で WebGPUがAPIで さまざまなインターフェイスをどのように 定義するかについて簡単に説明します

    WebGPUはフラットAPIですが 多くのインターフェイスを持っています 階層の最上位には GPUオブジェクトインターフェイスと GPUアダプタインターフェイスがあります

    canvasはWebGPUでよく使われます canvasはWebGPUのコンテキストを照会 することでGPUCanvasContextを返します

    デバイスはほとんどのAPI呼び出しの メインエントリポイントです これは他のほとんどのインターフェイスを 作成するために使われます

    APIにはさまざまなインターフェイスが ありますが それらはいくつかのカテゴリに 整理されています テクスチャ バッファ サンプラなどの リソースや

    リソースに対してコマンドを 発行するエンコーダ エンコーダでのリソースの解釈方法を 指示するパイプライン 関連リソースをグループ化する バインドグループ GPUで計算を実行するための命令を含む シェーダモジュール といったカテゴリがあります ではWebGPUの 全体構造を理解したところで デバイスとリソースの作成方法を示して APIの使い方を説明します

    デバイスはほとんどのAPI呼び出しの エントリポイントです Metalに詳しい方であれば MTLDeviceと似ていることがわかるでしょう

    ページにcanvasがあると仮定して まずcanvas要素を取得します 次にnavigator.gpu.requestAdapter() を使ってアダプタを作成し requestDeviceを呼び出して GPUデバイスを作成します

    WebGPUはいくつかの拡張機能を サポートしており その一つが半精度浮動小数点数を使うための shader-f16拡張機能です

    これはメモリ帯域幅を削減することで パフォーマンスを向上させます すべてのAppleデバイスでサポートされて いますが オプション機能であるため 他のプラットフォームで使う際は 事前にサポート状況を確認してください

    次にconfigureを呼び出し デバイスで canvasのコンテキストを設定します これによりcanvasがメモリにリンクされ GPUはこのメモリに書き込みを行います

    デバイスの準備ができたので リソースの作成を開始できます WebGPUではバッファやテクスチャなどを 使って処理を行います MetalではこれらはMTLBufferと MTLTextureで表されます

    バッファは非常に柔軟性が高く 浮動小数点数のベクトルといった 単純なものから 自分で定義した より複雑なカスタムデータ型まで あらゆる種類のデータを保存できます たとえばパーティクル型の 複数のインスタンスを保持する バッファがあるとします バッファには3つのパーティクルが 保存されていると考えてみましょう

    バッファはデバイスでcreateBufferを 呼び出すことで作成されます バッファサイズと使用モードを渡します 使用モードによりWebGPUは データ競合を回避できます APIを追加して複雑にする 必要はありません

    デバイスにはqueueというプロパティがあり バッファやテクスチャの操作に使います

    バッファが作成されたら writeBufferを呼び出し バッファ オフセット JavaScriptの arrayBufferを渡し その内容を設定します

    バッファと同様にテクスチャも 基本的にはメモリの塊ですが GPU上の特別なテクスチャレジスタや 命令と関連付けられます 多くの場合 これらは画像データを表し 1次元 2次元 2次元テクスチャの配列 6つの2次元テクスチャの配列である キューブマップ または3次元テクスチャとして 扱われます

    テクスチャを作成するには device.createTextureを呼び出し テクスチャの幅と高さ 2Dテクスチャフォーマット および使用モードを渡します

    GPUTextureの作成後 device.queue.copyExternal ImageToTextureを使って 画像ビットマップ 作成した2Dテクスチャ 画像サイズを渡すことで 画像データを読み込むことができます

    多くの場合テクスチャは画像データから 作成されGPU上で画像を表します デバイスとリソースを作成したら パイプラインの作成方法を見てみましょう

    パイプラインはGPUでのテクスチャや バッファの使用方法を指定します パイプラインには2つの種類があります レンダリングパイプラインは頂点プログラム やフラグメントプログラムで使われ 演算パイプラインは演算プログラムで 使われます これらはMetalの MTLRenderPipelineStateオブジェクトと MTLComputePipelineState objects オブジェクトにマップされます

    演算パイプラインを作成するには device.createComputePipelineを呼び出し バインドグループまたは シェーダからレイアウトを生成する 定数識別子autoを渡します

    レイアウトとはバッファ テクスチャ サンプラが APIからGPUプログラムへ渡される 構造化された方法です

    パイプラインの作成には シェーダモジュールが必要です これは文字列から作成されます

    レンダリングパイプラインも 同様の方法で作成され 自動レイアウト 頂点シェーダモジュール フラグメントシェーダモジュールが 使われます

    デバイス リソース パイプラインを 作成したら WebGPUアプリケーションの基本設定は 完了です

    WebGPU APIのアーキテクチャについて 説明してきました 次にシェーダの開発方法を見てみましょう

    WGSLと呼ばれる WebGPUシェーディング言語を使うと WebサイトではGPU上で直接実行される プログラムを簡単に作成できます AppleはWGSLシェーディング言語の 設計と実装に深く関わっています WGSLはWebでの安全を考慮し 一から構築されています WGSLは3種類のプログラムに 対応しています 頂点プログラムとフラグメントプログラム 演算プログラムです

    この簡単なWebGPUの例の作成方法を 説明します 次のプログラムで構成されます JavaScriptからバッファデータを取得し 画面に三角形を作成する頂点プログラム テクスチャの個々の色と深度の値を計算する フラグメントプログラム そして一般的な演算を実行できる 演算プログラムです この演算プログラムでは 物理シミュレーションを実行します

    頂点プログラムは三角形が表示される 画面上の位置を計算します

    ここではこの例で使われている 10万個の三角形の輪郭を確認できます

    三角形の出力位置を書き込むには @builtin位置属性を使います

    これはmain関数の定義と 頂点シェーダの入力です 位置と色を書き込むだけです ではフラグメントシェーダを見てみましょう

    頂点ステージで生成した色を取得し その色をテクスチャに保存します これは簡単な例ですが ここに任意のロジックを挿入して 色と深度の値を計算できます ストレージテクスチャやバッファへの 書き込み アトミック操作なども実行できます WGSLは本当に柔軟です その柔軟性をさらに見てみましょう 演算シェーダを取り上げます

    他のプログラムと同様に 演算シェーダには JavaScriptからシェーダへの入力である 多くのバインディングを含めることが できます

    演算シェーダは非常に便利です 必要な演算を実行し 結果をバッファに保存し バッファをJavaScriptコードに 読み戻すことができます 画面上に描画する必要はありません WebGLでは演算シェーダを 使えませんでした これが新しいアプリケーションで WebGPUを使うべきもう一つの理由です

    演算プログラムには 演算シェーダが実行されるグリッドの サイズを定義するワークグループサイズ が必要です

    グリッド全体における位置を示す global_invocation_idも使います これは組み込み変数であり JavaScriptから何も渡さなくても使えます

    演算シェーダの本体は 重力 速度 経過時間を適用して パーティクルシミュレーションを更新します

    演算シェーダでは必要な演算を すべて実行できます この演算はGPU上で驚異的な パフォーマンスで並列実行されます

    パーティクルが完全にフェードアウトすると 確率マップに対して textureLoadを呼び出し パーティクルの新しい位置を 選択することで そのパーティクルが再生成される 新しい位置が決まります

    最後にパーティクル残りの属性が 開始値にリセットされ パーティクルはバッファに保存されます

    すべてを組み合わせると WebGPUロゴの 素敵なアニメーションが完成します GPUの並列処理能力を活用することで これまでWebではできなかった どのような規模の演算でも リアルタイムのパフォーマンスを 維持しながら実行できます

    素晴らしいですね

    WebGPUアプリケーション用のシェーダの 開発方法に関する概要を説明しました 次に WebGPUの最高のパフォーマンスを 引き出す方法を説明します

    Appleのプラットフォームで 最高の体験を実現するために役立つ 覚えておくべきガイドラインがあります 優れたパフォーマンスの鍵は メモリ使用量に注意することです つまりメモリ効率の良いデータ型を使い レンダリングコマンドを 一度記録して再利用し リソースの数を低く抑えるということです さらに詳しく見ていきましょう

    メモリ使用量を最小限に抑えるには いくつか方法があります まず半精度浮動小数点数を使います これはIEEE標準です WGSLではデータ型はf16と呼ばれます これによりメモリ使用量が大幅に削減され パフォーマンスが向上します しかし 必ずしも実用的ではありません 精度が低くてもアルゴリズムが 安定していることを確認し より大きな値を処理できる 32ビット浮動小数点数とは異なり その値が65,000強で最大になることに 注意してください 特にiOSとvisionOSでは データをf16や圧縮形式で保存すると メモリ不足によりプログラムが 終了するのを 防ぐことができます 半精度浮動小数点を使うには デバイス作成時とWGSLコードで 有効にする必要があります 簡単なコード例を使って その方法を説明します

    まずrequestDeviceの呼び出しで shader-f16拡張機能を有効にして シェーダに「enable f16」 ステートメントを追加します

    その後でf16スカラ型とベクトル型を 先ほどと同様にすべての32ビット型と共に 使うことができます データを半精度で保存し すぐにf32にパック解除しても 多くのメモリのメリットを活かして メモリ不足によりアプリの終了を 回避できます

    メモリ使用量を最小限に抑える もう一つの方法は 不要なバッファやテクスチャの 更新呼び出しを回避することです これを行うには Metalリソースをサポートするメモリへの JavaScriptからのデータコピーが必要です インデックスモードや間接使用モードでの バッファ更新は 高いコストがかかる場合があります バッファの再利用前に 検証の実行が必要になるためです これらのバッファは頂点バッファを 直接的/間接的にインデックス参照しており WebGPUでは描画コマンドの実行前に バッファへのすべてのオフセットが 範囲内にあることを確認する必要があります

    こうしたバッファは必要な場合にのみ 更新してください これは書き込みまたは読み取り/書き込み アクセスで バインドグループ内のバッファを使う際にも 該当します コード例のようにシェーダ内のリソースを 使って書き込まないのであれば 特にリソースがインデックスや間接バッファ の場合は 読み取り専用アクセスを優先してください メモリに関するこれらのヒントは Appleのプラットフォームだけでなく すべてのモバイルやデスクトップデバイスで パフォーマンスに大きな影響を与えます 次にレンダリングコマンドの 再利用について詳しく説明します

    再利用の方法にレンダリングバンドルが あります コマンドを1回エンコードしておけば 必要なだけ何度でも再利用できます WebGPUではすべての読み書きが適切に 定義され 範囲内にあることを確認する 必要があります 通常であれば各フレームで多数の検証が 行われます レンダリングバンドルでは 検証はバンドル作成時の1回だけで バンドル実行時に毎回実行されません このため 処理時間の短縮や ネイティブに近いパフォーマンスが実現され 実際のロジックに余裕が生まれます レンダリングバンドルは簡単に作成できます レンダリングバンドルエンコーダを作成し 次に描画関数の呼び出しをエンコードします レンダリングパスエンコーダと同じです finish()を呼びして 再利用向けのバンドルを作ります

    バンドルができたので executeBundles()を呼び出して すべての描画コマンドを実行できます 必要に応じて何度でも実行できます

    内部的にレンダリングバンドルは Metalの間接コマンドバッファにマップされ パフォーマンスが同様に改善されます メモリ使用量の問題を解決し 検証のオーバーヘッドを削減したので リソース数の削減について見てみましょう

    具体的には コマンドバッファや レンダリングパスと演算パス バインドグループレイアウトと バインドグループです

    コマンドバッファの境界では 高速なオンチップメモリと 統合されたオンデバイスメモリ間の 同期が必要です 可能であれば更新ループごとに 1つのコマンドバッファを使うか それが不可能な場合は 一般的な経験則として コマンドバッファの数を できるだけ少なくします コマンドバッファを分割する必要があるのは 統合メモリに書き戻されたデータが 必要になる場合だけです 通常 そのようなケースはまれです

    コマンドバッファとは異なり パスは統合メモリとの同期を必要としません それでもレンダーターゲットや 演算ディスパッチのサイズによっては かなりのメモリ帯域を消費します そのためメモリ帯域幅を節約するには 可能な限り少ないパスを使うのが適切です

    多くの携帯電話と同様にAppleデバイスの GPUは タイルベースの遅延レンダラに 基づいています パスの統合やメモリ帯域の節約のための ベストプラクティスによって サイトやWebアプリはAppleのハードウェア上 で優れた性能を発揮できます タイルベースのレンダラの詳細については 「Metal Performanceを Appleシリコン搭載のMacに最適化する」と WWDC 2020の「Apple GPUと Metalの併用」をご覧ください

    バインドグループに注目してみましょう バインドグループはMetalの引数バッファで 実装されており バインドグループの作成と同時に 新しいMTLBufferも作られます 動的オフセットを使うと 同じレイアウトを共有するが 実行時に異なるリソースを使う単一の バインドグループを作成できます 動的オフセットを使うには シェーダモジュール からの自動レイアウトを使わずに カスタムのバインドグループレイアウトを 作る必要があります

    hasDynamicOffsetを指定し createBindGroupLayoutを呼び出して レイアウトを作り 次にそのレイアウトを 渡してバインドグループを作ります 動的オフセットはsetBindGroupの 呼び出しに関係します バインドグループの動的バッファごとに 1つのオフセットが必要です

    このバインドグループで動的オフセットを 使うバッファは1つであるため 1つのオフセットがsetBindGroupに 渡されます

    たとえば10個のバインドグループを作り 各 グループが64バイトのバッファを持つよりも

    640バイトのバッファを1つ作って10個分の 64バイトオブジェクトを表す方が適切です これでMetalバッファを9個作らずに 済みました

    類似したデータを少ないメモリに保存し 検証の繰り返しを避け 作られるMetalオブジェクトの総数を最小に 抑えることで WebGPUで魅力的かつ 高効率なWebサイトやWebアプリを作れます WebGPUを使う際は これらパフォーマンスの 考慮事項を意識してください WebGPUを使うとカスタムアルゴリズムを GPU上で直接実行できます これまでWebからは不可能でした 今日からWebGPUをお使いください Mac、iPhone、iPadと Vision Proで動作します 最適な使用ガイドラインもご参照ください

    WebでのGPUプログラミングの未来に 期待しています

Developer Footer

  • ビデオ
  • WWDC25
  • WebGPUでGPUコンピューティングのパワーを最大化
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン