メモです。
所感
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
ファイルをモジュールとして参照できます(実際には置換マクロです)
#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 ~ 3
の範囲で作る。 -
-1 ~ 1
は矩形領域となるので、それに合わせてtexcoord
を変換する。
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を付けることによって、より詳細にどのタイミングでエラーが出たのかを知ることができます。
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 }
})
}