Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門した / learn-about-babylonjs-webgpu-computeshader
Search
にー兄さん
September 30, 2023
Technology
0
390
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門した / learn-about-babylonjs-webgpu-computeshader
IwakenLab Shaderこんな感じ発表会#2
にー兄さん
September 30, 2023
Tweet
Share
More Decks by にー兄さん
See All by にー兄さん
Babylon.js 7注目機能を 軽率にまとめてみる/whats-new-in-babylonjs-v7
drumath2237
1
53
軽率にVFX Graphと Compute Shaderを 組み合わせるテクニック/integrate-vfxgraph-and-compute-shader
drumath2237
1
56
軽率にVue 3で リアルタイム3Dアプリを作れる ライブラリを作ってみた/vue-with-3d-app
drumath2237
3
1.5k
軽率にBabylon.jsを C#で使う技術 / using-babylonjs-with-csharp
drumath2237
1
380
今こそ軽率に理解したい WebXR Device APIとBabylon.jsの話 / understand-webxr-device-api-and-babylonjs
drumath2237
0
31
Vue・Babylon連携ライブラリ BabyuewJSについて / about-babyuewjs
drumath2237
0
81
Snapdragon Spacesを通して Unity XRプラグインフレームワーク について軽率に学ぶ / about snapdragon spaces sdk and unity xr framework
drumath2237
0
390
Babylon.jsユーザのためのCLIを軽率にnpmで公開した話 / about create babylon app CLI
drumath2237
0
540
軽率な執筆活動 / writing books roughly
drumath2237
0
34
Other Decks in Technology
See All in Technology
Taking Flight with Tailwind CSS
opdavies
0
4.3k
Gemini in Android Studio
devpicon
0
110
生成AIがもたらす変革 / GitHubGalaxy_CyberAgent
cyberagentdevelopers
PRO
2
310
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
5
38k
[2024년 5월 세미나] 생성형 AI와 함께하는 데이터 분석가 커리어
datarian
0
1.4k
DatabricksにおけるRAGの実践
taka_aki
1
180
気が付いたらJSTQB AL TAに合格していた。そんな旅がしたいの。
bun913
2
130
大規模言語モデル (LLM)における低精度数値表現
pfn
PRO
3
900
AWSだ! Google Cloudだ! Azureだ! 認証連携だ!
ken5scal
4
620
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
3
1.2k
SLOいつ決めましょう?
abnoumaru
3
930
WACATE流 勉強会会場の選び方 / WACATE venue
nihonbuson
1
110
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
60
4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
84
45k
Building Your Own Lightsaber
phodgson
100
5.7k
Being A Developer After 40
akosma
67
580k
KATA
mclloyd
16
12k
Teambox: Starting and Learning
jrom
128
8.4k
Designing for Performance
lara
601
67k
Facilitating Awesome Meetings
lara
43
5.6k
Navigating Team Friction
lara
179
13k
Embracing the Ebb and Flow
colly
80
4.2k
Optimizing for Happiness
mojombo
371
69k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
14
8.4k
Transcript
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門した Shaderってこんな感じ発表会 #2 にー兄さん(@ninisan_drumath)
にー兄さん(@ninisan_drumath) ソフトウェアエンジニア 株式会社ホロラボ / IwakenLab Unity / ロケーションベースAR / WebAR
/ Babylon.js / Azure Kinect 最新技術を使った検証開発や デモンストレーションが好き 唐突な うちの猫たち→
本日の話: 「WebGPUのComputeShaderって こんな感じ」 Babylon.jsの
アジェンダ - WebGPUとかWGSLとかComputeShaderとか - Babylon.jsでもComputeShaderが使いたい - おわりに
WebGPUとかWGSLとか ComputeShaderとか
WebGPUとは① ブラウザ向けグラフィクスAPIの一種 従来はWebGL・WebGL2などがあり、 WebGL2が主流になろうとしている(ここの温度感あってる?) 今年の5月くらいにPC向けGoogle Chrome 113から 特殊な設定なしで利用できるように
WebGPUとは② 嬉しいところ - 低レベルなAPIを採用され、処理効率が向上 - モダングラフィクスAPIの流れを汲んでいる - コンピュートシェーダが使える これからに期待 -
2023年現在 使える環境が限られている - WebXRでは使えない、はず(要出典)
WGSL WebGPUで採用されているシェーダ言語 Rustっぽい構文 下記はCYOSで生成されたコードの比較(少し調整済み) #version 300 es precision highp float;
in vec3 position; uniform mat4 worldViewProjection; out vec4 vPosition; void main() { vec4 p = vec4(position, 1.f); vPosition = p; gl_Position = worldViewProjection * p; } #include<sceneUboDeclaration> #include<meshUboDeclaration> attribute position : vec3<f32>; varying vPosition : vec4<f32>; @vertex fn main(input: VertexInputs) -> FragmentInputs { let p = vec4<f32>(vertexInputs.position, 1.0); vertexOutputs.vPosition = p; vertexOutputs.position = scene.viewProjection * mesh.world * p; } WGSL GLSL
Compute Shader 汎用的な計算をGPUで行うための仕組み つまりGPGPU(General Purpose GPU) WebGL系ではこの仕組みが無かったので vertex/fragmentシェーダで実現していた WebGPUには標準搭載されており、WGSLで書ける
Babylon.jsでも ComputeShaderが使いたい
完成イメージ
どんなものを作るか GPUパーティクルを意識して 大量のオブジェクトの属性計算をGPGPUで処理したい (今回は90,000パーティクル) 平面上のランダムな位置にパーティクル位置を初期化 StorageBufferにPositionの配列を格納 3D Sin Waveを適用(dispatch) PointsCloudSystemにPosition配列を適用
時間によってアニメーションさせて上記処理を繰り返す
環境 - Windows 10 Home - Google Chrome 117 -
Babylon.js 6.7.0 - WebGPU Engine使用 - Vite + TypeScript - もし素でWebGPUをTSで開発する場合 @webgpu/typesに型定義があります - Babylon.jsでは不要です サンプルはGitHubで公開しています(docs整備中) https://github.com/drumath2237/babylon-compute-shader-sandbox
Babylon.jsにおけるWebGPUとComputeShader WebGPUは ほぼフルサポート 一部機能は動かないらしい 基本的にEngineをWebGPUEngineに差し替えれば 既存のWebGLアプリから移行できる const engine = new WebGPUEngine(renderCanvas,
{ antialias: true, }); await engine.initAsync(); ComputeShaderはWebGPUエンジンでのみ使用可能 > Note that in Babylon.js this is a WebGPU feature only (starting at v5.0), WebGL does not support compute shaders.
ComputeShaderを書く(3dSinWave.wgsl) struct Params { time: f32 } @group(0) @binding(0) var<uniform>
params : Params; @group(0) @binding(1) var<storage,read_write> positionBuffer : array<f32>; @compute @workgroup_size(2,1,1) fn main(@builtin(global_invocation_id) global_id: vec3<u32>) { var particleId = global_id.x * u32(300) + global_id.y; var x = positionBuffer[particleId * u32(3)]; var z = positionBuffer[particleId * u32(3) + u32(2)]; var distance = sqrt(x * x + z * z); positionBuffer[particleId * u32(3) + u32(1)] = sin(distance * 1.2 - params.time); } 拡張機能を入れれば VSCodeで普通に書ける
ComputeShaderインスタンスの作成 Compute Shaderのコードと bindingsのLayoutを定義して インスタンス化 const sinWaveComputeShader = new ComputeShader(
"3d sin wave", engine, { computeSource: computeShaderSource }, { bindingsMapping: { params: { group: 0, binding: 0 }, positionBuffer: { group: 0, binding: 1 }, }, } );
UniformBufferを作成 プリミティブな値は UniformBufferとして渡している 時間によるアニメーションのための float32を渡して更新する let time = 5; const
waveParamsUniformBuffer = new UniformBuffer( engine, undefined, undefined, "params" ); waveParamsUniformBuffer.addUniform("time", 1); waveParamsUniformBuffer.updateFloat("time", time); sinWaveComputeShader.setUniformBuffer( "params", waveParamsUniformBuffer );
Position配列の初期化とStorageBufferの作成 PointCloudSystemと Compute Shaderの相互で 参照するPosition配列(Float32Array) ComputeShaderには StorageBufferに変換して渡している const positionBuffer =
new Float32Array(PARTICLE_COUNT * 3); for (let i = 0; i < PARTICLE_COUNT; i++) { positionBuffer[i * 3] = randomNumberBetween(-10, 10); positionBuffer[i * 3 + 1] = 0; positionBuffer[i * 3 + 2] = randomNumberBetween(-10, 10); } const positionStorage = new StorageBuffer( engine, positionBuffer.byteLength ); positionStorage.update(positionBuffer); sinWaveComputeShader.setStorageBuffer( "positionBuffer", positionStorage);
繰り返しdispatch シーンのレンダリングループで 時間を更新して位置を再計算 dispatchのコスト高そうなので あまりよくない……? scene.registerBeforeRender(async () => { time
+= 0.1; waveParamsUniformBuffer.updateFloat("time", time); waveParamsUniformBuffer.update(); await sinWaveComputeShader.dispatchWhenReady( PARTICLE_ONE_SIDE, PARTICLE_ONE_SIDE ); const res = await positionStorage.read(); positionBuffer.set(new Float32Array(res.buffer)); pointCloud.setParticles(); });
完成
おわりに
まとめと感想 WebGPUのComputeShader気になっていたので 入門できてうれしい Babylon.jsだと普通に動くっぽいのでみんなでやろう
参考 WebGPUがついに利用可能に WebGL以上の高速な描画と、計算処理への可能性 https://ics.media/entry/230426/ IwakenLabShader勉強会でBabylon.jsにおけるComputeShaderでGPUパーティクルを行うデモの準備 https://zenn.dev/drumath2237/scraps/082ff30318fb2e WGSL 仕様メモ https://ikorin2.hatenablog.jp/entry/2023/04/23/213426 Compute
Shaders | Babylon.js Documentation https://doc.babylonjs.com/features/featuresDeepDive/materials/shaders/computeShader