@woosh/meep-engine 3.68.0 → 3.69.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/CHANGELOG.md +45 -0
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +2 -17
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +3 -18
- package/package.json +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +33 -65
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +37 -245
- package/src/engine/graphics/ecs/trail3d/Trail3DFlags.d.ts +0 -4
- package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +4 -10
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts +13 -10
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +28 -37
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts +10 -0
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts.map +1 -0
- package/src/engine/graphics/ecs/trail3d/trail_knot_count.js +27 -0
- package/src/engine/graphics/trail/TrailKnots.d.ts +62 -0
- package/src/engine/graphics/trail/TrailKnots.d.ts.map +1 -0
- package/src/engine/graphics/trail/TrailKnots.js +137 -0
- package/src/engine/graphics/trail/tube/TubeXMaterialSpec.d.ts +1 -1
- package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +1 -1
- package/src/engine/graphics3/EntityRowHold.d.ts +48 -0
- package/src/engine/graphics3/EntityRowHold.d.ts.map +1 -0
- package/src/engine/graphics3/EntityRowHold.js +128 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -2
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +11 -44
- package/src/engine/graphics3/Trail3DSystem.d.ts +69 -35
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem.js +380 -81
- package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts +17 -0
- package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacle.js +22 -2
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +6 -5
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +14 -3
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts +9 -1
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js +11 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts +5 -0
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.js +2 -0
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts +4 -3
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.js +11 -3
- package/src/shade/playground/trails/index.html +50 -0
- package/src/shade/playground/trails/main.d.ts +2 -0
- package/src/shade/playground/trails/main.d.ts.map +1 -0
- package/src/shade/playground/trails/main.js +258 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.d.ts +18 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.d.ts.map +1 -0
- package/src/shade/renderer/animation/animation_curve_write_keys.js +34 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/ColorGrade.js +13 -36
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +2 -2
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts +2 -13
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.js +6 -21
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts +17 -6
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.js +38 -178
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts +7 -9
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +17 -106
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts +7 -17
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +18 -118
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts +14 -0
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING.js +18 -0
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts +3 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.js +4 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +9 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +20 -4
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts +11 -2
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.js +59 -2
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +4 -1
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +367 -341
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +6 -2
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +339 -282
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +3 -2
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -1
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +5 -3
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts +49 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.js +144 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts +71 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.js +152 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts +21 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.js +30 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts +101 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.js +306 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +9 -0
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +11 -4
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts +69 -0
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts.map +1 -0
- package/src/shade/renderer/trails/GPUTrailAVBOITChannel.js +129 -0
- package/src/shade/renderer/trails/GPUTrailSystem.d.ts +164 -0
- package/src/shade/renderer/trails/GPUTrailSystem.d.ts.map +1 -0
- package/src/shade/renderer/trails/GPUTrailSystem.js +725 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts +14 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.js +38 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts +66 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_KNOT.js +154 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts +19 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_RECORD.js +68 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts +18 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts.map +1 -0
- package/src/shade/renderer/trails/data/TRAIL_STATE.js +43 -0
- package/src/shade/renderer/trails/graph_trails.d.ts +58 -0
- package/src/shade/renderer/trails/graph_trails.d.ts.map +1 -0
- package/src/shade/renderer/trails/graph_trails.js +155 -0
- package/src/shade/renderer/trails/graph_trails_avboit.d.ts +126 -0
- package/src/shade/renderer/trails/graph_trails_avboit.d.ts.map +1 -0
- package/src/shade/renderer/trails/graph_trails_avboit.js +300 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts +56 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailFadeCurves.js +220 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts +49 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailKnotPool.js +162 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.d.ts +52 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.d.ts.map +1 -0
- package/src/shade/renderer/trails/runtime/TrailParameters.js +126 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts +23 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.js +57 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts +14 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.js +40 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts +18 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_seed.js +64 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts +14 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_segment.js +51 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts +48 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_update.js +197 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts +34 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/chunk_trail_vertex.js +111 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts +24 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit.js +78 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts +23 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.js +130 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts +29 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_draw_args.js +78 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts +18 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_seed.js +79 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts +20 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts.map +1 -0
- package/src/shade/renderer/trails/shaders/shader_trail_update.js +101 -0
- package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts +0 -18
- package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +0 -42
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts +0 -14
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +0 -75
- package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts +0 -17
- package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts.map +0 -1
- package/src/engine/graphics/ecs/trail3d/trail_head_position.js +0 -19
- package/src/engine/graphics/trail/tube/TubeX.d.ts +0 -186
- package/src/engine/graphics/trail/tube/TubeX.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/TubeX.js +0 -575
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +0 -16
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +0 -34
- package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts +0 -27
- package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts.map +0 -1
- package/src/engine/graphics/trail/tube/tube_attributes_spec.js +0 -70
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +0 -38
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +0 -1
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +0 -119
|
@@ -1,341 +1,367 @@
|
|
|
1
|
-
import { chunk_fluid_effector_record_resolve } from "../../../../engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.js";
|
|
2
|
-
import { FLUID_EFFECTOR_RECORD_STRUCT } from "../../../../engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.js";
|
|
3
|
-
import { FLUID_OBSTACLE_RECORD_STRUCT } from "../../../../engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js";
|
|
4
|
-
import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
|
|
5
|
-
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
6
|
-
import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
|
|
7
|
-
import { chunk_folded_workgroup_index } from "../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
8
|
-
import { chunk_grid3d_to_index } from "../../shader/chunk/grid/chunk_grid3d_to_index.js";
|
|
9
|
-
import { chunk_grid_tile_window } from "../../shader/chunk/grid/chunk_grid_tile_window.js";
|
|
10
|
-
import { chunk_index_to_grid3d } from "../../shader/chunk/grid/chunk_index_to_grid3d.js";
|
|
11
|
-
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
12
|
-
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
13
|
-
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
14
|
-
import { f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
15
|
-
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
16
|
-
import { chunk_fluid_forcing_cell } from "./chunk_fluid_forcing_cell.js";
|
|
17
|
-
import {
|
|
18
|
-
FLUID_EFFECTOR_DESCRIPTOR,
|
|
19
|
-
FLUID_OBSTACLE_DESCRIPTOR,
|
|
20
|
-
FLUID_OBSTACLE_PLANE_DESCRIPTOR
|
|
21
|
-
} from "./FLUID_DATABASE_SPEC.js";
|
|
22
|
-
import { FLUID_FORCING_BRICK } from "./FLUID_FORCING.js";
|
|
23
|
-
import { FLUID_FORCING_APPLY_STRUCT } from "./FLUID_FORCING_APPLY_STRUCT.js";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Cells of the block a forcing workgroup tests for solids: its brick and the layer before it on every
|
|
27
|
-
* axis, whose cells pin the brick's −faces.
|
|
28
|
-
* @type {number}
|
|
29
|
-
*/
|
|
30
|
-
const SOLID_BLOCK = FLUID_FORCING_BRICK + 1;
|
|
31
|
-
|
|
32
|
-
const resources = new ShaderResourceSetDescriptor();
|
|
33
|
-
|
|
34
|
-
resources.createGroup()
|
|
35
|
-
.addUniform("settings", FLUID_FORCING_APPLY_STRUCT)
|
|
36
|
-
.addStorageBuffer("fluid_database", WebGPUArray.from(u32), false)
|
|
37
|
-
.addStorageBuffer("scene_database", WebGPUArray.from(u32), false)
|
|
38
|
-
.addStorageBuffer("list", COLLECTION_U32_STRUCT_READ, false)
|
|
39
|
-
.addStorageBuffer("survivors", WebGPUArray.from(u32), false)
|
|
40
|
-
.addStorageBuffer("leaf_rows", WebGPUArray.from(u32), false)
|
|
41
|
-
// the cascade's solid flags, window-local
|
|
42
|
-
.addStorageBuffer("solid", WebGPUArray.from(u32), true)
|
|
43
|
-
// the tick's forcing: u faces, then v from settings.forcing_v, then w from settings.forcing_w
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.addStorageTexture("
|
|
48
|
-
.addStorageTexture("
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var<workgroup>
|
|
58
|
-
var<workgroup>
|
|
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
|
-
return
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
forcing[index] = 0.0;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
let
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
forcing[index] = 0.0;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
let
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
forcing[index] = 0.0;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
let
|
|
192
|
-
let
|
|
193
|
-
let
|
|
194
|
-
let
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
1
|
+
import { chunk_fluid_effector_record_resolve } from "../../../../engine/physics/fluid/effector/record/chunk_fluid_effector_record_resolve.js";
|
|
2
|
+
import { FLUID_EFFECTOR_RECORD_STRUCT } from "../../../../engine/physics/fluid/effector/record/FLUID_EFFECTOR_RECORD_STRUCT.js";
|
|
3
|
+
import { FLUID_OBSTACLE_RECORD_STRUCT } from "../../../../engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js";
|
|
4
|
+
import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
|
|
5
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
6
|
+
import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
|
|
7
|
+
import { chunk_folded_workgroup_index } from "../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
8
|
+
import { chunk_grid3d_to_index } from "../../shader/chunk/grid/chunk_grid3d_to_index.js";
|
|
9
|
+
import { chunk_grid_tile_window } from "../../shader/chunk/grid/chunk_grid_tile_window.js";
|
|
10
|
+
import { chunk_index_to_grid3d } from "../../shader/chunk/grid/chunk_index_to_grid3d.js";
|
|
11
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
12
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
13
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
14
|
+
import { f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
15
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
16
|
+
import { chunk_fluid_forcing_cell } from "./chunk_fluid_forcing_cell.js";
|
|
17
|
+
import {
|
|
18
|
+
FLUID_EFFECTOR_DESCRIPTOR,
|
|
19
|
+
FLUID_OBSTACLE_DESCRIPTOR,
|
|
20
|
+
FLUID_OBSTACLE_PLANE_DESCRIPTOR
|
|
21
|
+
} from "./FLUID_DATABASE_SPEC.js";
|
|
22
|
+
import { FLUID_FORCING_BRICK } from "./FLUID_FORCING.js";
|
|
23
|
+
import { FLUID_FORCING_APPLY_STRUCT } from "./FLUID_FORCING_APPLY_STRUCT.js";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Cells of the block a forcing workgroup tests for solids: its brick and the layer before it on every
|
|
27
|
+
* axis, whose cells pin the brick's −faces.
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
const SOLID_BLOCK = FLUID_FORCING_BRICK + 1;
|
|
31
|
+
|
|
32
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
33
|
+
|
|
34
|
+
resources.createGroup()
|
|
35
|
+
.addUniform("settings", FLUID_FORCING_APPLY_STRUCT)
|
|
36
|
+
.addStorageBuffer("fluid_database", WebGPUArray.from(u32), false)
|
|
37
|
+
.addStorageBuffer("scene_database", WebGPUArray.from(u32), false)
|
|
38
|
+
.addStorageBuffer("list", COLLECTION_U32_STRUCT_READ, false)
|
|
39
|
+
.addStorageBuffer("survivors", WebGPUArray.from(u32), false)
|
|
40
|
+
.addStorageBuffer("leaf_rows", WebGPUArray.from(u32), false)
|
|
41
|
+
// the cascade's solid flags, window-local
|
|
42
|
+
.addStorageBuffer("solid", WebGPUArray.from(u32), true)
|
|
43
|
+
// the tick's forcing: u faces, then v from settings.forcing_v, then w from settings.forcing_w,
|
|
44
|
+
// then the cells' drag from settings.forcing_porous
|
|
45
|
+
.addStorageBuffer("forcing", WebGPUArray.from(f32), true)
|
|
46
|
+
// the cascade's persistent faces, toroidal, where a pinned face takes its wall's velocity
|
|
47
|
+
.addStorageTexture("out_u", "r32float", "3d", "write-only")
|
|
48
|
+
.addStorageTexture("out_v", "r32float", "3d", "write-only")
|
|
49
|
+
.addStorageTexture("out_w", "r32float", "3d", "write-only");
|
|
50
|
+
|
|
51
|
+
const body = CodeChunk.from(
|
|
52
|
+
//language=WGSL
|
|
53
|
+
`
|
|
54
|
+
const SOLID_BLOCK: u32 = ${SOLID_BLOCK}u;
|
|
55
|
+
const SOLID_BLOCK_CELLS: u32 = ${SOLID_BLOCK ** 3}u;
|
|
56
|
+
|
|
57
|
+
var<workgroup> fluid_forcing_obstacles: array<${FLUID_OBSTACLE_RECORD_STRUCT.wgsl_ref}, FLUID_FORCING_OBSTACLE_LIMIT>;
|
|
58
|
+
var<workgroup> fluid_forcing_globals: array<mat4x4<f32>, FLUID_FORCING_OBSTACLE_LIMIT>;
|
|
59
|
+
var<workgroup> fluid_forcing_effectors: array<${FLUID_EFFECTOR_RECORD_STRUCT.wgsl_ref}, FLUID_FORCING_EFFECTOR_LIMIT>;
|
|
60
|
+
// the slot of the obstacle each cell of the block is solid in, or FLUID_FORCING_NONE
|
|
61
|
+
var<workgroup> fluid_forcing_solid_slot: array<u32, SOLID_BLOCK_CELLS>;
|
|
62
|
+
|
|
63
|
+
fn fluid_forcing_obstacle(slot: u32) -> ${FLUID_OBSTACLE_RECORD_STRUCT.wgsl_ref} {
|
|
64
|
+
return fluid_forcing_obstacles[slot];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
fn fluid_forcing_obstacle_global(slot: u32) -> mat4x4<f32> {
|
|
68
|
+
return fluid_forcing_globals[slot];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn fluid_forcing_effector(slot: u32) -> ${FLUID_EFFECTOR_RECORD_STRUCT.wgsl_ref} {
|
|
72
|
+
return fluid_forcing_effectors[slot];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fn shape_record_plane(index: u32) -> vec4<f32> {
|
|
76
|
+
return ${FLUID_OBSTACLE_PLANE_DESCRIPTOR.marshalling_method_read_field('plane')}(&fluid_database, index);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Solid test using the pre-normalised rotation columns stored in fluid_forcing_globals[slot]
|
|
80
|
+
fn fluid_forcing_solid_prenorm(x: vec3<f32>, count: u32) -> u32 {
|
|
81
|
+
var found = FLUID_FORCING_NONE;
|
|
82
|
+
|
|
83
|
+
for (var slot = 0u; slot < FLUID_FORCING_OBSTACLE_LIMIT; slot++) {
|
|
84
|
+
if (slot >= count) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (fluid_forcing_obstacles[slot].drag != 0.0) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let g = fluid_forcing_globals[slot];
|
|
93
|
+
let offset = x - g[3].xyz;
|
|
94
|
+
let node = vec3<f32>(
|
|
95
|
+
dot(g[0].xyz, offset),
|
|
96
|
+
dot(g[1].xyz, offset),
|
|
97
|
+
dot(g[2].xyz, offset),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
let q = fluid_forcing_obstacles[slot].pose_rotation;
|
|
101
|
+
let local = quat_rotate_v3(vec4<f32>(-q.xyz, q.w), node - fluid_forcing_obstacles[slot].pose_translation);
|
|
102
|
+
let d = shape_record_signed_distance(fluid_forcing_obstacles[slot].shape_kind, fluid_forcing_obstacles[slot].shape_parameters, local);
|
|
103
|
+
|
|
104
|
+
if (d <= fluid_forcing_obstacles[slot].inflation) {
|
|
105
|
+
found = slot;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return found;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// the slot a brick-local cell (-1 to 3 on each axis) is solid in
|
|
114
|
+
fn fluid_forcing_block_slot(local: vec3<i32>) -> u32 {
|
|
115
|
+
return fluid_forcing_solid_slot[grid3d_to_index(vec3<u32>(local + vec3<i32>(1)), vec2<u32>(SOLID_BLOCK, SOLID_BLOCK))];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fn fluid_forcing_face_world(face: vec3<f32>) -> vec3<f32> {
|
|
119
|
+
return fluid_forcing_world(settings.cells.corner, settings.cell_size, face);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// A face between the cells whose solids are minus and plus: pinned when either is solid, and then it
|
|
123
|
+
// takes the wall's velocity in the persistent faces, the solid cell's obstacle's, the + side's when
|
|
124
|
+
// both are; otherwise its forcing is what the effectors deposit there.
|
|
125
|
+
fn fluid_forcing_face_u(face: vec3<i32>, minus: u32, plus: u32, effector_count: u32) {
|
|
126
|
+
let index = grid3d_to_index(vec3<u32>(face), settings.faces_u.size.xy);
|
|
127
|
+
let wall = select(minus, plus, plus != FLUID_FORCING_NONE);
|
|
128
|
+
|
|
129
|
+
if (wall != FLUID_FORCING_NONE) {
|
|
130
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.5, 0.0, 0.0));
|
|
131
|
+
let velocity = fluid_forcing_wall_velocity(wall, x);
|
|
132
|
+
|
|
133
|
+
textureStore(out_u, grid_tile_window_storage(face, settings.faces_u.corner_storage, settings.faces_u.period), vec4<f32>(velocity.x, 0.0, 0.0, 0.0));
|
|
134
|
+
forcing[index] = 0.0;
|
|
135
|
+
} else if (effector_count > 0u) {
|
|
136
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.5, 0.0, 0.0));
|
|
137
|
+
forcing[index] = fluid_forcing_deposit(x, settings.dt, settings.cell_size, effector_count).x;
|
|
138
|
+
} else {
|
|
139
|
+
forcing[index] = 0.0;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fn fluid_forcing_face_v(face: vec3<i32>, minus: u32, plus: u32, effector_count: u32) {
|
|
144
|
+
let index = settings.forcing_v + grid3d_to_index(vec3<u32>(face), settings.faces_v.size.xy);
|
|
145
|
+
let wall = select(minus, plus, plus != FLUID_FORCING_NONE);
|
|
146
|
+
|
|
147
|
+
if (wall != FLUID_FORCING_NONE) {
|
|
148
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.0, 0.5, 0.0));
|
|
149
|
+
let velocity = fluid_forcing_wall_velocity(wall, x);
|
|
150
|
+
|
|
151
|
+
textureStore(out_v, grid_tile_window_storage(face, settings.faces_v.corner_storage, settings.faces_v.period), vec4<f32>(velocity.y, 0.0, 0.0, 0.0));
|
|
152
|
+
forcing[index] = 0.0;
|
|
153
|
+
} else if (effector_count > 0u) {
|
|
154
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.0, 0.5, 0.0));
|
|
155
|
+
forcing[index] = fluid_forcing_deposit(x, settings.dt, settings.cell_size, effector_count).y;
|
|
156
|
+
} else {
|
|
157
|
+
forcing[index] = 0.0;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
fn fluid_forcing_face_w(face: vec3<i32>, minus: u32, plus: u32, effector_count: u32) {
|
|
162
|
+
let index = settings.forcing_w + grid3d_to_index(vec3<u32>(face), settings.faces_w.size.xy);
|
|
163
|
+
let wall = select(minus, plus, plus != FLUID_FORCING_NONE);
|
|
164
|
+
|
|
165
|
+
if (wall != FLUID_FORCING_NONE) {
|
|
166
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.0, 0.0, 0.5));
|
|
167
|
+
let velocity = fluid_forcing_wall_velocity(wall, x);
|
|
168
|
+
|
|
169
|
+
textureStore(out_w, grid_tile_window_storage(face, settings.faces_w.corner_storage, settings.faces_w.period), vec4<f32>(velocity.z, 0.0, 0.0, 0.0));
|
|
170
|
+
forcing[index] = 0.0;
|
|
171
|
+
} else if (effector_count > 0u) {
|
|
172
|
+
let x = fluid_forcing_face_world(vec3<f32>(face) - vec3<f32>(0.0, 0.0, 0.5));
|
|
173
|
+
forcing[index] = fluid_forcing_deposit(x, settings.dt, settings.cell_size, effector_count).z;
|
|
174
|
+
} else {
|
|
175
|
+
forcing[index] = 0.0;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@compute @workgroup_size(${FLUID_FORCING_BRICK}, ${FLUID_FORCING_BRICK}, ${FLUID_FORCING_BRICK})
|
|
180
|
+
fn main(
|
|
181
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
182
|
+
@builtin(local_invocation_id) local: vec3<u32>,
|
|
183
|
+
@builtin(local_invocation_index) lane: u32,
|
|
184
|
+
) {
|
|
185
|
+
let entry = folded_workgroup_index(workgroup_id);
|
|
186
|
+
|
|
187
|
+
if (entry >= list.count) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let query = list.elements[entry];
|
|
192
|
+
let base = query * FLUID_FORCING_SURVIVOR_STRIDE;
|
|
193
|
+
let header = survivors[base];
|
|
194
|
+
let obstacle_count = header & 0xffffu;
|
|
195
|
+
let effector_count = header >> 16u;
|
|
196
|
+
let origin = vec3<i32>(index_to_grid3d(query - settings.query_base, settings.bricks.xy) * FLUID_FORCING_BRICK);
|
|
197
|
+
let brick_local = vec3<i32>(local);
|
|
198
|
+
let cell = origin + brick_local;
|
|
199
|
+
let flags = grid3d_to_index(vec3<u32>(cell), settings.cells.size.xy);
|
|
200
|
+
|
|
201
|
+
// listed only to clear what an earlier tick left: fluid, and no forcing to read
|
|
202
|
+
if (obstacle_count + effector_count == 0u) {
|
|
203
|
+
solid[flags] = 0u;
|
|
204
|
+
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// the brick's survivors into workgroup memory, posed: obstacles on lanes 0..23, effectors on 32..47
|
|
209
|
+
if (lane < obstacle_count) {
|
|
210
|
+
let row = leaf_rows[survivors[base + 1u + lane]];
|
|
211
|
+
let record = ${FLUID_OBSTACLE_DESCRIPTOR.marshalling_method_read}(&fluid_database, row);
|
|
212
|
+
let g = ${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, record.node);
|
|
213
|
+
|
|
214
|
+
fluid_forcing_obstacles[lane] = record;
|
|
215
|
+
fluid_forcing_globals[lane] = mat4x4<f32>(
|
|
216
|
+
vec4<f32>(g[0].xyz * (1.0 / length(g[0].xyz)), 0.0),
|
|
217
|
+
vec4<f32>(g[1].xyz * (1.0 / length(g[1].xyz)), 0.0),
|
|
218
|
+
vec4<f32>(g[2].xyz * (1.0 / length(g[2].xyz)), 0.0),
|
|
219
|
+
g[3]
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (lane >= 32u && lane - 32u < effector_count) {
|
|
224
|
+
let slot = lane - 32u;
|
|
225
|
+
let row = leaf_rows[survivors[base + 1u + FLUID_FORCING_OBSTACLE_LIMIT + slot]];
|
|
226
|
+
let record = ${FLUID_EFFECTOR_DESCRIPTOR.marshalling_method_read}(&fluid_database, row);
|
|
227
|
+
|
|
228
|
+
fluid_forcing_effectors[slot] = fluid_effector_record_resolve(
|
|
229
|
+
record,
|
|
230
|
+
${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, record.node),
|
|
231
|
+
${TRANSFORMS_TABLE.marshalling_method_read_field('prev_global')}(&scene_database, record.node),
|
|
232
|
+
settings.inverse_frame_dt
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
workgroupBarrier();
|
|
237
|
+
|
|
238
|
+
var own = FLUID_FORCING_NONE;
|
|
239
|
+
var minus_x = FLUID_FORCING_NONE;
|
|
240
|
+
var minus_y = FLUID_FORCING_NONE;
|
|
241
|
+
var minus_z = FLUID_FORCING_NONE;
|
|
242
|
+
|
|
243
|
+
// the solid test at every cell centre of the brick and the layer before it; a cell before the
|
|
244
|
+
// window is fluid, as every pass of the step reads it
|
|
245
|
+
if (obstacle_count > 0u) {
|
|
246
|
+
for (var round = 0u; round < 2u; round++) {
|
|
247
|
+
let k = round * FLUID_FORCING_BRICK_CELLS + lane;
|
|
248
|
+
|
|
249
|
+
if (k < SOLID_BLOCK_CELLS) {
|
|
250
|
+
let block_cell = origin - vec3<i32>(1) + vec3<i32>(index_to_grid3d(k, vec2<u32>(SOLID_BLOCK, SOLID_BLOCK)));
|
|
251
|
+
|
|
252
|
+
var slot = FLUID_FORCING_NONE;
|
|
253
|
+
|
|
254
|
+
if (all(block_cell >= vec3<i32>(0))) {
|
|
255
|
+
slot = fluid_forcing_solid_prenorm(fluid_forcing_face_world(vec3<f32>(block_cell)), obstacle_count);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
fluid_forcing_solid_slot[k] = slot;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
workgroupBarrier();
|
|
263
|
+
|
|
264
|
+
own = fluid_forcing_block_slot(brick_local);
|
|
265
|
+
minus_x = fluid_forcing_block_slot(brick_local - vec3<i32>(1, 0, 0));
|
|
266
|
+
minus_y = fluid_forcing_block_slot(brick_local - vec3<i32>(0, 1, 0));
|
|
267
|
+
minus_z = fluid_forcing_block_slot(brick_local - vec3<i32>(0, 0, 1));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// the drag of the porous obstacles on a cell that is not solid, over the step
|
|
271
|
+
var porous = 0u;
|
|
272
|
+
|
|
273
|
+
if (obstacle_count > 0u && own == FLUID_FORCING_NONE) {
|
|
274
|
+
let drag = fluid_forcing_porous(fluid_forcing_face_world(vec3<f32>(cell)), settings.cell_size, obstacle_count);
|
|
275
|
+
|
|
276
|
+
if (drag.x > 0.0) {
|
|
277
|
+
let at = settings.forcing_porous + flags * FLUID_FORCING_POROUS_WORDS;
|
|
278
|
+
|
|
279
|
+
forcing[at] = drag.x * settings.dt;
|
|
280
|
+
forcing[at + 1u] = drag.y;
|
|
281
|
+
forcing[at + 2u] = drag.z;
|
|
282
|
+
forcing[at + 3u] = drag.w;
|
|
283
|
+
|
|
284
|
+
porous = FLUID_POROUS_FLAG;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
solid[flags] = FLUID_FORCED_FLAG | select(0u, FLUID_SOLID_FLAG, own != FLUID_FORCING_NONE) | porous;
|
|
289
|
+
|
|
290
|
+
// the cell's -x, -y and -z faces
|
|
291
|
+
fluid_forcing_face_u(cell, minus_x, own, effector_count);
|
|
292
|
+
fluid_forcing_face_v(cell, minus_y, own, effector_count);
|
|
293
|
+
fluid_forcing_face_w(cell, minus_z, own, effector_count);
|
|
294
|
+
|
|
295
|
+
// the +boundary face planes, owned by the window's last cells; the cell beyond is fluid
|
|
296
|
+
let last = vec3<i32>(settings.cells.size) - vec3<i32>(1);
|
|
297
|
+
|
|
298
|
+
if (cell.x == last.x) {
|
|
299
|
+
fluid_forcing_face_u(cell + vec3<i32>(1, 0, 0), own, FLUID_FORCING_NONE, effector_count);
|
|
300
|
+
}
|
|
301
|
+
if (cell.y == last.y) {
|
|
302
|
+
fluid_forcing_face_v(cell + vec3<i32>(0, 1, 0), own, FLUID_FORCING_NONE, effector_count);
|
|
303
|
+
}
|
|
304
|
+
if (cell.z == last.z) {
|
|
305
|
+
fluid_forcing_face_w(cell + vec3<i32>(0, 0, 1), own, FLUID_FORCING_NONE, effector_count);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
`, [
|
|
309
|
+
chunk_folded_workgroup_index,
|
|
310
|
+
chunk_index_to_grid3d,
|
|
311
|
+
chunk_grid3d_to_index,
|
|
312
|
+
chunk_grid_tile_window,
|
|
313
|
+
chunk_fluid_forcing_cell,
|
|
314
|
+
chunk_fluid_effector_record_resolve,
|
|
315
|
+
FLUID_OBSTACLE_DESCRIPTOR.chunk_read,
|
|
316
|
+
FLUID_EFFECTOR_DESCRIPTOR.chunk_read,
|
|
317
|
+
FLUID_OBSTACLE_PLANE_DESCRIPTOR.chunk_read_field('plane'),
|
|
318
|
+
TRANSFORMS_TABLE.chunk_read_field('global'),
|
|
319
|
+
TRANSFORMS_TABLE.chunk_read_field('prev_global'),
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Q3 of a tick, the forcing (GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md §10), for one stepping
|
|
326
|
+
* cascade: one workgroup of 4×4×4 for each brick its query listed, dispatched indirectly from Q2's
|
|
327
|
+
* command, the brick found by `folded_workgroup_index`.
|
|
328
|
+
*
|
|
329
|
+
* 1. **The survivors, posed:** the brick's obstacle records with their nodes' `global` (rotation
|
|
330
|
+
* columns pre-normalised), and its effector records brought to the world
|
|
331
|
+
* (`fluid_effector_record_resolve` with the node's `global` and `prev_global`), into workgroup
|
|
332
|
+
* memory; one barrier.
|
|
333
|
+
* 2. **The solid test** (`fluid_forcing_solid_prenorm`) at the centre of every cell of the brick and
|
|
334
|
+
* the layer before it on each axis (125 cells, two rounds), recording the solid's obstacle; a cell
|
|
335
|
+
* before the window is fluid, as the step reads it. One barrier.
|
|
336
|
+
* 3. **Per cell:** its solid flags, `FLUID_FORCED_FLAG` with `FLUID_SOLID_FLAG` where solid, and
|
|
337
|
+
* `FLUID_POROUS_FLAG` where a porous obstacle drags on a cell that is not solid, whose drag over the
|
|
338
|
+
* step and the velocity it drags toward go into the forcing buffer's porous block
|
|
339
|
+
* (`fluid_forcing_porous`, the drag times `dt_c`); then each
|
|
340
|
+
* of its −x, −y, −z faces, and the window's last cells their +boundary faces: a face with a solid
|
|
341
|
+
* cell on either side is pinned, as every pass of the step will find it from the flags, and takes
|
|
342
|
+
* the wall's velocity (`fluid_forcing_wall_velocity`, the solid cell's obstacle, the + side's when
|
|
343
|
+
* both are) **in the cascade's persistent faces**, before the step reads them, with forcing 0;
|
|
344
|
+
* any other face's forcing is the effectors' deposit over `dt_c` on `h_c`
|
|
345
|
+
* (`fluid_forcing_deposit`).
|
|
346
|
+
*
|
|
347
|
+
* Writing the wall's velocity into the persistent faces is what makes a face that just became pinned
|
|
348
|
+
* carry the wall, never the fluid value it held: advection reads it as a boundary value and every pass
|
|
349
|
+
* carries it through. A brick listed only because its flags held an earlier tick's has no survivors
|
|
350
|
+
* and writes its cells' flags to 0, which is also what leaves no reader of this tick's forcing there.
|
|
351
|
+
*
|
|
352
|
+
* Per invocation: two solid tests of at most 24 fields (768 hull planes at worst), three to six faces
|
|
353
|
+
* of at most 16 kernels. Workgroup memory: 24 records and matrices, 16 records, 125 slots, 4,724
|
|
354
|
+
* bytes.
|
|
355
|
+
*
|
|
356
|
+
* Bindings: `settings` ({@link FLUID_FORCING_APPLY_STRUCT}); `fluid_database` and `scene_database`;
|
|
357
|
+
* `list`, `survivors` and `leaf_rows` from the tick's query and the frame's leaf list; `solid`, the
|
|
358
|
+
* cascade's flags; `forcing`, the tick's; `out_u`, `out_v`, `out_w`, the cascade's persistent faces.
|
|
359
|
+
* Seven storage buffers and three storage textures.
|
|
360
|
+
*
|
|
361
|
+
* @type {ComputeShader}
|
|
362
|
+
*/
|
|
363
|
+
export const shader_fluid_forcing_apply = ComputeShader.from({
|
|
364
|
+
label: "Fluid / forcing / apply",
|
|
365
|
+
resources,
|
|
366
|
+
body,
|
|
367
|
+
});
|