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に入門し...
Search
にー兄さん
September 30, 2023
Technology
0
760
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門した / learn-about-babylonjs-webgpu-computeshader
IwakenLab Shaderこんな感じ発表会#2
にー兄さん
September 30, 2023
Tweet
Share
More Decks by にー兄さん
See All by にー兄さん
UnJSを使って軽率にCLIを作ってみたらめちゃくちゃ便利だった / create CLI with UnJS
drumath2237
4
1.4k
create-babylon-appを軽率にアプデしたい / update create babylon app
drumath2237
1
1.5k
Babylon.js 7注目機能を 軽率にまとめてみる/whats-new-in-babylonjs-v7
drumath2237
1
310
軽率にVFX Graphと Compute Shaderを 組み合わせるテクニック/integrate-vfxgraph-and-compute-shader
drumath2237
1
380
軽率にVue 3で リアルタイム3Dアプリを作れる ライブラリを作ってみた/vue-with-3d-app
drumath2237
3
1.9k
軽率にBabylon.jsを C#で使う技術 / using-babylonjs-with-csharp
drumath2237
1
840
今こそ軽率に理解したい WebXR Device APIとBabylon.jsの話 / understand-webxr-device-api-and-babylonjs
drumath2237
0
210
Vue・Babylon連携ライブラリ BabyuewJSについて / about-babyuewjs
drumath2237
0
180
Snapdragon Spacesを通して Unity XRプラグインフレームワーク について軽率に学ぶ / about snapdragon spaces sdk and unity xr framework
drumath2237
0
920
Other Decks in Technology
See All in Technology
Classmethod AI Talks(CATs) #14 司会進行スライド(2025.01.31) / classmethod-ai-talks-aka-cats_moderator-slides_vol14_2025-01-31
shinyaa31
0
120
Kubernetesでメールの大量配信をしている話/k8sjp-20250205
hfukamachi
0
340
AIをプロダクトに実装するならAPIで分離しよう 〜タクシーアプリ『GO』のアーキテクチャ実例紹介〜
74th
2
140
家電アプリ共通PF "Linova" のAPI利用とPostman活用事例ご紹介
yukiogawa
0
110
EDRからERM: PFN-SIRTが関わるセキュリティとリスクへの取り組み
pfn
PRO
0
150
The 5 Obstacles to High-Performing Teams
mdalmijn
0
240
アーキテクチャわからん、の話
shirayanagiryuji
0
280
滅・サービスクラス🔥 / Destruction Service Class
sinsoku
2
340
君はPostScriptなウィンドウシステム 「NeWS」をご存知か?/sunnews
koyhoge
0
680
Fintech SREの挑戦 PCI DSS対応をスマートにこなすインフラ戦略/Fintech SRE’s Challenge: Smart Infrastructure Strategies for PCI DSS Compliance
maaaato
0
400
Platform Engineeringは自由のめまい
nwiizo
1
120
AIプロダクト開発から得られた知見 - 2025年1月版
takaakikakei
0
180
Featured
See All Featured
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Writing Fast Ruby
sferik
628
61k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
31
2.1k
What's in a price? How to price your products and services
michaelherold
244
12k
Thoughts on Productivity
jonyablonski
69
4.4k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
The World Runs on Bad Software
bkeepers
PRO
67
11k
KATA
mclloyd
29
14k
Being A Developer After 40
akosma
89
590k
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