本セッションの登壇者
セッション動画
みなさん、こんにちは。@emadurandalと申します。今回は「WebGLと比較して学ぶWebGPU」と題して発表させていただきます。
私自身の紹介についてですが、私は2015年ごろにWebGLにはじめて触れて、それ以来3Dライブラリ開発をずっとやっています。Rhodoniteというライブラリを開発して、長らくWeb3Dの情報を発信しています。現在は株式会社HIKKYで、WebGLベースのメタバースプラットフォームの開発に従事しています。
こちらの3Dエンジンは、妹尾さんという方をメインアーキテクトとした「VketCloud」という新世代のエンジンを使っています。C++を使ってWebGLを操るというけっこうめずらしいエンジンです。ご興味のある方はぜひ応募してみてください。

WebGPU − あるべきGPUの状態を最初に作り置きする
さて、今回は「WebGPUとは」ということで説明させていただきます。WebGPUはWebブラウザ向けの新しい低レベル3D APIです。WebGLよりもGPUの構造に近いAPI体系で、より高速に動作します。そして、WebGLにはなかったCompute Shaderという汎用計算を行うためのシェーダを使うことができます。

まず、今までのWebGLにはパフォーマンス上の問題が存在していました。GPUには描画を行うためにいろいろな状態を設定しないといけないのですが、今までのWebGLでは、ドローコールなどを呼ばないとあるべきGPUの状態を最終的に決定できません。gl.drawElements
などのドローコールを毎フレーム呼ぶときにボトルネックが発生するという問題が存在していました。

一方、新しいWebGPUではあるべきGPUの状態をあらかじめ作り置きして何回も使い回すことができます。このあるべきGPU状態をまとめて保存したものをPipeline State Object、WebGPUの名前ではGPURenderPipelineといいます。右側にコードを示していますが、赤字で示した createRenderPipeline
という関数で作ることができます。

右側の今までのWebGLでは、gl.createShader
、gl.attachShader
、gl.useProgram
など、いろいろな関数を五月雨式に毎回呼ぶ必要があり、複雑な内部処理を長い時間をかけて行って、あるべきGPU状態がようやく決まります。WebGPUではあらかじめ作り置いたものを必要なときにすばやく設定してすぐに反映できます。そのため高速になります。

もう少し深堀りすると、左側に示したWebGPUのGPUPrimitiveStateにはGPUが描画を走らせるための状態、triangle-list(赤字)がありますが、右側のWebGLでは、それをドローコールの赤字部分まで来てようやく指定します。このことがボトルネックの一因となります。

Compute ShaderによるScatter / 必要なオブジェクトの明示的な指定
WebGPUにはまた、Compute ShaderというGPUを使った汎用計算のための仕組みがあります。WebGLでも限定的に可能だったのですが、WebGLではデータのGatherはできてもScatterができないという欠点がありました。Scatterとは複数の異なる箇所に一気にデータを書き込むことです。WebGPUのほうではこれをできるようになっているのが大きな違いです。

また、WebGPUでは、WebGLよりも多少長い行数が必要ですが、WebGLのような gl.bind~~
という関数を使わずに必要なオブジェクトを明示的に指定できます。WebGLではコードブロックを超えたところで状態管理が発生してしまいますが、それがないので非常にわかりやすいしくみになっています。

参考資料を示します。一番下のサンプルコードが非常にわかりやすいです。

ブラウザではこのように表示できるようになっています。

以上です。ご清聴ありがとうございました。
