|
31 | 31 | <script type="module"> |
32 | 32 |
|
33 | 33 | import * as THREE from 'three/webgpu'; |
34 | | - import { Fn, If, uniform, float, uv, vec3, hash, shapeCircle, |
| 34 | + import { Fn, If, Switch, uniform, float, uv, vec2, vec3, hash, shapeCircle, storage, |
35 | 35 | instancedArray, instanceIndex } from 'three/tsl'; |
36 | 36 |
|
37 | 37 | import { Inspector } from 'three/addons/inspector/Inspector.js'; |
38 | 38 |
|
39 | 39 | import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; |
40 | 40 |
|
41 | | - const particleCount = 200000; |
| 41 | + const particleCount = 200_000; |
| 42 | + const movableParticleCount = particleCount / 2; |
42 | 43 |
|
43 | 44 | const gravity = uniform( - .00098 ); |
44 | 45 | const bounce = uniform( .8 ); |
|
186 | 187 |
|
187 | 188 | // |
188 | 189 |
|
| 190 | + const movableParticleIndirectBuffer = new THREE.IndirectStorageBufferAttribute(new Uint32Array(3)); |
| 191 | + const movableParticleBufferNode = storage( movableParticleIndirectBuffer, 'uint' ); |
| 192 | + |
| 193 | + const computeMovableCount = Fn( () => { |
| 194 | + |
| 195 | + If( instanceIndex.lessThan( 3 ), () => { |
| 196 | + const count = movableParticleBufferNode.element(instanceIndex); |
| 197 | + |
| 198 | + Switch(instanceIndex) |
| 199 | + .Case(0, () => count.assign(Math.ceil(movableParticleCount / 64))) |
| 200 | + .Case(1, () => count.assign(1)) |
| 201 | + .Case(2, () => count.assign(1)); |
| 202 | + }) |
| 203 | + |
| 204 | + } )().compute( 3 ); |
| 205 | + |
| 206 | + renderer.computeAsync( computeMovableCount ); |
| 207 | + |
189 | 208 | function onMove( event ) { |
190 | 209 |
|
191 | 210 | if ( isOrbitControlsActive ) return; |
|
207 | 226 |
|
208 | 227 | // compute |
209 | 228 |
|
210 | | - renderer.compute( computeHit ); |
| 229 | + renderer.compute( computeHit, movableParticleIndirectBuffer ); |
211 | 230 |
|
212 | 231 | } |
213 | 232 |
|
|
0 commit comments