$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門し...
Search
にー兄さん
September 30, 2023
Technology
0
940
軽率にBabylon.jsの WebGPUエンジンを使って ComputeShaderに入門した / learn-about-babylonjs-webgpu-computeshader
IwakenLab Shaderこんな感じ発表会#2
にー兄さん
September 30, 2023
Tweet
Share
More Decks by にー兄さん
See All by にー兄さん
XRエンジニアの視点から XRのイマと社会実装の実現について考える / thinking-about-xr-popularization
drumath2237
0
27
軽率にプログラミング言語のシンタックスについて考えてみよう / lets-think-about-programming-lang-syntax
drumath2237
0
72
エンジニアが軽率に趣味から始める、OSS貢献を軸とした個人活動 / oss-contribution-as-a-hoby-project
drumath2237
0
42
Babylon.js 8.0のアプデ情報を 軽率にキャッチアップ / catch-up-babylonjs-8
drumath2237
0
250
フォークギター with VFXの 制作を軽率に振り返ろう! / look back fork guitar with vfx
drumath2237
0
54
軽率に始まった Babylon.js勉強会運営の 1年間をふりかえって / look back babylonjs japan activity
drumath2237
0
90
利己的利他、 あるいは軽率2.0に備えよ。 / prepare-for-keisotsu-2.0
drumath2237
0
66
軽率にAndroidXRのJetpack SceneCoreを使って3Dモデルを表示してみる / androidxr-scenecore-3dmodels
drumath2237
0
160
あなたの知らないWebXR Device APIの話を軽率に / about-webxr-device-api-you-dont-know
drumath2237
0
97
Other Decks in Technology
See All in Technology
翻訳・対話・越境で強いチームワークを作ろう! / Building Strong Teamwork through Interpretation, Dialogue, and Border-Crossing
ar_tama
0
130
Codeer.LowCode.Blazor 紹介と成長録
wadawada
0
110
AI 時代のデータ戦略
na0
3
610
TypeScript×CASLでつくるSaaSの認可 / Authz with CASL
saka2jp
2
160
How native lazy objects will change Doctrine and Symfony forever
beberlei
1
170
ローカルLLM基礎知識 / local LLM basics 2025
kishida
25
11k
[続・営業向け 誰でも話せるOCI セールストーク] AWSよりOCIの優位性が分からない編(2025年11月21日開催)
oracle4engineer
PRO
1
150
ブラウザ拡張のセキュリティの話 / Browser Extension Security
flatt_security
0
210
20251127 BigQueryリモート関数で作る、お手軽AIバッチ実行環境
daimatz
0
330
マルチドライブアーキテクチャ: 複数の駆動力でプロダクトを前進させる
knih
0
12k
段階的に進める、 挫折しない自宅サーバ入門
yu_kod
4
1.6k
pmconf 2025 大阪「生成AI時代に未来を切り開くためのプロダクト戦略:圧倒的生産性を実現するためのプロダクトサイクロン」 / The Product Cyclone for Outstanding Productivity
yamamuteki
3
2.9k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
54k
Rails Girls Zürich Keynote
gr2m
95
14k
Embracing the Ebb and Flow
colly
88
4.9k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Optimizing for Happiness
mojombo
379
70k
Practical Orchestrator
shlominoach
190
11k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Raft: Consensus for Rubyists
vanstee
140
7.2k
A better future with KSS
kneath
239
18k
Typedesign – Prime Four
hannesfritz
42
2.9k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
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