@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
|
@@ -1,216 +1,213 @@
|
|
|
1
|
-
import { atomic_u32, f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
-
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
3
|
-
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
4
|
-
import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
5
|
-
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
} from "../../shader/chunk/geometry/
|
|
10
|
-
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
11
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
12
|
-
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
13
|
-
import { PARTICLE_EMITTER_TICK_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The emitter tick: one thread per emitter table row, deciding how many particles each emitter
|
|
21
|
-
* spawns this frame. This is the pass that took spawning off the CPU — the host no longer walks the
|
|
22
|
-
* emitters, and no longer knows or cares how many there are.
|
|
23
|
-
*
|
|
24
|
-
* Per live row it:
|
|
25
|
-
*
|
|
26
|
-
* 1. picks up the row's GPU-owned state (the `emitter_state` table, see
|
|
27
|
-
* {@link ../data/PARTICLE_EMITTER_STATE.js}) — or starts it over, when the state's generation is
|
|
28
|
-
* not the record's, which is how both a brand-new row and a reused one are recognised without
|
|
29
|
-
* the CPU clearing anything;
|
|
30
|
-
* 2. takes whatever the spawn-command pass queued into `pending` (the CPU's bursts, and in time
|
|
31
|
-
* whatever a VM opcode asks for) into the accumulator;
|
|
32
|
-
* 3. if the emitter opts into culling, tests
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* 4. integrates `spawn_rate * dt`, and turns the whole part of the accumulator into this frame's
|
|
36
|
-
* count — clamped by the frame's spawn budget, which the reset pass seeded from the dead count,
|
|
37
|
-
* so an emitter is only ever debited for particles the pool can hold;
|
|
38
|
-
* 5. writes that count to `spawn_counts.elements[row]`.
|
|
39
|
-
*
|
|
40
|
-
* `spawn_counts` is the input of a prefix scan, and the scan's inclusive sums are what the emit
|
|
41
|
-
* pass expands: one thread per particle, each locating its emitter by binary search over the sums.
|
|
42
|
-
* That is the same shape the rasteriser uses to expand meshes into meshlets, and it is what makes
|
|
43
|
-
* the per-emitter count unbounded — no thread here loops over its particles.
|
|
44
|
-
*
|
|
45
|
-
* The rows are walked with the emitter table's page iterator, one page group per workgroup, so an
|
|
46
|
-
* unallocated page costs one word read and a freed row costs one bit test. The state rows live in
|
|
47
|
-
* the same database buffer, bound once and read-write, and are read and written whole: each row is
|
|
48
|
-
* one thread's, so nothing here needs an atomic. Rows the walk skips leave their count at zero,
|
|
49
|
-
* which is why the counts buffer is cleared before this runs. The scan's `count` header is written
|
|
50
|
-
* by the first thread, from the table's element capacity, which is the only number the host
|
|
51
|
-
* supplies.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
export { PARTICLE_EMITTER_TICK_WORKGROUP_SIZE };
|
|
1
|
+
import { atomic_u32, f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
3
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
4
|
+
import { CAMERA_UNIFORM_STRUCT } from "../../camera/CAMERA_UNIFORM_STRUCT.js";
|
|
5
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
6
|
+
import { AABB3_STRUCT } from "../../shader/chunk/geometry/aabb3/AABB3_STRUCT.js";
|
|
7
|
+
import {
|
|
8
|
+
chunk_aabb3_intersects_frustum
|
|
9
|
+
} from "../../shader/chunk/geometry/aabb3/chunk_aabb3_intersects_frustum.js";
|
|
10
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
11
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
12
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
13
|
+
import { PARTICLE_EMITTER_TICK_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
14
|
+
import { PARTICLE_EMITTER_DESCRIPTOR, PARTICLE_EMITTER_STATE_DESCRIPTOR } from "../data/PARTICLE_DATABASE_SPEC.js";
|
|
15
|
+
import { EMITTER_FLAG } from "../data/PARTICLE_EMITTER_STRUCT.js";
|
|
16
|
+
import { chunk_particle_spawn_budget } from "./chunk_particle_spawn_budget.js";
|
|
17
|
+
import { chunk_particle_bounds_unknown } from "../bounds/chunk_particle_bounds_unknown.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The emitter tick: one thread per emitter table row, deciding how many particles each emitter
|
|
21
|
+
* spawns this frame. This is the pass that took spawning off the CPU — the host no longer walks the
|
|
22
|
+
* emitters, and no longer knows or cares how many there are.
|
|
23
|
+
*
|
|
24
|
+
* Per live row it:
|
|
25
|
+
*
|
|
26
|
+
* 1. picks up the row's GPU-owned state (the `emitter_state` table, see
|
|
27
|
+
* {@link ../data/PARTICLE_EMITTER_STATE.js}) — or starts it over, when the state's generation is
|
|
28
|
+
* not the record's, which is how both a brand-new row and a reused one are recognised without
|
|
29
|
+
* the CPU clearing anything;
|
|
30
|
+
* 2. takes whatever the spawn-command pass queued into `pending` (the CPU's bursts, and in time
|
|
31
|
+
* whatever a VM opcode asks for) into the accumulator;
|
|
32
|
+
* 3. if the emitter opts into culling, tests the bounding box on its state row against the camera
|
|
33
|
+
* frustum; a culled emitter sleeps, accruing time it pays back as a bounded burst when it is
|
|
34
|
+
* next seen;
|
|
35
|
+
* 4. integrates `spawn_rate * dt`, and turns the whole part of the accumulator into this frame's
|
|
36
|
+
* count — clamped by the frame's spawn budget, which the reset pass seeded from the dead count,
|
|
37
|
+
* so an emitter is only ever debited for particles the pool can hold;
|
|
38
|
+
* 5. writes that count to `spawn_counts.elements[row]`.
|
|
39
|
+
*
|
|
40
|
+
* `spawn_counts` is the input of a prefix scan, and the scan's inclusive sums are what the emit
|
|
41
|
+
* pass expands: one thread per particle, each locating its emitter by binary search over the sums.
|
|
42
|
+
* That is the same shape the rasteriser uses to expand meshes into meshlets, and it is what makes
|
|
43
|
+
* the per-emitter count unbounded — no thread here loops over its particles.
|
|
44
|
+
*
|
|
45
|
+
* The rows are walked with the emitter table's page iterator, one page group per workgroup, so an
|
|
46
|
+
* unallocated page costs one word read and a freed row costs one bit test. The state rows live in
|
|
47
|
+
* the same database buffer, bound once and read-write, and are read and written whole: each row is
|
|
48
|
+
* one thread's, so nothing here needs an atomic. Rows the walk skips leave their count at zero,
|
|
49
|
+
* which is why the counts buffer is cleared before this runs. The scan's `count` header is written
|
|
50
|
+
* by the first thread, from the table's element capacity, which is the only number the host
|
|
51
|
+
* supplies.
|
|
52
|
+
*
|
|
53
|
+
* ## What it does not do
|
|
54
|
+
*
|
|
55
|
+
* It does not measure the box it culls with. An emitter has no bounds an author could declare, so
|
|
56
|
+
* they are measured from the live particles by a pass of their own at the end of the frame
|
|
57
|
+
* (`../bounds/`), which publishes into the same state row this reads. All that reaches here is the
|
|
58
|
+
* finished box and one frustum test — the emitter table is walked twice a frame rather than three
|
|
59
|
+
* times, and this pass stays about spawning.
|
|
60
|
+
*
|
|
61
|
+
* The box is therefore one frame old: it is over the particles that were alive when the last frame
|
|
62
|
+
* ended. That is the right staleness for what it decides. A wrongly culled emitter spawns nothing
|
|
63
|
+
* for a frame and is paid back by the wake-up catch-up; a wrongly woken one spawns particles it
|
|
64
|
+
* would have had a frame later anyway.
|
|
65
|
+
*
|
|
66
|
+
* A new row, and any row without measured live particles, is exempt from culling. Unknown bounds
|
|
67
|
+
* are an infinite box, recognized before the frustum math: even a sub-frame spawn rate must be able
|
|
68
|
+
* to accumulate its first particle when the emitter's origin is offscreen. Prewarm remains optional.
|
|
69
|
+
*
|
|
70
|
+
* @type {ComputeShader}
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
const GROUP_SIZE = PARTICLE_EMITTER_TICK_WORKGROUP_SIZE;
|
|
74
|
+
|
|
75
|
+
// The database is bound read-write (the state rows are written), so the iterator and the readers
|
|
76
|
+
// are the `_rw` variants: WGSL does not coerce access modes at a call site.
|
|
77
|
+
const PG = PARTICLE_EMITTER_DESCRIPTOR.page_iterator_symbol_prefix(GROUP_SIZE, true);
|
|
78
|
+
const STATE = PARTICLE_EMITTER_STATE_DESCRIPTOR;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Per-dispatch, 16 bytes, read-only.
|
|
82
|
+
*
|
|
83
|
+
* @type {WebGPUStruct}
|
|
84
|
+
*/
|
|
85
|
+
const TICK_SETTINGS = WebGPUStruct.from({
|
|
86
|
+
/** seconds */
|
|
87
|
+
u_dt: f32,
|
|
88
|
+
/** cap on how much missed time a wake-up burst covers, seconds */
|
|
89
|
+
u_max_catchup: f32,
|
|
90
|
+
/** pool capacity — the ceiling on the accumulator, and the wrap guard for the budget counter */
|
|
91
|
+
u_capacity: u32,
|
|
92
|
+
/** element capacity of the emitter table — the length of the counts list the scan consumes */
|
|
93
|
+
u_emitter_capacity: u32,
|
|
94
|
+
}, 'ParticleEmitterTickSettings');
|
|
95
|
+
|
|
96
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
97
|
+
|
|
98
|
+
resources.setImmediate('settings', TICK_SETTINGS);
|
|
99
|
+
|
|
100
|
+
resources.createGroup()
|
|
101
|
+
.addUniform("camera", CAMERA_UNIFORM_STRUCT)
|
|
102
|
+
.addStorageBuffer("emitter_database", WebGPUArray.u32, true)
|
|
103
|
+
.addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true)
|
|
104
|
+
.addStorageBuffer("spawn_counts", COLLECTION_U32_STRUCT_READ, true);
|
|
105
|
+
|
|
106
|
+
const body = CodeChunk.from(/* language=wgsl */ `
|
|
107
|
+
const EMITTER_FLAG_CULL : u32 = ${EMITTER_FLAG.CULL}u;
|
|
108
|
+
|
|
109
|
+
@compute @workgroup_size(${GROUP_SIZE}, 1, 1)
|
|
110
|
+
fn main(
|
|
111
|
+
@builtin(workgroup_id) wg_id : vec3<u32>,
|
|
112
|
+
@builtin(local_invocation_index) local_id : u32,
|
|
113
|
+
) {
|
|
114
|
+
// The scan reads exactly this many counts. Written before the page test so it lands even when
|
|
115
|
+
// page 0 is unallocated — an empty table still has to scan to a total of zero.
|
|
116
|
+
if (wg_id.x == 0u && local_id == 0u) {
|
|
117
|
+
spawn_counts.count = settings.u_emitter_capacity;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// page_address is uniform across the workgroup, so this branch is uniform.
|
|
121
|
+
if (!${PG}_setup(&emitter_database, wg_id.x, local_id)) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let slot_in_page = ${PG}_slot_in_page(local_id);
|
|
126
|
+
|
|
127
|
+
if (slot_in_page >= ${PG}_ELEMENTS_PER_PAGE || !${PG}_is_occupied(slot_in_page)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let em = ${PG}_read(&emitter_database, slot_in_page);
|
|
132
|
+
let row = ${PG}_slot_to_index(slot_in_page);
|
|
133
|
+
|
|
134
|
+
var state = ${STATE.marshalling_method_read_rw}(&emitter_database, row);
|
|
135
|
+
|
|
136
|
+
// Whatever the spawn-command pass queued since last tick. Taken before the generation test so a
|
|
137
|
+
// burst issued on the frame a row was (re)assigned is not lost with the stale state.
|
|
138
|
+
let pending = state.pending;
|
|
139
|
+
state.pending = 0u;
|
|
140
|
+
|
|
141
|
+
// A row this state has not seen: new emitter, or a reused row. Start from nothing.
|
|
142
|
+
let restarted = state.generation != em.generation;
|
|
143
|
+
|
|
144
|
+
if (restarted) {
|
|
145
|
+
state.generation = em.generation;
|
|
146
|
+
state.accumulator = 0.0;
|
|
147
|
+
state.age = 0.0;
|
|
148
|
+
state.sleep = 0.0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var accumulator = state.accumulator + f32(pending);
|
|
152
|
+
var sleep = state.sleep;
|
|
153
|
+
|
|
154
|
+
state.age = state.age + settings.u_dt;
|
|
155
|
+
|
|
156
|
+
var visible = true;
|
|
157
|
+
|
|
158
|
+
// \`restarted\` is what keeps a row's first tick out of this: nothing has measured it yet, and
|
|
159
|
+
// the box the CPU staged is not a statement about where the emitter is.
|
|
160
|
+
if (!restarted && !particle_bounds_unknown(state.bounds_min) && (em.flags & EMITTER_FLAG_CULL) != 0u) {
|
|
161
|
+
let box = ${AABB3_STRUCT.make({ min: "state.bounds_min", max: "state.bounds_max" })};
|
|
162
|
+
|
|
163
|
+
visible = aabb3_intersects_frustum(box, camera.frustum);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
var count = 0u;
|
|
167
|
+
|
|
168
|
+
if (visible) {
|
|
169
|
+
// Waking up: a bounded catch-up for the time spent culled, so a long occlusion cannot
|
|
170
|
+
// spike the pool on the frame the emitter comes back into view.
|
|
171
|
+
if (sleep > 0.0) {
|
|
172
|
+
accumulator = accumulator + em.spawn_rate * min(sleep, settings.u_max_catchup);
|
|
173
|
+
sleep = 0.0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
accumulator = accumulator + em.spawn_rate * settings.u_dt;
|
|
177
|
+
|
|
178
|
+
// A permanently over-subscribed emitter cannot grow its debt without limit.
|
|
179
|
+
accumulator = min(accumulator, f32(settings.u_capacity));
|
|
180
|
+
|
|
181
|
+
let wanted = u32(floor(accumulator));
|
|
182
|
+
|
|
183
|
+
if (wanted > 0u) {
|
|
184
|
+
count = particle_take_spawn_budget(wanted, settings.u_capacity);
|
|
185
|
+
accumulator = accumulator - f32(count);
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
sleep = sleep + settings.u_dt;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
spawn_counts.elements[row] = count;
|
|
192
|
+
|
|
193
|
+
state.accumulator = accumulator;
|
|
194
|
+
state.sleep = sleep;
|
|
195
|
+
${STATE.marshalling_method_write}(&emitter_database, row, state);
|
|
196
|
+
}
|
|
197
|
+
`, [
|
|
198
|
+
PARTICLE_EMITTER_DESCRIPTOR.chunk_iterate(GROUP_SIZE, true),
|
|
199
|
+
STATE.chunk_read_rw,
|
|
200
|
+
STATE.chunk_write,
|
|
201
|
+
chunk_particle_spawn_budget,
|
|
202
|
+
chunk_particle_bounds_unknown,
|
|
203
|
+
chunk_aabb3_intersects_frustum,
|
|
204
|
+
AABB3_STRUCT.declaration_chunk,
|
|
205
|
+
]);
|
|
206
|
+
|
|
207
|
+
export const shader_particle_emitter_tick = ComputeShader.from({
|
|
208
|
+
label: "Particle Emitter Tick",
|
|
209
|
+
resources,
|
|
210
|
+
body,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
export { PARTICLE_EMITTER_TICK_WORKGROUP_SIZE };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return to the free list the slots the emit pass's pre-warm killed.
|
|
3
|
+
*
|
|
4
|
+
* A newborn of a pre-warming emitter runs its UPDATE program forward before it is shown
|
|
5
|
+
* ({@link ./chunk_particle_emit_step.js}), and one whose life runs out during that never belongs on
|
|
6
|
+
* the alive list. Its slot has to go back to the free list, and this pass is where that happens.
|
|
7
|
+
*
|
|
8
|
+
* ## Why it is a pass of its own
|
|
9
|
+
*
|
|
10
|
+
* Because emit is the one pass that POPS the free list, and a push racing a pop on an array stack
|
|
11
|
+
* hands one slot to two particles.
|
|
12
|
+
*
|
|
13
|
+
* The pop is `old = atomicSub(DEAD, 1)` followed by a read of `dead[old - 1]`; a push would be
|
|
14
|
+
* `d = atomicAdd(DEAD, 1)` followed by a write to `dead[d]`. Order one thread's `atomicSub` before
|
|
15
|
+
* another's `atomicAdd` and the two name the same index, with nothing between the atomic and the
|
|
16
|
+
* plain access to order them. If the write lands first, the popper takes the pushed slot AND leaves
|
|
17
|
+
* it on the stack under a count that now includes it — so the next popper takes it again, and two
|
|
18
|
+
* live particles share one record. That is precisely the failure the build-indirect pass warns about
|
|
19
|
+
* for a different reason, and it is why the emit pass writes to `dead` nowhere: even its
|
|
20
|
+
* pool-exhaustion path only ever puts the counter back.
|
|
21
|
+
*
|
|
22
|
+
* Between two dispatches there is no such race. This pass only pushes; nothing in it pops.
|
|
23
|
+
*
|
|
24
|
+
* ## Where the slots are between the two
|
|
25
|
+
*
|
|
26
|
+
* At the far end of `alive_out`, growing down from `capacity`, counted by
|
|
27
|
+
* {@link PARTICLE_COUNTER.STILLBORN}. A region of a buffer emit already binds, rather than a list of
|
|
28
|
+
* its own: emit binds exactly the eight storage buffers a compute stage gets by default, and a ninth
|
|
29
|
+
* for a list that is empty on all but a handful of frames is not what the ninth is for.
|
|
30
|
+
*
|
|
31
|
+
* The park cannot collide with the alive list growing up from zero. Every entry in either is a
|
|
32
|
+
* distinct pool slot and a parked one is by definition not alive, so the two lengths sum to at most
|
|
33
|
+
* the `capacity` entries between them.
|
|
34
|
+
*
|
|
35
|
+
* ## Sizing
|
|
36
|
+
*
|
|
37
|
+
* A bounded launch with a grid-stride loop, the shape the wide interpreter uses and for the same
|
|
38
|
+
* reason: the length it walks is a GPU-side count. Nothing about it is sized from the host, and the
|
|
39
|
+
* dispatch costs one atomic load and an exit on the frames — nearly all of them — where nothing was
|
|
40
|
+
* parked.
|
|
41
|
+
*
|
|
42
|
+
* @type {ComputeShader}
|
|
43
|
+
*/
|
|
44
|
+
/** Workgroups this pass dispatches. Constant: the launch does not depend on how many slots were parked. */
|
|
45
|
+
export const PARTICLE_RECLAIM_WORKGROUP_COUNT: number;
|
|
46
|
+
export const shader_particle_reclaim: ComputeShader;
|
|
47
|
+
export { PARTICLE_RECLAIM_WORKGROUP_SIZE };
|
|
48
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
49
|
+
import { PARTICLE_RECLAIM_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
50
|
+
//# sourceMappingURL=shader_particle_reclaim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_particle_reclaim.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_reclaim.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,2GAA2G;AAC3G,sDAAyG;AAWzG,oDAqBG;;8BAnF2B,+BAA+B;gDAGW,yBAAyB"}
|
|
@@ -72,7 +72,7 @@ fn fs_main(in : ParticleVertexOut) -> @location(0) vec4<f32> {
|
|
|
72
72
|
let A = camera.device_depth_to_view_space.y;
|
|
73
73
|
let B = camera.device_depth_to_view_space.x;
|
|
74
74
|
let scene_vd = select(A / (scene_dev + B), 1e9, scene_dev <= 0.0);
|
|
75
|
-
color
|
|
75
|
+
color = particle_fade_color(color, in.blend, particle_soft_fade(scene_vd, in.view_depth, PARTICLE_SOFT_FADE_RANGE));
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
if ((in.flags & PARTICLE_FLAG_LIGHTING) != 0u) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a warm-up tick does to one particle: run its emitter's UPDATE program over it, by a tick
|
|
3
|
+
* jittered for it alone, and say whether it lived.
|
|
4
|
+
*
|
|
5
|
+
* Shared by `./shader_particle_warmup_advance.js` and `./shader_particle_warmup_advance_wide.js`
|
|
6
|
+
* the way the main simulate's step is shared by its two register backings.
|
|
7
|
+
*
|
|
8
|
+
* ## Why this is not `particle_simulate_one`
|
|
9
|
+
*
|
|
10
|
+
* It is the same shape — header, record, node, context, program, verdict — and it differs in two
|
|
11
|
+
* things that are each the whole point of a separate pipeline.
|
|
12
|
+
*
|
|
13
|
+
* It decodes the program section **per lane**. The main step reads the section parameters from the
|
|
14
|
+
* wave's first lane, and is correct only because the bucketing passes regrouped the list so every
|
|
15
|
+
* wave holds one program. The warm-up feeds its advance the raw alive list — spawned by emitters that
|
|
16
|
+
* may run different programs, appended in whatever order the atomics landed — and would need the
|
|
17
|
+
* bucketing's six passes per tick to earn the broadcast. Per-lane decode costs the warm-up some of
|
|
18
|
+
* its own occupancy and nothing else, and the warm-up's occupancy is its own business: nothing here
|
|
19
|
+
* is linked into the main passes, and their compiled code is unchanged by this file existing.
|
|
20
|
+
*
|
|
21
|
+
* It **jitters the tick per particle**. Every particle born in one tick would otherwise reach the
|
|
22
|
+
* end of the loop with exactly that tick's age, and a warm-up of N ticks would arrive as N cohorts.
|
|
23
|
+
* A program does not care what `DELTA_TIME` it is handed, so each particle is advanced by
|
|
24
|
+
* `dt * (1 + PARTICLE_WARMUP_DT_JITTER * (u - 0.5))` for a `u` hashed from its slot and the tick —
|
|
25
|
+
* a hash and not a draw from `random()`, so the program's own random stream is exactly what it would
|
|
26
|
+
* have been.
|
|
27
|
+
*
|
|
28
|
+
* There is no padding sentinel to recognise: the list this reads is the alive list, which holds real
|
|
29
|
+
* slots only. The generation test is kept — the host holds the queue for one frame and an emitter
|
|
30
|
+
* cannot leave mid-loop, but the header carries the generation and honouring it is one compare.
|
|
31
|
+
*
|
|
32
|
+
* @type {CodeChunk}
|
|
33
|
+
*/
|
|
34
|
+
export const chunk_particle_warmup_step: CodeChunk;
|
|
35
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
36
|
+
//# sourceMappingURL=chunk_particle_warmup_step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_particle_warmup_step.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/warmup/chunk_particle_warmup_step.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,yCAFU,SAAS,CA0DhB;0BArGuB,oCAAoC"}
|