背景
世間では WebGPU といえば wgpu というところでしょう。しかし、emscripten にも WebGPU を扱うためのバインディングが用意されており、WebGPU を使った Web アプリを開発することができます。
ブラウザ側でも WebGPU 対応はもう間も無く1といったところまできており、Chrome v102 からフラグなしで利用可能になる予定です2。
OpenSiv3D for Web では、今年7月から WebGPU バックエンドの実装の優先度を高め、その実装を進めてきました。OpenSiv3D for Web の WebGPU バックエンドは v0.6.3 から、実験的な機能として利用可能になります。
OpenSiv3D for Web v0.6.3 の WebGPU バックエンドのサンプルは このページ からアクセスできます。
この記事で得られる知見
- OpenSiv3D for Web v0.6.3 で WebGPU バックエンドを有効にする方法
- OpenSiv3D for Web v0.6.3 での WebGL/WebGPU バックエンドの性能の考察 (ただし、動作検証環境は1つだけのため参考程度に)
WebGPU バックエンドの制限事項
- Chrome Canary (Windows, macOS) で enable-unsafe-webgpu のフラグを有効にしたうえで動作します
- VideoReader, WebCam, ScreenCapture, Texture::readRT は未実装のため利用できません
- レンダーターゲットの切り替え時に、viewport の範囲がおかしくなる現象が発生します
OpenSiv3D for Web v0.6.3 で WebGPU アプリを作成する
OpenSiv3D for Web v0.6.3 のインストール
通常版の OpenSiv3D for Web に WebGL2 バックエンド、WebGPU バックエンドの両方が含まれています。OpenSiv3D for Web のインストールは OpenSiv3D for Web プロジェクトサイト を参照してください
WebGPU バックエンドを有効にする
次の一行をグローバルスコープに追加します。
SIV3D_SET(EngineOption::Renderer::WebGPU)
例えば、OpenSiv3D for Web プロジェクトサイトのトップページに掲載しているコードサンプル では、次の通りに一行を追加します。
# include <Siv3D.hpp>
SIV3D_SET(EngineOption::Renderer::WebGPU)
void Main()
{
// 背景を水色にする
Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });
// 通常のフォントを作成
const Font font{ 60 };
// 絵文字用フォントを作成
const Font emojiFont{ 60, Typeface::ColorEmoji };
// `font` が絵文字用フォントも使えるようにする
font.addFallback(emojiFont);
// 画像ファイルからテクスチャを作成
const Texture texture{ U"example/windmill.png" };
// 絵文字からテクスチャを作成
const Texture emoji{ U"🐈"_emoji };
// 絵文字を描画する座標
Vec2 emojiPos{ 300, 150 };
// テキストを画面にデバッグ出力
Print << U"Push [A] key";
while (System::Update())
{
// テクスチャを描く
texture.draw(200, 200);
// テキストを画面の中心に描く
font(U"Hello, Siv3D!🚀").drawAt(Scene::Center(), Palette::Black);
// サイズをアニメーションさせて絵文字を描く
emoji.resized(100 + Periodic::Sine0_1(1s) * 20).drawAt(emojiPos);
// マウスカーソルに追随する半透明な円を描く
Circle{ Cursor::Pos(), 40 }.draw(ColorF{ 1, 0, 0, 0.5 });
// もし [A] キーが押されたら
if (KeyA.down())
{
// 選択肢からランダムに選ばれたメッセージをデバッグ表示
Print << Sample({ U"Hello!", U"こんにちは", U"你好", U"안녕하세요?" });
}
// もし [Button] が押されたら
if (SimpleGUI::Button(U"Button", Vec2{ 640, 40 }))
{
// 画面内のランダムな場所に座標を移動
emojiPos = RandomVec2(Scene::Rect());
}
}
}
WebGPU バックエンドと WebGL バックエンドの性能比較
OpenSiv3D for Web v0.6.3 のサンプルを このページ において、 WebGL2 バックエンド、WebGPU バックエンド別に掲載してあります。
手元の環境での性能比較のまとめ
以下は手元の環境 (MacBook Air, 2015) での動作比較です。
- WebGL/WebGPU バックエンドの差を感じられるサンプルはあまりありませんでした
- GPU 負荷の特に高いサンプルでは、フレームレートの向上がみられます
- SivSky を使うサンプルでは、WebGL バックエンドでは 40fps 程度しかでなかったのが、WebGPU バックエンドでは 60fps までフレームレートが改善しました
- CPU と GPU のデータのやり取りが多いサンプルでも、WebGPU バックエンドで負荷が小さくなるわけではありませんでした
- データコピーに
GPUQueue.writeBuffer
を使っているため? - これは、将来のリリースで改善される可能性があります。
- データコピーに
参考程度に、EmpoweredAudio、GeoJson、Test3DSky のパフォーマンスインスペクタのスクリーンショットと簡単な考察を以下に掲載します。
EmpoweredAudio
ほとんど差を感じられませんでした。
WebGL バックエンド
WebGPU バックエンド
GeoJson
若干 WebGPU バックエンドの方がもたついているように感じられました。
WebGL バックエンド
WebGPU バックエンド
Test3DSky
WebGPU バックエンドの方で CPU 負荷が上昇していますが、安定してフレームレートを保てています。