3
4

【WebGPU】メモ

Posted at

メモです。

所感

WebGPUを勉強していると「お前に私が使いこなせるかな?」と問われている感じになる。

学習サイト

最初にこちらの記事で、大まかな雰囲気を掴んで、
WebGPUでガチリアルタイムレンダリングの世界が見えてきた
WebGLからWebGPUにステップアップしよう!

こちらで手を動かして実践します。
WebGPU入門

そして、こちらを読み込むのが良さそうです。
WebGPU Fundamentals

実装サンプルはこちら。
WebGPU Samples

周辺ライブラリ

Typescript Type Definitions for WebGPU

Typescriptを使用する場合に、現在(2024.10.06時点)ではWebGPUの型定義がされていないので、こちらを使用して型情報を追加してあげる必要があります。

webgpu-utils

Attribute,Uniform,Textureなどの生成や設定(特にメモリレイアウト)を簡潔にしてくれるライブラリ。

wgpu-matrix

WebGPUで使える、MatrixやVector等を揃えたライブラリ。WebGLで言うところのgl-matrixです。

ほとんどの他の3D数学ライブラリは、WebGL向けに設計されており、WebGPUには最適化されていません。WebGPUはクリップ空間のZ軸が0から1の範囲であるのに対し、WebGLでは-1から1の範囲です。そのため、正射影、透視投影、視錐体の計算が異なります。また、WebGPUのmat3は12の浮動小数点数(パディングあり)で構成されているのに対し、WebGLでは9の浮動小数点数です。
wgpu-matrix README 抜粋

vite-plugin-glsl

開発環境にViteを使う場合は、こちらのプラグインを使うことによって、shader内で他のwgslファイルをモジュールとして参照できます(実際には置換マクロです)

.wgsl
#include './noise.wgsl'

@frangmet fn fs(@location(0) uv: vec2f) -> @location(0) vec4f {
  let color: vec3f = noise(uv, time);
  return vec4f(color, 1.0);
}

shaderファイルをstringとしてimportする機能も備えています。
ただ、それをしたいだけであれば、プラグインは使わずに?rawを付けるだけでOK。

import shader from './hoge.wgsl?raw';

WebGPUをいつ学ぶのか

2024.10.06現在、WebGPU自体まだSafariやFirefoxが対応できていないので、学ぶのはもう少し後でもいいかもしれません。

ただ、WebGL API(の使い方的なところ)や、3DCGの考え方をまったく知らない人が、WebGPUからいきなり学習を始めるのは、WebGLから学習を始めるよりはるかに難易度が高いと思います。(他に、GPU APIを使った経験があれば別です)

今後、数年内にWebGPUはモダンブラウザで全サポートされて、徐々にWebGL < WebGPUとなっていくでしょう。そうなったときに、WebGPUを勉強するためにWebGLから勉強するのは、非効率だしモチベもわかないと思います。
なので、Webでの3DCG表現や、GPUをつかった計算(compute shaderを使った機械学習)に興味があれば、今からWebGLを学んでおくのがいいと思います。

幸いWebGLであれば、ネット上にたくさんの情報があり、またオンラインスクールや講座もあるので、学ぶ環境がかなり整っていると思います。

毎年開催されているWebGLスクールがおすすめです。(※講師の方が事実上毎年やられていますが、そう決めているわけではないみたいです。なので、開催されなくても悪しからず)
挑戦することからすべては始まる! WebGL スクール第11期募集開始(リモート開催)(2024年開催分)

日本語の講座ではないですが、Three.jsの↓の講座もおすすめです。
Three.js Journey

Tips

画面いっぱいに面を張る(ポストプロセスとかで使う)

もはや、頂点属性すらいらない。

  1. 三角形を-1 ~ 3の範囲で作る。
  2. -1 ~ 1は矩形領域となるので、それに合わせてtexcoordを変換する。
.wgsl
struct VSOut {
  @builtin(position) position: vec4f,
  @location(0) texcoord: vec2f,
}

@vertex fn vs(@builtin(vertex_index) vertexIndex: u32) -> VSOut {
  let pos = array(
    vec2f(-1, -1),
    vec2f( 3, -1),
    vec2f(-1,  3),
  );

  var out: VSOut;
  let xy = pos[vertexIndex];
  out.position = vec4f(xy, 0, 1);
  out.texcoord = (xy + 1.0) / 4.0 * 2.0;
  return out;
}

@fragment fn fs(in: VSOut) -> @location(0) vec4f {
  return vec4f(in.texcoord, 0.0, 1.0);
}

エラー表示

WebGLより手厚い印象あがります。WebGLのようにエラーハンドリングしなくても、エラーが起きた場所を教えてくれます。

また、device.create***系の関数では、labelを付けることができます。labelを付けることによって、より詳細にどのタイミングでエラーが出たのかを知ることができます。

.ts
const pipelineA = createPipeline(layoutA, sourceA, 'A');
const pipelineB = createPipeline(layoutB, sourceB, 'B');

function createPipeline(layout: GPUPipelineLayout, source: string, name?: string) {
  const shaderModule = device.createShaderModule({
    label: `create shader module ${name}.`, 
    code: source 
  })
  return device.createComputePipeline({ 
    label: `create pipeline ${name}.`, 
    layout, 
    compute: { module: shaderModule } 
  })
}
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4