@woosh/meep-engine 3.17.1 → 3.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editor/actions/concrete/ComponentAddAction.d.ts +1 -0
- package/editor/actions/concrete/ComponentAddAction.d.ts.map +1 -1
- package/editor/actions/concrete/ComponentAddAction.js +4 -0
- package/editor/actions/concrete/ComponentRemoveAction.d.ts +1 -0
- package/editor/actions/concrete/ComponentRemoveAction.d.ts.map +1 -1
- package/editor/actions/concrete/ComponentRemoveAction.js +4 -0
- package/editor/actions/concrete/EntityCreateAction.d.ts +1 -0
- package/editor/actions/concrete/EntityCreateAction.d.ts.map +1 -1
- package/editor/actions/concrete/EntityCreateAction.js +7 -0
- package/editor/actions/concrete/EntityRemoveAction.d.ts +1 -0
- package/editor/actions/concrete/EntityRemoveAction.d.ts.map +1 -1
- package/editor/actions/concrete/EntityRemoveAction.js +4 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.d.ts +10 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.d.ts.map +1 -1
- package/editor/actions/concrete/PatchTerrainHeightAction.js +107 -85
- package/editor/actions/concrete/TransformModifyAction.d.ts +1 -0
- package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
- package/editor/actions/concrete/TransformModifyAction.js +4 -0
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
- package/editor/particles/effect/ParticleEffectDocument.js +10 -6
- package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
- package/editor/particles/effect/ParticleReferenceSimulation.js +98 -4
- package/editor/particles/effect/make_starter_particle_effect.d.ts.map +1 -1
- package/editor/particles/effect/make_starter_particle_effect.js +0 -2
- package/editor/tools/engine/ToolEngine.d.ts +30 -0
- package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
- package/editor/tools/engine/ToolEngine.js +257 -188
- package/editor/view/ecs/EntityList.d.ts.map +1 -1
- package/editor/view/ecs/EntityList.js +6 -5
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +17 -9
- package/package.json +1 -1
- package/src/CODEC_LAYOUT_VERIFICATION.md +1 -2
- package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts +56 -0
- package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts.map +1 -0
- package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.js +73 -0
- package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.d.ts.map +1 -1
- package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +18 -63
- package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts +53 -0
- package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts.map +1 -0
- package/src/core/binary/meshopt/meshopt_encode_byte_group.js +140 -0
- package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts +32 -0
- package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts.map +1 -0
- package/src/core/binary/meshopt/meshopt_encode_data_block.js +77 -0
- package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts +46 -0
- package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts.map +1 -0
- package/src/core/binary/meshopt/meshopt_encode_index_sequence.js +146 -0
- package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts +40 -0
- package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts.map +1 -0
- package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.js +700 -0
- package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts +24 -0
- package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts.map +1 -0
- package/src/core/binary/meshopt/meshopt_write_uint_var.js +39 -0
- package/src/core/math/random/seededRandom_Mulberry32.d.ts.map +1 -1
- package/src/core/math/random/seededRandom_Mulberry32.js +4 -2
- package/src/core/process/undo/Action.d.ts +19 -0
- package/src/core/process/undo/Action.d.ts.map +1 -1
- package/src/core/process/undo/Action.js +17 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +78 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +310 -0
- package/src/engine/graphics3/GraphicsEngine.d.ts +17 -0
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine.js +30 -10
- package/src/engine/graphics3/particles/particle_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/particles/particle_gpu_records.js +0 -2
- package/src/engine/interpolation/InterpolationSystem.d.ts +7 -0
- package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
- package/src/engine/interpolation/InterpolationSystem.js +10 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +14 -34
- package/src/engine/network/time/RenderPlayout.d.ts +76 -0
- package/src/engine/network/time/RenderPlayout.d.ts.map +1 -0
- package/src/engine/network/time/RenderPlayout.js +163 -0
- package/src/engine/network/transport/adapters/WebSocketTransport.d.ts.map +1 -1
- package/src/engine/network/transport/adapters/WebSocketTransport.js +11 -4
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +4 -12
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +39 -13
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
- package/src/engine/sound/simulation/core/VolumeField.js +4 -1
- package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +23 -2
- package/src/shade/playground/particle_system/README.md +139 -139
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +0 -2
- package/src/shade/playground/particle_system/particle_scene.d.ts +6 -9
- package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_scene.js +6 -13
- package/src/shade/playground/ssr_reprojection/README.md +103 -0
- package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts +17 -0
- package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts.map +1 -0
- package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +68 -0
- package/src/shade/playground/ssr_reprojection/index.html +79 -0
- package/src/shade/playground/ssr_reprojection/main.d.ts +2 -0
- package/src/shade/playground/ssr_reprojection/main.d.ts.map +1 -0
- package/src/shade/playground/ssr_reprojection/main.js +245 -0
- package/src/shade/playground/ssr_reprojection/scene.d.ts +18 -0
- package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -0
- package/src/shade/playground/ssr_reprojection/scene.js +51 -0
- package/src/shade/renderer/Renderer.d.ts +2 -23
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +185 -218
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +5 -8
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +12 -12
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +6 -0
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +7 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts +4 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.js +51 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.js +5 -35
- package/src/shade/renderer/particles/DESIGN.md +703 -514
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +16 -4
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1189 -991
- package/src/shade/renderer/particles/ParticleConstants.d.ts +64 -0
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +71 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts +57 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +181 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts +7 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts.map +1 -0
- package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.js +12 -0
- package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts +33 -0
- package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/bounds/graph_particle_bounds.js +67 -0
- package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts +40 -0
- package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/bounds/shader_particle_bounds.js +187 -0
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +15 -2
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +14 -8
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +58 -4
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +79 -4
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts +23 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.js +35 -2
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +4 -2
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +5 -8
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/particle_emitter_record.js +0 -6
- package/src/shade/renderer/particles/graph_particles.d.ts +25 -3
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +108 -31
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts +6 -4
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +5 -5
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +5 -0
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +27 -6
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +4 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +6 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +35 -27
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +424 -425
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +20 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +4 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +38 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts +22 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.js +42 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.js +53 -22
- package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.js +213 -216
- package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +50 -0
- package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_render.js +1 -1
- package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts +36 -0
- package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.js +102 -0
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts +102 -0
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +329 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts +112 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup.js +318 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts +35 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +108 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts +3 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +70 -0
- package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts +62 -0
- package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts.map +1 -0
- package/src/shade/renderer/particles/warmup/warmup_schedule.js +55 -0
- package/src/shade/renderer/postprocess/PostProcess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/PostProcess.js +2 -1
- package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +286 -0
- package/src/shade/renderer/postprocess/ssr/SSR.d.ts +57 -21
- package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/SSR.js +230 -129
- package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts +11 -0
- package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.js +6 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts +4 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.js +32 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts +4 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.js +41 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts +3 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +30 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts +4 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +70 -0
- package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts +21 -0
- package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.js +363 -0
- package/src/shade/renderer/postprocess/ssr/resolve/chunk_get_neighbour_weight.js +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts +2 -0
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.js +24 -0
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts +1 -6
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +16 -332
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts +1 -6
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +25 -358
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -5
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +201 -276
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts +1 -0
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +167 -143
- package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts +15 -0
- package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts.map +1 -0
- package/src/shade/renderer/shader/graph/graph_create_buffer.js +20 -0
- package/src/shade/renderer/view/GPUViewContext.d.ts +3 -4
- package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
- package/src/shade/renderer/view/GPUViewContext.js +5 -5
- package/src/core/binary/meshopt/__meshopt_test_streams.d.ts +0 -24
- package/src/core/binary/meshopt/__meshopt_test_streams.d.ts.map +0 -1
- package/src/core/binary/meshopt/__meshopt_test_streams.js +0 -237
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +0 -84
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +0 -1
- package/src/core/geom/3d/atlas/atlas_test_fixtures.js +0 -266
- package/src/engine/asset/loaders/gltf_test_fixtures.d.ts +0 -97
- package/src/engine/asset/loaders/gltf_test_fixtures.d.ts.map +0 -1
- package/src/engine/asset/loaders/gltf_test_fixtures.js +0 -359
- package/src/engine/sound/simulation/core/OcclusionSolver.d.ts +0 -29
- package/src/engine/sound/simulation/core/OcclusionSolver.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_test_fixtures.d.ts +0 -86
- package/src/shade/renderer/animation/skin_test_fixtures.d.ts.map +0 -1
- package/src/shade/renderer/animation/skin_test_fixtures.js +0 -250
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts +0 -16
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +0 -27
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts +0 -151
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +0 -1
- package/src/shade/renderer/particles/particle_test_fixtures.js +0 -229
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js +0 -23
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +0 -457
|
@@ -30,6 +30,70 @@ export const PARTICLE_RECORD_HEADER_EMITTER: number;
|
|
|
30
30
|
* @type {number}
|
|
31
31
|
*/
|
|
32
32
|
export const PARTICLE_EMITTER_TICK_WORKGROUP_SIZE: number;
|
|
33
|
+
/**
|
|
34
|
+
* Most ticks a warm-up runs an emitter's simulation forward in, whatever it owes — see `warmup/`.
|
|
35
|
+
*
|
|
36
|
+
* A warm-up is the ordinary loop (spawn, init, advance) run over a transient population until the
|
|
37
|
+
* emitter has been running for its `prewarm`. Each tick is a handful of dispatches, so this bounds
|
|
38
|
+
* the frame that pays for it; the tick length stretches to cover the debt rather than the count
|
|
39
|
+
* growing to cover it ({@link ./warmup/warmup_schedule.js}). Thirty-two ticks of a three-second
|
|
40
|
+
* warm-up are ninety-millisecond steps — coarse, and smeared by the jitter below so it does not
|
|
41
|
+
* read as thirty-two bands; a stiff program will not reproduce under it and nothing here claims to.
|
|
42
|
+
*
|
|
43
|
+
* @type {number}
|
|
44
|
+
*/
|
|
45
|
+
export const PARTICLE_WARMUP_MAX_TICKS: number;
|
|
46
|
+
/**
|
|
47
|
+
* Shortest a warm-up tick gets, in seconds — a frame at sixty. A warm-up shorter than
|
|
48
|
+
* {@link PARTICLE_WARMUP_MAX_TICKS} of these runs fewer ticks rather than finer ones: there is nothing
|
|
49
|
+
* to be gained from integrating a two-hundred-millisecond warm-up at a finer grain than the frame
|
|
50
|
+
* loop will from then on.
|
|
51
|
+
*
|
|
52
|
+
* @type {number}
|
|
53
|
+
*/
|
|
54
|
+
export const PARTICLE_WARMUP_TICK_SECONDS: number;
|
|
55
|
+
/**
|
|
56
|
+
* How far a warm-up tick's length is jittered per particle, as a fraction of the tick: each
|
|
57
|
+
* particle advances by `dt * (1 + this * (u - 0.5))` for a `u` hashed from its slot and the tick.
|
|
58
|
+
*
|
|
59
|
+
* Without it every particle born in one tick has exactly the age of that tick at the end, and a
|
|
60
|
+
* warm-up of N ticks arrives as N cohorts — visible banding on exactly the effects that wanted
|
|
61
|
+
* warming. A program does not care what `DELTA_TIME` it is handed, so the smear is free. Half a
|
|
62
|
+
* tick each way is enough to close the gaps between cohorts and not enough to reorder them.
|
|
63
|
+
*
|
|
64
|
+
* @type {number}
|
|
65
|
+
*/
|
|
66
|
+
export const PARTICLE_WARMUP_DT_JITTER: number;
|
|
67
|
+
/**
|
|
68
|
+
* Per-emitter counterpart of {@link PARTICLE_WARMUP_DT_JITTER}: an emitter's own clock runs at
|
|
69
|
+
* `1 + this * (u - 0.5)` times the tick, for a `u` the host hashes from its row. Two emitters warmed
|
|
70
|
+
* in the same batch then do not spawn on the same beat, which is what aligns their bands with each
|
|
71
|
+
* other even after the per-particle smear has hidden each one's own.
|
|
72
|
+
*
|
|
73
|
+
* @type {number}
|
|
74
|
+
*/
|
|
75
|
+
export const PARTICLE_WARMUP_EMITTER_JITTER: number;
|
|
76
|
+
/**
|
|
77
|
+
* Words per entry of the warm-up queue the host hands the GPU: see
|
|
78
|
+
* {@link ./warmup/shader_particle_warmup.js WARMUP_QUEUE_ENTRY}.
|
|
79
|
+
* @type {number}
|
|
80
|
+
*/
|
|
81
|
+
export const PARTICLE_WARMUP_QUEUE_WORDS: number;
|
|
82
|
+
/**
|
|
83
|
+
* Lanes the warm-up's per-particle passes launch. A bounded launch with a grid-stride loop, so the
|
|
84
|
+
* loop's passes are sized by a constant rather than by a count that changes every tick and would
|
|
85
|
+
* otherwise need an indirect-args pass of its own per tick. Equal to
|
|
86
|
+
* {@link PARTICLE_VM_WIDE_LAUNCH_LANES} so that the wide register file, sized by that, fits the
|
|
87
|
+
* warm-up's wide advance pass without a second file.
|
|
88
|
+
*
|
|
89
|
+
* @type {number}
|
|
90
|
+
*/
|
|
91
|
+
export const PARTICLE_WARMUP_LAUNCH_LANES: number;
|
|
92
|
+
/**
|
|
93
|
+
* Threads per workgroup in the warm-up passes.
|
|
94
|
+
* @type {number}
|
|
95
|
+
*/
|
|
96
|
+
export const PARTICLE_WARMUP_WORKGROUP_SIZE: number;
|
|
33
97
|
/**
|
|
34
98
|
* Words per entry of the spawn-command list the host hands the GPU: `[emitter row, count]`.
|
|
35
99
|
* @type {number}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticleConstants.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/ParticleConstants.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,yCAFU,MAAM,CAE6B;AAE7C;;;;GAIG;AACH,6CAFU,MAAM,CAEgC;AAEhD;;;;;;GAMG;AACH,mDAFU,MAAM,CAEuC;AAEvD;;;GAGG;AACH,2CAFU,MAAM,CAE8B;AAE9C;;;;;;;;;GASG;AACH,4CAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,8CAFU,MAAM,CAEiC;AAEjD;;;;;;GAMG;AACH,yCAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,8CAFU,MAAM,CAEiC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,yCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,8CAFU,MAAM,CAEkC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,4CAFU,MAAM,CAEkC;;AASlD;;;;;;;;;;;;;;;GAeG;AACH,2CAFU,MAAM,CAEiC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,+CAFU,MAAM,CAEmC;AAEnD;;;;;;;;;;;;GAYG;AACH,oCAFU,MAAM,CAEgC;AAEhD;;;;;;;;;;GAUG;AACH,uCAFU,MAAM,CAE4B"}
|
|
1
|
+
{"version":3,"file":"ParticleConstants.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/ParticleConstants.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,yCAFU,MAAM,CAE6B;AAE7C;;;;GAIG;AACH,6CAFU,MAAM,CAEgC;AAEhD;;;;;;GAMG;AACH,mDAFU,MAAM,CAEuC;AAEvD;;;;;;;;;;;GAWG;AACH,wCAFU,MAAM,CAE4B;AAE5C;;;;;;;GAOG;AACH,2CAFU,MAAM,CAEmC;AAEnD;;;;;;;;;;GAUG;AACH,wCAFU,MAAM,CAE6B;AAE7C;;;;;;;GAOG;AACH,6CAFU,MAAM,CAEkC;AAElD;;;;GAIG;AACH,0CAFU,MAAM,CAE6B;AAE7C;;;;;;;;GAQG;AACH,2CAFU,MAAM,CAEiC;AAEjD;;;GAGG;AACH,6CAFU,MAAM,CAEiC;AAEjD;;;GAGG;AACH,2CAFU,MAAM,CAE8B;AAE9C;;;;;;;;;GASG;AACH,4CAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,8CAFU,MAAM,CAEiC;AAEjD;;;;;;GAMG;AACH,yCAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,8CAFU,MAAM,CAEiC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,yCAFU,MAAM,CAE8B;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,8CAFU,MAAM,CAEkC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,4CAFU,MAAM,CAEkC;;AASlD;;;;;;;;;;;;;;;GAeG;AACH,2CAFU,MAAM,CAEiC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,+CAFU,MAAM,CAEmC;AAEnD;;;;;;;;;;;;GAYG;AACH,oCAFU,MAAM,CAEgC;AAEhD;;;;;;;;;;GAUG;AACH,uCAFU,MAAM,CAE4B"}
|
|
@@ -34,6 +34,77 @@ export const PARTICLE_RECORD_HEADER_EMITTER = 0;
|
|
|
34
34
|
*/
|
|
35
35
|
export const PARTICLE_EMITTER_TICK_WORKGROUP_SIZE = 64;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Most ticks a warm-up runs an emitter's simulation forward in, whatever it owes — see `warmup/`.
|
|
39
|
+
*
|
|
40
|
+
* A warm-up is the ordinary loop (spawn, init, advance) run over a transient population until the
|
|
41
|
+
* emitter has been running for its `prewarm`. Each tick is a handful of dispatches, so this bounds
|
|
42
|
+
* the frame that pays for it; the tick length stretches to cover the debt rather than the count
|
|
43
|
+
* growing to cover it ({@link ./warmup/warmup_schedule.js}). Thirty-two ticks of a three-second
|
|
44
|
+
* warm-up are ninety-millisecond steps — coarse, and smeared by the jitter below so it does not
|
|
45
|
+
* read as thirty-two bands; a stiff program will not reproduce under it and nothing here claims to.
|
|
46
|
+
*
|
|
47
|
+
* @type {number}
|
|
48
|
+
*/
|
|
49
|
+
export const PARTICLE_WARMUP_MAX_TICKS = 32;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Shortest a warm-up tick gets, in seconds — a frame at sixty. A warm-up shorter than
|
|
53
|
+
* {@link PARTICLE_WARMUP_MAX_TICKS} of these runs fewer ticks rather than finer ones: there is nothing
|
|
54
|
+
* to be gained from integrating a two-hundred-millisecond warm-up at a finer grain than the frame
|
|
55
|
+
* loop will from then on.
|
|
56
|
+
*
|
|
57
|
+
* @type {number}
|
|
58
|
+
*/
|
|
59
|
+
export const PARTICLE_WARMUP_TICK_SECONDS = 1 / 60;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* How far a warm-up tick's length is jittered per particle, as a fraction of the tick: each
|
|
63
|
+
* particle advances by `dt * (1 + this * (u - 0.5))` for a `u` hashed from its slot and the tick.
|
|
64
|
+
*
|
|
65
|
+
* Without it every particle born in one tick has exactly the age of that tick at the end, and a
|
|
66
|
+
* warm-up of N ticks arrives as N cohorts — visible banding on exactly the effects that wanted
|
|
67
|
+
* warming. A program does not care what `DELTA_TIME` it is handed, so the smear is free. Half a
|
|
68
|
+
* tick each way is enough to close the gaps between cohorts and not enough to reorder them.
|
|
69
|
+
*
|
|
70
|
+
* @type {number}
|
|
71
|
+
*/
|
|
72
|
+
export const PARTICLE_WARMUP_DT_JITTER = 0.5;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Per-emitter counterpart of {@link PARTICLE_WARMUP_DT_JITTER}: an emitter's own clock runs at
|
|
76
|
+
* `1 + this * (u - 0.5)` times the tick, for a `u` the host hashes from its row. Two emitters warmed
|
|
77
|
+
* in the same batch then do not spawn on the same beat, which is what aligns their bands with each
|
|
78
|
+
* other even after the per-particle smear has hidden each one's own.
|
|
79
|
+
*
|
|
80
|
+
* @type {number}
|
|
81
|
+
*/
|
|
82
|
+
export const PARTICLE_WARMUP_EMITTER_JITTER = 0.1;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Words per entry of the warm-up queue the host hands the GPU: see
|
|
86
|
+
* {@link ./warmup/shader_particle_warmup.js WARMUP_QUEUE_ENTRY}.
|
|
87
|
+
* @type {number}
|
|
88
|
+
*/
|
|
89
|
+
export const PARTICLE_WARMUP_QUEUE_WORDS = 4;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Lanes the warm-up's per-particle passes launch. A bounded launch with a grid-stride loop, so the
|
|
93
|
+
* loop's passes are sized by a constant rather than by a count that changes every tick and would
|
|
94
|
+
* otherwise need an indirect-args pass of its own per tick. Equal to
|
|
95
|
+
* {@link PARTICLE_VM_WIDE_LAUNCH_LANES} so that the wide register file, sized by that, fits the
|
|
96
|
+
* warm-up's wide advance pass without a second file.
|
|
97
|
+
*
|
|
98
|
+
* @type {number}
|
|
99
|
+
*/
|
|
100
|
+
export const PARTICLE_WARMUP_LAUNCH_LANES = 8192;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Threads per workgroup in the warm-up passes.
|
|
104
|
+
* @type {number}
|
|
105
|
+
*/
|
|
106
|
+
export const PARTICLE_WARMUP_WORKGROUP_SIZE = 64;
|
|
107
|
+
|
|
37
108
|
/**
|
|
38
109
|
* Words per entry of the spawn-command list the host hands the GPU: `[emitter row, count]`.
|
|
39
110
|
* @type {number}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-emitter bounds accumulator: where a measured box is built up, and how it is read back.
|
|
3
|
+
*
|
|
4
|
+
* An emitter has no bounds it could declare. Its particles are simulated in world space by arbitrary
|
|
5
|
+
* bytecode — they go where the program sends them, at whatever size it gives them, for as long as it
|
|
6
|
+
* keeps them alive — so the only bound an author could write down and still be right is an infinite
|
|
7
|
+
* one, which culls nothing and reserves every depth slice. What CAN be known is where the particles
|
|
8
|
+
* actually are, and that is what the two passes in {@link ./shader_particle_bounds.js} measure.
|
|
9
|
+
*
|
|
10
|
+
* One accumulator per emitter table row, six words of the counters buffer (see
|
|
11
|
+
* {@link ../data/PARTICLE_COUNTERS.js} for why it lives there rather than in a binding of its own),
|
|
12
|
+
* holding `min.xyz` then `max.xyz` as plain f32 bit patterns.
|
|
13
|
+
*
|
|
14
|
+
* ## Why f32 in the buffer, and not an order-preserving encoding
|
|
15
|
+
*
|
|
16
|
+
* `aabb_atomic_min_f32` / `aabb_atomic_max_f32` are the engine's, shared with the skinned-mesh
|
|
17
|
+
* bounds refresh, and they CAS-spin over the plain float so the words are readable as floats at
|
|
18
|
+
* every moment of the frame. The sign-flip encoding that would let `atomicMin` do it in one
|
|
19
|
+
* instruction leaves the buffer in a form only a decoder understands, and the publish pass reads
|
|
20
|
+
* these words in the same frame the accumulate pass writes them.
|
|
21
|
+
*
|
|
22
|
+
* The spin is cheaper than it looks at particle counts: both helpers load first and return without a
|
|
23
|
+
* CAS when the box already holds the contribution. It is the record-breaking argument — over `n`
|
|
24
|
+
* particles in arbitrary order, the number that actually extend an axis is `O(log n)` in
|
|
25
|
+
* expectation, so `n` threads produce `n` loads and a handful of exchanges per word rather than `n`
|
|
26
|
+
* of each. What is left is the load traffic, and a subgroup reduction ahead of the atomic is the
|
|
27
|
+
* lever if it ever matters; the pass is separate partly so there is somewhere to pull it.
|
|
28
|
+
*
|
|
29
|
+
* ## What this chunk needs from its shader
|
|
30
|
+
*
|
|
31
|
+
* The `counters` binding, by that name and read-write, the way
|
|
32
|
+
* {@link ../shaders/chunk_particle_billboard_vertex.js} takes `pool` and `camera`. Both bounds
|
|
33
|
+
* passes bind it — that is the point of the accumulator living there.
|
|
34
|
+
*
|
|
35
|
+
* @type {CodeChunk}
|
|
36
|
+
*/
|
|
37
|
+
export const chunk_particle_bounds_store: CodeChunk;
|
|
38
|
+
/**
|
|
39
|
+
* One live particle's contribution to its emitter's box: where its quad is, and how far the quad
|
|
40
|
+
* reaches from there.
|
|
41
|
+
*
|
|
42
|
+
* Read in exactly the terms {@link ../shaders/chunk_particle_billboard_vertex.js} reads a particle
|
|
43
|
+
* in — same record offsets, same defaults for an unbound channel, same radius as the corner
|
|
44
|
+
* expansion it performs — because the box has to hold what is drawn, not what is simulated. An
|
|
45
|
+
* emitter with no `position` binding really does draw every particle at the world origin, and this
|
|
46
|
+
* really does book the origin for it; the box stays a true statement about where the quads are, and
|
|
47
|
+
* an author who sees their effect culled at the origin has been told something accurate about their
|
|
48
|
+
* bindings.
|
|
49
|
+
*
|
|
50
|
+
* Five words of a record, no VM and no scene: that is the whole reason the measurement is a pass of
|
|
51
|
+
* its own rather than a tail on `particle_simulate_one`.
|
|
52
|
+
*
|
|
53
|
+
* @type {CodeChunk}
|
|
54
|
+
*/
|
|
55
|
+
export const chunk_particle_bounds_of_record: CodeChunk;
|
|
56
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
57
|
+
//# sourceMappingURL=chunk_particle_bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_particle_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/chunk_particle_bounds.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,0CAFU,SAAS,CAwEyC;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,8CAFU,SAAS,CA4CsC;0BApL/B,oCAAoC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_aabb_atomic_f32 } from "../../animation/skinning/bounds_refresh/chunk_aabb_atomic_f32.js";
|
|
3
|
+
import { AABB3_STRUCT } from "../../shader/chunk/geometry/aabb3/AABB3_STRUCT.js";
|
|
4
|
+
import {
|
|
5
|
+
PARTICLE_BOUNDS_BASE,
|
|
6
|
+
PARTICLE_BOUNDS_MINUS_INF,
|
|
7
|
+
PARTICLE_BOUNDS_PLUS_INF,
|
|
8
|
+
PARTICLE_BOUNDS_WORDS,
|
|
9
|
+
} from "../data/PARTICLE_COUNTERS.js";
|
|
10
|
+
import { EMITTER_ATTRIBUTE_ABSENT } from "../data/PARTICLE_EMITTER_STRUCT.js";
|
|
11
|
+
import { chunk_particle_emitter } from "../data/chunk_particle_emitter.js";
|
|
12
|
+
import { chunk_particle_render_math } from "../shaders/chunk_particle_render_math.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The per-emitter bounds accumulator: where a measured box is built up, and how it is read back.
|
|
16
|
+
*
|
|
17
|
+
* An emitter has no bounds it could declare. Its particles are simulated in world space by arbitrary
|
|
18
|
+
* bytecode — they go where the program sends them, at whatever size it gives them, for as long as it
|
|
19
|
+
* keeps them alive — so the only bound an author could write down and still be right is an infinite
|
|
20
|
+
* one, which culls nothing and reserves every depth slice. What CAN be known is where the particles
|
|
21
|
+
* actually are, and that is what the two passes in {@link ./shader_particle_bounds.js} measure.
|
|
22
|
+
*
|
|
23
|
+
* One accumulator per emitter table row, six words of the counters buffer (see
|
|
24
|
+
* {@link ../data/PARTICLE_COUNTERS.js} for why it lives there rather than in a binding of its own),
|
|
25
|
+
* holding `min.xyz` then `max.xyz` as plain f32 bit patterns.
|
|
26
|
+
*
|
|
27
|
+
* ## Why f32 in the buffer, and not an order-preserving encoding
|
|
28
|
+
*
|
|
29
|
+
* `aabb_atomic_min_f32` / `aabb_atomic_max_f32` are the engine's, shared with the skinned-mesh
|
|
30
|
+
* bounds refresh, and they CAS-spin over the plain float so the words are readable as floats at
|
|
31
|
+
* every moment of the frame. The sign-flip encoding that would let `atomicMin` do it in one
|
|
32
|
+
* instruction leaves the buffer in a form only a decoder understands, and the publish pass reads
|
|
33
|
+
* these words in the same frame the accumulate pass writes them.
|
|
34
|
+
*
|
|
35
|
+
* The spin is cheaper than it looks at particle counts: both helpers load first and return without a
|
|
36
|
+
* CAS when the box already holds the contribution. It is the record-breaking argument — over `n`
|
|
37
|
+
* particles in arbitrary order, the number that actually extend an axis is `O(log n)` in
|
|
38
|
+
* expectation, so `n` threads produce `n` loads and a handful of exchanges per word rather than `n`
|
|
39
|
+
* of each. What is left is the load traffic, and a subgroup reduction ahead of the atomic is the
|
|
40
|
+
* lever if it ever matters; the pass is separate partly so there is somewhere to pull it.
|
|
41
|
+
*
|
|
42
|
+
* ## What this chunk needs from its shader
|
|
43
|
+
*
|
|
44
|
+
* The `counters` binding, by that name and read-write, the way
|
|
45
|
+
* {@link ../shaders/chunk_particle_billboard_vertex.js} takes `pool` and `camera`. Both bounds
|
|
46
|
+
* passes bind it — that is the point of the accumulator living there.
|
|
47
|
+
*
|
|
48
|
+
* @type {CodeChunk}
|
|
49
|
+
*/
|
|
50
|
+
export const chunk_particle_bounds_store = CodeChunk.from(/* language=wgsl */ `
|
|
51
|
+
const PARTICLE_BOUNDS_BASE : u32 = ${PARTICLE_BOUNDS_BASE}u;
|
|
52
|
+
const PARTICLE_BOUNDS_WORDS : u32 = ${PARTICLE_BOUNDS_WORDS}u;
|
|
53
|
+
|
|
54
|
+
// The empty interval, as bit patterns because WGSL has no literal for either infinity. The same two
|
|
55
|
+
// words the host writes over a newly grown region, from the same constants.
|
|
56
|
+
const PARTICLE_BOUNDS_PLUS_INF : u32 = ${PARTICLE_BOUNDS_PLUS_INF}u;
|
|
57
|
+
const PARTICLE_BOUNDS_MINUS_INF : u32 = ${PARTICLE_BOUNDS_MINUS_INF}u;
|
|
58
|
+
|
|
59
|
+
fn particle_bounds_base(row : u32) -> u32 {
|
|
60
|
+
return PARTICLE_BOUNDS_BASE + row * PARTICLE_BOUNDS_WORDS;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Book one particle's quad into its emitter's accumulator: the sphere of radius \`radius\` about
|
|
64
|
+
// \`center\`, as an axis-aligned box.
|
|
65
|
+
//
|
|
66
|
+
// A sphere rather than the quad itself because the quad's plane is the camera's, and this box is
|
|
67
|
+
// read on a later frame with the camera somewhere else. See \`particle_billboard_radius\`.
|
|
68
|
+
fn particle_bounds_contribute(row : u32, center : vec3<f32>, radius : f32) {
|
|
69
|
+
let base = particle_bounds_base(row);
|
|
70
|
+
|
|
71
|
+
let lo = center - vec3<f32>(radius);
|
|
72
|
+
let hi = center + vec3<f32>(radius);
|
|
73
|
+
|
|
74
|
+
aabb_atomic_min_f32(&counters[base + 0u], lo.x);
|
|
75
|
+
aabb_atomic_min_f32(&counters[base + 1u], lo.y);
|
|
76
|
+
aabb_atomic_min_f32(&counters[base + 2u], lo.z);
|
|
77
|
+
aabb_atomic_max_f32(&counters[base + 3u], hi.x);
|
|
78
|
+
aabb_atomic_max_f32(&counters[base + 4u], hi.y);
|
|
79
|
+
aabb_atomic_max_f32(&counters[base + 5u], hi.z);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// What the frame accumulated for one row. Empty (see \`particle_bounds_is_empty\`) when nothing
|
|
83
|
+
// contributed — the emitter had no live particles.
|
|
84
|
+
fn particle_bounds_read(row : u32) -> ${AABB3_STRUCT.wgsl_ref} {
|
|
85
|
+
let base = particle_bounds_base(row);
|
|
86
|
+
|
|
87
|
+
let lo = vec3<f32>(
|
|
88
|
+
bitcast<f32>(atomicLoad(&counters[base + 0u])),
|
|
89
|
+
bitcast<f32>(atomicLoad(&counters[base + 1u])),
|
|
90
|
+
bitcast<f32>(atomicLoad(&counters[base + 2u])),
|
|
91
|
+
);
|
|
92
|
+
let hi = vec3<f32>(
|
|
93
|
+
bitcast<f32>(atomicLoad(&counters[base + 3u])),
|
|
94
|
+
bitcast<f32>(atomicLoad(&counters[base + 4u])),
|
|
95
|
+
bitcast<f32>(atomicLoad(&counters[base + 5u])),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return ${AABB3_STRUCT.make({ min: "lo", max: "hi" })};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Start a row's next frame of measurement. All six axes are set together and no contribution ever
|
|
102
|
+
// touches one without the others, so "min above max on any axis" is exactly "nothing contributed".
|
|
103
|
+
//
|
|
104
|
+
// Unconditional in the publish pass, which is what lets a row that changes hands start clean: the
|
|
105
|
+
// last publish before it was freed left it empty, and it stays that way until somebody measures.
|
|
106
|
+
fn particle_bounds_reset(row : u32) {
|
|
107
|
+
let base = particle_bounds_base(row);
|
|
108
|
+
|
|
109
|
+
atomicStore(&counters[base + 0u], PARTICLE_BOUNDS_PLUS_INF);
|
|
110
|
+
atomicStore(&counters[base + 1u], PARTICLE_BOUNDS_PLUS_INF);
|
|
111
|
+
atomicStore(&counters[base + 2u], PARTICLE_BOUNDS_PLUS_INF);
|
|
112
|
+
atomicStore(&counters[base + 3u], PARTICLE_BOUNDS_MINUS_INF);
|
|
113
|
+
atomicStore(&counters[base + 4u], PARTICLE_BOUNDS_MINUS_INF);
|
|
114
|
+
atomicStore(&counters[base + 5u], PARTICLE_BOUNDS_MINUS_INF);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fn particle_bounds_is_empty(box : ${AABB3_STRUCT.wgsl_ref}) -> bool {
|
|
118
|
+
return any(box.min > box.max);
|
|
119
|
+
}
|
|
120
|
+
`, [chunk_aabb_atomic_f32, AABB3_STRUCT.declaration_chunk]);
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* One live particle's contribution to its emitter's box: where its quad is, and how far the quad
|
|
124
|
+
* reaches from there.
|
|
125
|
+
*
|
|
126
|
+
* Read in exactly the terms {@link ../shaders/chunk_particle_billboard_vertex.js} reads a particle
|
|
127
|
+
* in — same record offsets, same defaults for an unbound channel, same radius as the corner
|
|
128
|
+
* expansion it performs — because the box has to hold what is drawn, not what is simulated. An
|
|
129
|
+
* emitter with no `position` binding really does draw every particle at the world origin, and this
|
|
130
|
+
* really does book the origin for it; the box stays a true statement about where the quads are, and
|
|
131
|
+
* an author who sees their effect culled at the origin has been told something accurate about their
|
|
132
|
+
* bindings.
|
|
133
|
+
*
|
|
134
|
+
* Five words of a record, no VM and no scene: that is the whole reason the measurement is a pass of
|
|
135
|
+
* its own rather than a tail on `particle_simulate_one`.
|
|
136
|
+
*
|
|
137
|
+
* @type {CodeChunk}
|
|
138
|
+
*/
|
|
139
|
+
export const chunk_particle_bounds_of_record = CodeChunk.from(/* language=wgsl */ `
|
|
140
|
+
const PARTICLE_BOUNDS_ATTRIBUTE_ABSENT : u32 = ${EMITTER_ATTRIBUTE_ABSENT}u;
|
|
141
|
+
|
|
142
|
+
struct ParticleBoundsSample {
|
|
143
|
+
center : vec3<f32>,
|
|
144
|
+
radius : f32,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fn particle_bounds_read_vec3(pool : ptr<storage, array<u32>>, base : u32, offset : u32) -> vec3<f32> {
|
|
148
|
+
return vec3<f32>(
|
|
149
|
+
bitcast<f32>((*pool)[base + offset]),
|
|
150
|
+
bitcast<f32>((*pool)[base + offset + 1u]),
|
|
151
|
+
bitcast<f32>((*pool)[base + offset + 2u]),
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
fn particle_bounds_of_record(
|
|
156
|
+
em : ParticleEmitter,
|
|
157
|
+
pool : ptr<storage, array<u32>>,
|
|
158
|
+
record_base : u32,
|
|
159
|
+
) -> ParticleBoundsSample {
|
|
160
|
+
var center = vec3<f32>(0.0);
|
|
161
|
+
if (em.render_position != PARTICLE_BOUNDS_ATTRIBUTE_ABSENT) {
|
|
162
|
+
center = particle_bounds_read_vec3(pool, record_base, em.render_position);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
var size = 1.0;
|
|
166
|
+
if (em.render_size != PARTICLE_BOUNDS_ATTRIBUTE_ABSENT) {
|
|
167
|
+
size = bitcast<f32>((*pool)[record_base + em.render_size]);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
var velocity = vec3<f32>(0.0);
|
|
171
|
+
if (em.render_velocity != PARTICLE_BOUNDS_ATTRIBUTE_ABSENT) {
|
|
172
|
+
velocity = particle_bounds_read_vec3(pool, record_base, em.render_velocity);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
var sample : ParticleBoundsSample;
|
|
176
|
+
sample.center = center;
|
|
177
|
+
sample.radius = particle_billboard_radius(size, velocity, particle_emitter_projection(em.flags));
|
|
178
|
+
|
|
179
|
+
return sample;
|
|
180
|
+
}
|
|
181
|
+
`, [chunk_particle_emitter, chunk_particle_render_math]);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Infinite bounds mean no live particles have supplied a measurement. Test before any geometry
|
|
2
|
+
* arithmetic: multiplying infinity by a zero plane component or adding opposite infinities is NaN.
|
|
3
|
+
* @type {CodeChunk}
|
|
4
|
+
*/
|
|
5
|
+
export const chunk_particle_bounds_unknown: CodeChunk;
|
|
6
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
7
|
+
//# sourceMappingURL=chunk_particle_bounds_unknown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_particle_bounds_unknown.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,4CAFU,SAAS,CAOhB;0BAXuB,oCAAoC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/** Infinite bounds mean no live particles have supplied a measurement. Test before any geometry
|
|
4
|
+
* arithmetic: multiplying infinity by a zero plane component or adding opposite infinities is NaN.
|
|
5
|
+
* @type {CodeChunk}
|
|
6
|
+
*/
|
|
7
|
+
export const chunk_particle_bounds_unknown = CodeChunk.from(/* wgsl */ `
|
|
8
|
+
fn particle_bounds_unknown(bounds_min : vec3<f32>) -> bool {
|
|
9
|
+
// Compare stored bits: a constant bitcast to an infinite f32 is a WGSL creation error.
|
|
10
|
+
return bitcast<u32>(bounds_min.x) == 0xff800000u;
|
|
11
|
+
}
|
|
12
|
+
`);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frame-graph wiring for the measured emitter bounds: the frame's alive list reduced to one
|
|
3
|
+
* world-space box per emitter, published where the culling and occupancy passes read it.
|
|
4
|
+
*
|
|
5
|
+
* Runs at the end of the frame, after emit and simulate have both finished appending to the alive
|
|
6
|
+
* list and after the coherence reset has written `dispatch_args` from the resulting count. Two
|
|
7
|
+
* passes, in this order and no other: the accumulate has to see every live particle before the
|
|
8
|
+
* publish takes what it measured.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} params
|
|
11
|
+
* @param {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
|
|
12
|
+
* @param {number} params.emitter_database graph handle; the publish pass writes the state rows
|
|
13
|
+
* @param {number} params.pool graph handle of the particle pool
|
|
14
|
+
* @param {number} params.alive graph handle of this frame's compacted alive list
|
|
15
|
+
* @param {number} params.counters graph handle of the atomic counters, which carry the accumulator
|
|
16
|
+
* @param {number} params.dispatch_args graph handle of one workgroup per live particle
|
|
17
|
+
* @param {number} params.emitter_group_count workgroups that walk every page group of the emitter
|
|
18
|
+
* table; zero when the table has no pages, and then there is nothing to publish
|
|
19
|
+
* @returns {{counters: number, emitter_database: number}} the threaded handles downstream passes must read
|
|
20
|
+
*/
|
|
21
|
+
export function graph_particle_bounds({ graph, emitter_database, pool, alive, counters, dispatch_args, emitter_group_count, }: {
|
|
22
|
+
graph: import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
|
|
23
|
+
emitter_database: number;
|
|
24
|
+
pool: number;
|
|
25
|
+
alive: number;
|
|
26
|
+
counters: number;
|
|
27
|
+
dispatch_args: number;
|
|
28
|
+
emitter_group_count: number;
|
|
29
|
+
}): {
|
|
30
|
+
counters: number;
|
|
31
|
+
emitter_database: number;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=graph_particle_bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph_particle_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/graph_particle_bounds.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAVqG,KAAK,EAA/F,OAAO,8DAA8D,EAAE,UAAU;IAClE,gBAAgB,EAA/B,MAAM;IACS,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,aAAa,EAA5B,MAAM;IACS,mBAAmB,EAAlC,MAAM;IAEJ;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAC,CAwCxD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { graph_compute_indirect_pass } from "../../shader/graph/compute/graph_compute_indirect_pass.js";
|
|
3
|
+
import { graph_compute_pass } from "../../shader/graph/compute/graph_compute_pass.js";
|
|
4
|
+
import {
|
|
5
|
+
shader_particle_bounds_accumulate,
|
|
6
|
+
shader_particle_bounds_publish,
|
|
7
|
+
} from "./shader_particle_bounds.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Frame-graph wiring for the measured emitter bounds: the frame's alive list reduced to one
|
|
11
|
+
* world-space box per emitter, published where the culling and occupancy passes read it.
|
|
12
|
+
*
|
|
13
|
+
* Runs at the end of the frame, after emit and simulate have both finished appending to the alive
|
|
14
|
+
* list and after the coherence reset has written `dispatch_args` from the resulting count. Two
|
|
15
|
+
* passes, in this order and no other: the accumulate has to see every live particle before the
|
|
16
|
+
* publish takes what it measured.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} params
|
|
19
|
+
* @param {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
|
|
20
|
+
* @param {number} params.emitter_database graph handle; the publish pass writes the state rows
|
|
21
|
+
* @param {number} params.pool graph handle of the particle pool
|
|
22
|
+
* @param {number} params.alive graph handle of this frame's compacted alive list
|
|
23
|
+
* @param {number} params.counters graph handle of the atomic counters, which carry the accumulator
|
|
24
|
+
* @param {number} params.dispatch_args graph handle of one workgroup per live particle
|
|
25
|
+
* @param {number} params.emitter_group_count workgroups that walk every page group of the emitter
|
|
26
|
+
* table; zero when the table has no pages, and then there is nothing to publish
|
|
27
|
+
* @returns {{counters: number, emitter_database: number}} the threaded handles downstream passes must read
|
|
28
|
+
*/
|
|
29
|
+
export function graph_particle_bounds({
|
|
30
|
+
graph,
|
|
31
|
+
emitter_database,
|
|
32
|
+
pool,
|
|
33
|
+
alive,
|
|
34
|
+
counters,
|
|
35
|
+
dispatch_args,
|
|
36
|
+
emitter_group_count,
|
|
37
|
+
}) {
|
|
38
|
+
assert.defined(graph, "graph");
|
|
39
|
+
assert.isNonNegativeInteger(emitter_group_count, "emitter_group_count");
|
|
40
|
+
|
|
41
|
+
if (emitter_group_count === 0) {
|
|
42
|
+
// No emitter table pages: no rows to accumulate into and none to publish. The alive list is
|
|
43
|
+
// empty for the same reason, so the accumulate pass would be a no-op even if it ran.
|
|
44
|
+
return { counters, emitter_database };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// One thread per live particle. Indirect, from the count the coherence reset read on the GPU —
|
|
48
|
+
// a host-side particle count is a frame stale at best.
|
|
49
|
+
const accumulated = graph_compute_indirect_pass({
|
|
50
|
+
graph,
|
|
51
|
+
shader: shader_particle_bounds_accumulate,
|
|
52
|
+
bindings: { emitter_database, pool, alive, counters },
|
|
53
|
+
command: dispatch_args,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const published = graph_compute_pass({
|
|
57
|
+
graph,
|
|
58
|
+
shader: shader_particle_bounds_publish,
|
|
59
|
+
bindings: { emitter_database, counters: accumulated.counters },
|
|
60
|
+
group_count: [emitter_group_count, 1, 1],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
counters: published.counters,
|
|
65
|
+
emitter_database: published.emitter_database,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One thread per live particle: merge its quad into its emitter's accumulator.
|
|
3
|
+
*
|
|
4
|
+
* The alive list holds real slots only — the padding sentinel belongs to the simulation-order list,
|
|
5
|
+
* and an orphan was killed by the simulate pass that built this list — so every entry is a particle
|
|
6
|
+
* whose emitter row is live and whose record has this frame's values in it.
|
|
7
|
+
*
|
|
8
|
+
* It decodes a whole emitter record to reach four of its fields, which the bucketing histogram
|
|
9
|
+
* deliberately does not (`chunk_particle_emitter_program_id`). The difference is what is being paid
|
|
10
|
+
* for: emitters are counted in tens, so the records are a working set that stays resident for the
|
|
11
|
+
* whole dispatch, while the pool reads are a gather over the free list and are what this pass costs.
|
|
12
|
+
* The billboard vertex stage reads a record the same way, per vertex.
|
|
13
|
+
*
|
|
14
|
+
* @type {ComputeShader}
|
|
15
|
+
*/
|
|
16
|
+
export const shader_particle_bounds_accumulate: ComputeShader;
|
|
17
|
+
/**
|
|
18
|
+
* One thread per emitter table row: publish what the accumulate pass measured into
|
|
19
|
+
* `bounds_min` / `bounds_max` of the emitter's state row, and reset the accumulator.
|
|
20
|
+
*
|
|
21
|
+
* The state row rather than the accumulator directly, because the readers — the tick's frustum test
|
|
22
|
+
* next frame, the AVBOIT occupancy later in this one — should not each have to know the
|
|
23
|
+
* accumulator's layout or repeat the empty case below. It is also where the rest of an emitter's
|
|
24
|
+
* GPU-owned state lives, for the reason {@link ../data/PARTICLE_EMITTER_STATE.js} gives.
|
|
25
|
+
*
|
|
26
|
+
* ## The empty case
|
|
27
|
+
*
|
|
28
|
+
* No measured particles means unknown bounds, represented by an infinite box. The tick lets such
|
|
29
|
+
* an emitter spawn until a finite population can be measured; occupancy skips it because there is
|
|
30
|
+
* nothing to splat. This also lets an exhausted effect restart without requiring authored bounds
|
|
31
|
+
* or prewarm. Readers recognize the sentinel before doing geometry arithmetic on infinities.
|
|
32
|
+
*
|
|
33
|
+
* @type {ComputeShader}
|
|
34
|
+
*/
|
|
35
|
+
export const shader_particle_bounds_publish: ComputeShader;
|
|
36
|
+
import { PARTICLE_SIMULATE_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
37
|
+
import { PARTICLE_EMITTER_TICK_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
38
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
39
|
+
export { PARTICLE_SIMULATE_WORKGROUP_SIZE, PARTICLE_EMITTER_TICK_WORKGROUP_SIZE };
|
|
40
|
+
//# sourceMappingURL=shader_particle_bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_particle_bounds.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/bounds/shader_particle_bounds.js"],"names":[],"mappings":"AA8DA;;;;;;;;;;;;;;GAcG;AACH,gDAFU,aAAa,CAgCpB;AAkBH;;;;;;;;;;;;;;;;;GAiBG;AACH,6CAFU,aAAa,CA6CpB;iDA/KI,yBAAyB;qDAAzB,yBAAyB;8BARF,+BAA+B"}
|