@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.
Files changed (190) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +2 -17
  3. package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
  4. package/editor/ecs/component/editors/ecs/Trail3DEditor.js +3 -18
  5. package/package.json +1 -1
  6. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +33 -65
  7. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
  8. package/src/engine/graphics/ecs/trail3d/Trail3D.js +37 -245
  9. package/src/engine/graphics/ecs/trail3d/Trail3DFlags.d.ts +0 -4
  10. package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +4 -10
  11. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts +13 -10
  12. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.d.ts.map +1 -1
  13. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +28 -37
  14. package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts +10 -0
  15. package/src/engine/graphics/ecs/trail3d/trail_knot_count.d.ts.map +1 -0
  16. package/src/engine/graphics/ecs/trail3d/trail_knot_count.js +27 -0
  17. package/src/engine/graphics/trail/TrailKnots.d.ts +62 -0
  18. package/src/engine/graphics/trail/TrailKnots.d.ts.map +1 -0
  19. package/src/engine/graphics/trail/TrailKnots.js +137 -0
  20. package/src/engine/graphics/trail/tube/TubeXMaterialSpec.d.ts +1 -1
  21. package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +1 -1
  22. package/src/engine/graphics3/EntityRowHold.d.ts +48 -0
  23. package/src/engine/graphics3/EntityRowHold.d.ts.map +1 -0
  24. package/src/engine/graphics3/EntityRowHold.js +128 -0
  25. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +6 -2
  26. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  27. package/src/engine/graphics3/GPUParticleEmitterSystem.js +11 -44
  28. package/src/engine/graphics3/Trail3DSystem.d.ts +69 -35
  29. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
  30. package/src/engine/graphics3/Trail3DSystem.js +380 -81
  31. package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts +17 -0
  32. package/src/engine/physics/fluid/ecs/FluidObstacle.d.ts.map +1 -1
  33. package/src/engine/physics/fluid/ecs/FluidObstacle.js +22 -2
  34. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +6 -5
  35. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
  36. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +14 -3
  37. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts +9 -1
  38. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.d.ts.map +1 -1
  39. package/src/engine/physics/fluid/obstacle/FLUID_OBSTACLE_RECORD_STRUCT.js +11 -1
  40. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts +5 -0
  41. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.d.ts.map +1 -1
  42. package/src/engine/physics/fluid/obstacle/fluid_obstacle_record_create.js +2 -0
  43. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts +4 -3
  44. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.d.ts.map +1 -1
  45. package/src/engine/physics/fluid/obstacle/fluid_obstacle_write_gpu_record.js +11 -3
  46. package/src/shade/playground/trails/index.html +50 -0
  47. package/src/shade/playground/trails/main.d.ts +2 -0
  48. package/src/shade/playground/trails/main.d.ts.map +1 -0
  49. package/src/shade/playground/trails/main.js +258 -0
  50. package/src/shade/renderer/animation/animation_curve_write_keys.d.ts +18 -0
  51. package/src/shade/renderer/animation/animation_curve_write_keys.d.ts.map +1 -0
  52. package/src/shade/renderer/animation/animation_curve_write_keys.js +34 -0
  53. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
  54. package/src/shade/renderer/deferred/tonemap/ColorGrade.js +13 -36
  55. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +2 -2
  56. package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts +2 -13
  57. package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts.map +1 -1
  58. package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.js +6 -21
  59. package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts +17 -6
  60. package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts.map +1 -1
  61. package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.js +38 -178
  62. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts +7 -9
  63. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
  64. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +17 -106
  65. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts +7 -17
  66. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts.map +1 -1
  67. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +18 -118
  68. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts +14 -0
  69. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.d.ts.map +1 -1
  70. package/src/shade/renderer/fluid/forcing/FLUID_FORCING.js +18 -0
  71. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts +3 -1
  72. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.d.ts.map +1 -1
  73. package/src/shade/renderer/fluid/forcing/FLUID_FORCING_APPLY_STRUCT.js +4 -1
  74. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +9 -0
  75. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  76. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +20 -4
  77. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts +11 -2
  78. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.d.ts.map +1 -1
  79. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_cell.js +59 -2
  80. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +4 -1
  81. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
  82. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +367 -341
  83. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +6 -2
  84. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
  85. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +339 -282
  86. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +3 -2
  87. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -1
  88. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +5 -3
  89. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts +49 -0
  90. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.d.ts.map +1 -0
  91. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_draw.js +144 -0
  92. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts +71 -0
  93. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.d.ts.map +1 -0
  94. package/src/shade/renderer/rasterize/native/avboit/avboit_unlit_splat.js +152 -0
  95. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts +21 -0
  96. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.d.ts.map +1 -0
  97. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_unlit_varyings.js +30 -0
  98. package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts +101 -0
  99. package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.d.ts.map +1 -0
  100. package/src/shade/renderer/rasterize/native/avboit/graph_avboit_unlit.js +306 -0
  101. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts +9 -0
  102. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.d.ts.map +1 -1
  103. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +11 -4
  104. package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts +69 -0
  105. package/src/shade/renderer/trails/GPUTrailAVBOITChannel.d.ts.map +1 -0
  106. package/src/shade/renderer/trails/GPUTrailAVBOITChannel.js +129 -0
  107. package/src/shade/renderer/trails/GPUTrailSystem.d.ts +164 -0
  108. package/src/shade/renderer/trails/GPUTrailSystem.d.ts.map +1 -0
  109. package/src/shade/renderer/trails/GPUTrailSystem.js +725 -0
  110. package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts +14 -0
  111. package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.d.ts.map +1 -0
  112. package/src/shade/renderer/trails/data/TRAIL_DATABASE_SPEC.js +38 -0
  113. package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts +66 -0
  114. package/src/shade/renderer/trails/data/TRAIL_KNOT.d.ts.map +1 -0
  115. package/src/shade/renderer/trails/data/TRAIL_KNOT.js +154 -0
  116. package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts +19 -0
  117. package/src/shade/renderer/trails/data/TRAIL_RECORD.d.ts.map +1 -0
  118. package/src/shade/renderer/trails/data/TRAIL_RECORD.js +68 -0
  119. package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts +18 -0
  120. package/src/shade/renderer/trails/data/TRAIL_STATE.d.ts.map +1 -0
  121. package/src/shade/renderer/trails/data/TRAIL_STATE.js +43 -0
  122. package/src/shade/renderer/trails/graph_trails.d.ts +58 -0
  123. package/src/shade/renderer/trails/graph_trails.d.ts.map +1 -0
  124. package/src/shade/renderer/trails/graph_trails.js +155 -0
  125. package/src/shade/renderer/trails/graph_trails_avboit.d.ts +126 -0
  126. package/src/shade/renderer/trails/graph_trails_avboit.d.ts.map +1 -0
  127. package/src/shade/renderer/trails/graph_trails_avboit.js +300 -0
  128. package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts +56 -0
  129. package/src/shade/renderer/trails/runtime/TrailFadeCurves.d.ts.map +1 -0
  130. package/src/shade/renderer/trails/runtime/TrailFadeCurves.js +220 -0
  131. package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts +49 -0
  132. package/src/shade/renderer/trails/runtime/TrailKnotPool.d.ts.map +1 -0
  133. package/src/shade/renderer/trails/runtime/TrailKnotPool.js +162 -0
  134. package/src/shade/renderer/trails/runtime/TrailParameters.d.ts +52 -0
  135. package/src/shade/renderer/trails/runtime/TrailParameters.d.ts.map +1 -0
  136. package/src/shade/renderer/trails/runtime/TrailParameters.js +126 -0
  137. package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts +23 -0
  138. package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.d.ts.map +1 -0
  139. package/src/shade/renderer/trails/shaders/chunk_trail_frame_transport.js +57 -0
  140. package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts +14 -0
  141. package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.d.ts.map +1 -0
  142. package/src/shade/renderer/trails/shaders/chunk_trail_knot_alpha.js +40 -0
  143. package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts +18 -0
  144. package/src/shade/renderer/trails/shaders/chunk_trail_seed.d.ts.map +1 -0
  145. package/src/shade/renderer/trails/shaders/chunk_trail_seed.js +64 -0
  146. package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts +14 -0
  147. package/src/shade/renderer/trails/shaders/chunk_trail_segment.d.ts.map +1 -0
  148. package/src/shade/renderer/trails/shaders/chunk_trail_segment.js +51 -0
  149. package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts +48 -0
  150. package/src/shade/renderer/trails/shaders/chunk_trail_update.d.ts.map +1 -0
  151. package/src/shade/renderer/trails/shaders/chunk_trail_update.js +197 -0
  152. package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts +34 -0
  153. package/src/shade/renderer/trails/shaders/chunk_trail_vertex.d.ts.map +1 -0
  154. package/src/shade/renderer/trails/shaders/chunk_trail_vertex.js +111 -0
  155. package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts +24 -0
  156. package/src/shade/renderer/trails/shaders/shader_trail_avboit.d.ts.map +1 -0
  157. package/src/shade/renderer/trails/shaders/shader_trail_avboit.js +78 -0
  158. package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts +23 -0
  159. package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.d.ts.map +1 -0
  160. package/src/shade/renderer/trails/shaders/shader_trail_avboit_segments.js +130 -0
  161. package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts +29 -0
  162. package/src/shade/renderer/trails/shaders/shader_trail_draw_args.d.ts.map +1 -0
  163. package/src/shade/renderer/trails/shaders/shader_trail_draw_args.js +78 -0
  164. package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts +18 -0
  165. package/src/shade/renderer/trails/shaders/shader_trail_seed.d.ts.map +1 -0
  166. package/src/shade/renderer/trails/shaders/shader_trail_seed.js +79 -0
  167. package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts +20 -0
  168. package/src/shade/renderer/trails/shaders/shader_trail_update.d.ts.map +1 -0
  169. package/src/shade/renderer/trails/shaders/shader_trail_update.js +101 -0
  170. package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts +0 -18
  171. package/src/engine/graphics/ecs/trail3d/advance_trail.d.ts.map +0 -1
  172. package/src/engine/graphics/ecs/trail3d/advance_trail.js +0 -42
  173. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts +0 -14
  174. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.d.ts.map +0 -1
  175. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +0 -75
  176. package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts +0 -17
  177. package/src/engine/graphics/ecs/trail3d/trail_head_position.d.ts.map +0 -1
  178. package/src/engine/graphics/ecs/trail3d/trail_head_position.js +0 -19
  179. package/src/engine/graphics/trail/tube/TubeX.d.ts +0 -186
  180. package/src/engine/graphics/trail/tube/TubeX.d.ts.map +0 -1
  181. package/src/engine/graphics/trail/tube/TubeX.js +0 -575
  182. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +0 -16
  183. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +0 -1
  184. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +0 -34
  185. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts +0 -27
  186. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts.map +0 -1
  187. package/src/engine/graphics/trail/tube/tube_attributes_spec.js +0 -70
  188. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +0 -38
  189. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +0 -1
  190. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +0 -119
@@ -0,0 +1,306 @@
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { GPUTextureUsage } from "../../../../descriptor/GPUTextureUsage.js";
3
+ import { TextureViewDescriptor } from "../../../../descriptor/texture/TextureViewDescriptor.js";
4
+ import { TextureResourceDescriptor } from "../../../../device/graph/TextureResourceDescriptor.js";
5
+ import { DEFAULT_DEPTH_TEXTURE_VIEW } from "../../../depth/DEFAULT_DEPTH_TEXTURE_VIEW.js";
6
+ import { STATIC_GRAPHICS_ENGINE_ASSETS } from "../../../STATIC_GRAPHICS_ENGINE_ASSETS.js";
7
+ import { SAMPLER_LINEAR_UPSCALE } from "../../../texture/SAMPLER_LINEAR_UPSCALE.js";
8
+ import { AVBOIT_UNLIT_DRAW_PASS_GROUP } from "./avboit_unlit_draw.js";
9
+ import { AVBOIT_UNLIT_SPLAT_PASS_GROUP, AVBOIT_UNLIT_SPLAT_SAMPLES } from "./avboit_unlit_splat.js";
10
+ import { AVBOIT_SPLAT_DUMMY_FORMAT, AVBOIT_SPLAT_VOLUME_GROUP } from "./shader_avboit_splat.js";
11
+
12
+ /**
13
+ * The passes an `AVBOITSideChannel` of unlit straight-alpha geometry records for its splat and its draw,
14
+ * with everything but the draws themselves in one place: the attachments, the multisampled target of
15
+ * the splat, the pass-level bind groups and the frame-graph reads and writes. A channel supplies a
16
+ * pipeline built by `avboit_unlit_splat_pipeline` / `avboit_unlit_draw_pipeline`, the graph handles its
17
+ * own draws read, and a `record` callback that issues them; the dynamic meshes and the trails draw
18
+ * through the same passes this way, with different vertex stages.
19
+ *
20
+ * Order does not matter to either pass — the volume and the accumulators are sums — which is why
21
+ * nothing here sorts.
22
+ */
23
+
24
+ /** The accumulators' and the splat target's view: one mip, the one the frame draws into. */
25
+ const COLOR_VIEW = TextureViewDescriptor.from({ mipLevelCount: 1, baseMipLevel: 0 });
26
+
27
+ /**
28
+ * @param {import("../../../shader/resource/ShaderResourceSetDescriptor.js").ShaderResourceSetDescriptor} resources
29
+ * @param {import("../../../shader/resource/ShaderResourceGroupDescriptor.js").ShaderResourceGroupDescriptor} group
30
+ * @returns {number} where the shader declares `group`
31
+ */
32
+ function group_index(resources, group) {
33
+ const index = resources.groups.indexOf(group);
34
+
35
+ assert.notEqual(index, -1, "the shader does not bind this pass group");
36
+
37
+ return index;
38
+ }
39
+
40
+ /**
41
+ * Read every handle of `inputs` in `pass`, keeping the names.
42
+ *
43
+ * @param {object} pass the pass builder
44
+ * @param {Object<string, number>} inputs
45
+ * @returns {Object<string, number>} the handles as the pass reads them
46
+ */
47
+ function read_inputs(pass, inputs) {
48
+ const read = {};
49
+
50
+ for (const name of Object.keys(inputs)) {
51
+ read[name] = pass.read(inputs[name]);
52
+ }
53
+
54
+ return read;
55
+ }
56
+
57
+ /**
58
+ * @param {Object<string, number>} handles
59
+ * @param {object} resources the pass's resolved resources
60
+ * @returns {Object<string, *>} the same names, resolved
61
+ */
62
+ function resolve_inputs(handles, resources) {
63
+ const resolved = {};
64
+
65
+ for (const name of Object.keys(handles)) {
66
+ resolved[name] = resources.get(handles[name]);
67
+ }
68
+
69
+ return resolved;
70
+ }
71
+
72
+ /**
73
+ * Splat a channel's unlit geometry into the voxel volume.
74
+ *
75
+ * The raster is multisampled ({@link AVBOIT_UNLIT_SPLAT_SAMPLES}), so it cannot use the volume's
76
+ * single-sampled splat target: the pass makes its own at the volume's resolution, never written,
77
+ * cleared and discarded, and hands the volume's back untouched.
78
+ *
79
+ * @param {object} params
80
+ * @param {import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
81
+ * @param {string} params.label the pass's label; its target is labelled after it
82
+ * @param {import("../../../../descriptor/pipeline/render/RenderPipelineDescriptor.js").RenderPipelineDescriptor} params.pipeline
83
+ * from `avboit_unlit_splat_pipeline`
84
+ * @param {import("../../../shader/resource/ShaderResourceSetDescriptor.js").ShaderResourceSetDescriptor} params.resources
85
+ * the pipeline's shader resources
86
+ * @param {Object<string, number>} params.inputs graph handles the channel's draws read, by name
87
+ * @param {number} params.warp graph handle
88
+ * @param {number[]} params.voxel_resolution the volume's width and height, which the raster is
89
+ * @param {{extinction: number, overflow: number, dummy: number}} params.volume the volume, to add to
90
+ * @param {function(): boolean} params.is_empty asked when the pass executes; `true` records no render pass
91
+ * @param {function(GPURenderPassEncoder, GraphicsContext, Object<string, *>): void} params.record issues
92
+ * the draws into the open pass, whose pass-level groups are set, with `inputs` resolved
93
+ * @returns {{extinction: number, overflow: number, dummy: number}} the volume after the write
94
+ */
95
+ export function graph_avboit_unlit_splat({
96
+ graph,
97
+ label,
98
+ pipeline,
99
+ resources,
100
+ inputs,
101
+ warp,
102
+ voxel_resolution,
103
+ volume,
104
+ is_empty,
105
+ record,
106
+ }) {
107
+ assert.isString(label, "label");
108
+ assert.isNonNegativeInteger(warp, "warp");
109
+ assert.isArrayLike(voxel_resolution, "voxel_resolution");
110
+ assert.defined(volume, "volume");
111
+ assert.isFunction(is_empty, "is_empty");
112
+ assert.isFunction(record, "record");
113
+
114
+ const pass_group_index = group_index(resources, AVBOIT_UNLIT_SPLAT_PASS_GROUP);
115
+ const volume_group_index = group_index(resources, AVBOIT_SPLAT_VOLUME_GROUP);
116
+
117
+ function execute(data, frame_resources, context) {
118
+ const encoder = context.encoder;
119
+ const graphics = context.graphics;
120
+
121
+ if (is_empty()) {
122
+ return;
123
+ }
124
+
125
+ // By name, never by position (AVBOIT ledger entry 21): the order a shader declares its
126
+ // bindings in is the shader's business.
127
+ const pass_group = AVBOIT_UNLIT_SPLAT_PASS_GROUP.generateBindings({
128
+ warp: frame_resources.get(data.warp),
129
+ }, encoder);
130
+
131
+ const volume_group = AVBOIT_SPLAT_VOLUME_GROUP.generateBindings({
132
+ extinction_volume: frame_resources.get(data.extinction),
133
+ overflow_slice: frame_resources.get(data.overflow),
134
+ }, encoder);
135
+
136
+ // the target is never written; it only sizes the raster and gives it its samples
137
+ const pass_encoder = encoder.constructRenderPass({
138
+ label,
139
+ pipeline,
140
+ // the pass's groups are set once, just below; the draws set their own
141
+ bindings: [],
142
+ colorAttachments: [{
143
+ view: frame_resources.get(data.target).obtainView(COLOR_VIEW),
144
+ loadOp: "clear",
145
+ storeOp: "discard",
146
+ }],
147
+ });
148
+
149
+ graphics.setPipelineBindGroup(pass_encoder, pipeline, pass_group_index, pass_group);
150
+ graphics.setPipelineBindGroup(pass_encoder, pipeline, volume_group_index, volume_group);
151
+
152
+ record(pass_encoder, graphics, resolve_inputs(data.inputs, frame_resources));
153
+
154
+ pass_encoder.end();
155
+ }
156
+
157
+ const pass_data = {};
158
+ const pass = graph.add(label, pass_data, execute);
159
+
160
+ pass_data.inputs = read_inputs(pass, inputs);
161
+ pass_data.warp = pass.read(warp);
162
+
163
+ pass.read(volume.extinction);
164
+ pass_data.extinction = pass.write(volume.extinction);
165
+ pass.read(volume.overflow);
166
+ pass_data.overflow = pass.write(volume.overflow);
167
+
168
+ const target = TextureResourceDescriptor.from({
169
+ resolution: voxel_resolution,
170
+ format: AVBOIT_SPLAT_DUMMY_FORMAT,
171
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
172
+ });
173
+
174
+ // `from` takes no sample count
175
+ target.sampleCount = AVBOIT_UNLIT_SPLAT_SAMPLES;
176
+
177
+ pass_data.target = pass.create(`${label} target`, target);
178
+
179
+ return {
180
+ extinction: pass_data.extinction,
181
+ overflow: pass_data.overflow,
182
+ // not this pass's to touch
183
+ dummy: volume.dummy,
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Draw a channel's unlit geometry into the four accumulators, depth-tested against the opaque scene.
189
+ *
190
+ * @param {object} params
191
+ * @param {import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
192
+ * @param {string} params.label
193
+ * @param {import("../../../../descriptor/pipeline/render/RenderPipelineDescriptor.js").RenderPipelineDescriptor} params.pipeline
194
+ * from `avboit_unlit_draw_pipeline`
195
+ * @param {import("../../../shader/resource/ShaderResourceSetDescriptor.js").ShaderResourceSetDescriptor} params.resources
196
+ * the pipeline's shader resources
197
+ * @param {Object<string, number>} params.inputs graph handles the channel's draws read, by name
198
+ * @param {import("../../../view/GPUViewContext.js").GPUViewContext} params.view_ctx
199
+ * @param {number} params.depth_texture graph handle of the opaque scene's depth — tested, never written
200
+ * @param {number} params.warp graph handle
201
+ * @param {number} params.integral graph handle of the integral texture
202
+ * @param {number} params.volumetrics_lut graph handle
203
+ * @param {number} params.volumetrics_metadata graph handle
204
+ * @param {{color: number, norm: number, extinction: number, emission: number}} params.accumulators to add to
205
+ * @param {function(): boolean} params.is_empty asked when the pass executes; `true` records no render pass
206
+ * @param {function(GPURenderPassEncoder, GraphicsContext, Object<string, *>): void} params.record issues
207
+ * the draws into the open pass, whose pass-level group is set, with `inputs` resolved
208
+ * @returns {{color: number, norm: number, extinction: number, emission: number}} the accumulators after the draw
209
+ */
210
+ export function graph_avboit_unlit_draw({
211
+ graph,
212
+ label,
213
+ pipeline,
214
+ resources,
215
+ inputs,
216
+ view_ctx,
217
+ depth_texture,
218
+ warp,
219
+ integral,
220
+ volumetrics_lut,
221
+ volumetrics_metadata,
222
+ accumulators,
223
+ is_empty,
224
+ record,
225
+ }) {
226
+ assert.isString(label, "label");
227
+ assert.isNonNegativeInteger(depth_texture, "depth_texture");
228
+ assert.isNonNegativeInteger(warp, "warp");
229
+ assert.isNonNegativeInteger(integral, "integral");
230
+ assert.defined(accumulators, "accumulators");
231
+ assert.isFunction(is_empty, "is_empty");
232
+ assert.isFunction(record, "record");
233
+
234
+ const pass_group_index = group_index(resources, AVBOIT_UNLIT_DRAW_PASS_GROUP);
235
+
236
+ function execute(data, frame_resources, context) {
237
+ const encoder = context.encoder;
238
+ const graphics = context.graphics;
239
+
240
+ if (is_empty()) {
241
+ return;
242
+ }
243
+
244
+ // by name rather than by position, for the reason the splat gives
245
+ const pass_group = AVBOIT_UNLIT_DRAW_PASS_GROUP.generateBindings({
246
+ view: view_ctx.uniform_buffer.buffer,
247
+ warp: frame_resources.get(data.warp),
248
+ tIntegral: frame_resources.get(data.integral).obtainView(),
249
+ sLinear: graphics.samplers.obtain(SAMPLER_LINEAR_UPSCALE),
250
+ volumetrics_metadata: frame_resources.get(data.volumetrics_metadata),
251
+ tVolumetrics: frame_resources.get(data.volumetrics_lut).obtainView(),
252
+ tSTBN_vec3: graphics.textures.obtain(STATIC_GRAPHICS_ENGINE_ASSETS.stbn_vec3).obtainView(),
253
+ }, encoder);
254
+
255
+ const attachment = (handle) => ({
256
+ view: frame_resources.get(handle).obtainView(COLOR_VIEW),
257
+ loadOp: "load",
258
+ storeOp: "store",
259
+ });
260
+
261
+ const pass_encoder = encoder.constructRenderPass({
262
+ label,
263
+ pipeline,
264
+ // the pass's group is set once, just below; the draws set their own
265
+ bindings: [],
266
+ colorAttachments: [
267
+ attachment(data.color),
268
+ attachment(data.norm),
269
+ attachment(data.extinction),
270
+ attachment(data.emission),
271
+ ],
272
+ depthStencilAttachment: {
273
+ view: frame_resources.get(data.depth).obtainView(DEFAULT_DEPTH_TEXTURE_VIEW),
274
+ depthReadOnly: true,
275
+ },
276
+ });
277
+
278
+ graphics.setPipelineBindGroup(pass_encoder, pipeline, pass_group_index, pass_group);
279
+
280
+ record(pass_encoder, graphics, resolve_inputs(data.inputs, frame_resources));
281
+
282
+ pass_encoder.end();
283
+ }
284
+
285
+ const pass_data = {};
286
+ const pass = graph.add(label, pass_data, execute);
287
+
288
+ pass_data.inputs = read_inputs(pass, inputs);
289
+ pass_data.depth = pass.read(depth_texture);
290
+ pass_data.warp = pass.read(warp);
291
+ pass_data.integral = pass.read(integral);
292
+ pass_data.volumetrics_lut = pass.read(volumetrics_lut);
293
+ pass_data.volumetrics_metadata = pass.read(volumetrics_metadata);
294
+
295
+ for (const name of ["color", "norm", "extinction", "emission"]) {
296
+ pass.read(accumulators[name]);
297
+ pass_data[name] = pass.write(accumulators[name]);
298
+ }
299
+
300
+ return {
301
+ color: pass_data.color,
302
+ norm: pass_data.norm,
303
+ extinction: pass_data.extinction,
304
+ emission: pass_data.emission,
305
+ };
306
+ }
@@ -10,11 +10,20 @@ export const AVBOIT_SPLAT_BIND_GROUP_VOLUME: number;
10
10
  * @type {GPUTextureFormat}
11
11
  */
12
12
  export const AVBOIT_SPLAT_DUMMY_FORMAT: GPUTextureFormat;
13
+ /**
14
+ * The voxel volume a splat adds its extinction into: the packed counts and the per-channel first
15
+ * overflow, both atomics, so fragment-only. Every splat that writes through `avboit_splat_slice` binds
16
+ * this group.
17
+ *
18
+ * @type {ShaderResourceGroupDescriptor}
19
+ */
20
+ export const AVBOIT_SPLAT_VOLUME_GROUP: ShaderResourceGroupDescriptor;
13
21
  /**
14
22
  * One pipeline per template that can be drawn forward.
15
23
  *
16
24
  * @type {TemplatePassDescriptor}
17
25
  */
18
26
  export const shader_avboit_splat: TemplatePassDescriptor;
27
+ import { ShaderResourceGroupDescriptor } from "../../../shader/resource/ShaderResourceGroupDescriptor.js";
19
28
  import { TemplatePassDescriptor } from "../../TemplatePassDescriptor.js";
20
29
  //# sourceMappingURL=shader_avboit_splat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shader_avboit_splat.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,6CAFU,MAAM,CAEgC;AAEhD;;;;GAIG;AACH,yDAAmD;AA8HnD;;;;GAIG;AACH,kCAFU,sBAAsB,CA+B7B;uCApLoC,iCAAiC"}
1
+ {"version":3,"file":"shader_avboit_splat.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,6CAFU,MAAM,CAEgC;AAEhD;;;;GAIG;AACH,yDAAmD;AASnD;;;;;;GAMG;AACH,wCAFU,6BAA6B,CAEsC;AAqH7E;;;;GAIG;AACH,kCAFU,sBAAsB,CA+B7B;8CArM2C,2DAA2D;uCAUlE,iCAAiC"}
@@ -49,14 +49,21 @@ view_group
49
49
  .addStorageBuffer("warp", AVBOIT_WARP_STRUCT)
50
50
  ;
51
51
 
52
- const volume_group = new ShaderResourceGroupDescriptor();
52
+ /**
53
+ * The voxel volume a splat adds its extinction into: the packed counts and the per-channel first
54
+ * overflow, both atomics, so fragment-only. Every splat that writes through `avboit_splat_slice` binds
55
+ * this group.
56
+ *
57
+ * @type {ShaderResourceGroupDescriptor}
58
+ */
59
+ export const AVBOIT_SPLAT_VOLUME_GROUP = new ShaderResourceGroupDescriptor();
53
60
 
54
- volume_group
61
+ AVBOIT_SPLAT_VOLUME_GROUP
55
62
  .addStorageBuffer("extinction_volume", WebGPUArray.from(atomic_u32), true)
56
63
  .addStorageBuffer("overflow_slice", WebGPUArray.from(atomic_u32), true)
57
64
  ;
58
65
 
59
- const pass_groups = [view_group, volume_group];
66
+ const pass_groups = [view_group, AVBOIT_SPLAT_VOLUME_GROUP];
60
67
 
61
68
  /*
62
69
  The layout is built group by group rather than with one visibility for every group: WebGPU refuses
@@ -67,7 +74,7 @@ const pass_groups = [view_group, volume_group];
67
74
  */
68
75
  const pass_layouts = [
69
76
  view_group.generateBindGroupLayoutDescriptor(GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT),
70
- volume_group.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT),
77
+ AVBOIT_SPLAT_VOLUME_GROUP.generateBindGroupLayoutDescriptor(GPUShaderStage.FRAGMENT),
71
78
  ];
72
79
 
73
80
  const shader_vertex = ShaderDescriptor.from({
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The GPU trails as an `AVBOITSideChannel`: drawn inside the transparency pipeline, order-independently
3
+ * against the transparent meshes, the particles, the dynamic meshes and each other.
4
+ *
5
+ * - **occupancy** — the segments pass: a thread per live segment, culled by fade and by the view
6
+ * frustum, marking the depth slices its capsule spans and appending itself to its draw class's list.
7
+ * - **splat** and **draw** — the unlit pair the dynamic meshes draw through, with the tube extruded in
8
+ * the vertex stage: one indexed indirect draw per draw class, a segment an instance.
9
+ *
10
+ * The frame's simulation is recorded before this is asked (the trails' frame extension runs at
11
+ * AfterLighting); {@link begin_frame} hands it over with the view it was recorded for. A registered
12
+ * trail makes the channel non-empty: whether every trail has faded is the GPU's to know, and the CPU
13
+ * does not read it back.
14
+ */
15
+ export class GPUTrailAVBOITChannel {
16
+ /**
17
+ * The frame's simulation, for the view it is drawn in.
18
+ *
19
+ * @param {object} graph
20
+ * @param {import("../view/GPUViewContext.js").GPUViewContext} view
21
+ * @param {import("./GPUTrailSystem.js").GPUTrailSystem} runtime
22
+ * @param {import("./graph_trails.js").TrailSimulationHandles} simulation
23
+ */
24
+ begin_frame(graph: object, view: import("../view/GPUViewContext.js").GPUViewContext, runtime: import("./GPUTrailSystem.js").GPUTrailSystem, simulation: import("./graph_trails.js").TrailSimulationHandles): void;
25
+ /**
26
+ * Forget the frame: the passes carry their own references to what they read.
27
+ */
28
+ end_frame(): void;
29
+ /**
30
+ * @param {import("../view/GPUViewContext.js").GPUViewContext} view
31
+ * @returns {boolean}
32
+ */
33
+ avboit_is_empty(view: import("../view/GPUViewContext.js").GPUViewContext): boolean;
34
+ avboit_occupancy({ graph, camera, cluster_parameters, occupancy }: {
35
+ graph: any;
36
+ camera: any;
37
+ cluster_parameters: any;
38
+ occupancy: any;
39
+ }): number;
40
+ avboit_splat({ graph, camera, warp, voxel_resolution, volume }: {
41
+ graph: any;
42
+ camera: any;
43
+ warp: any;
44
+ voxel_resolution: any;
45
+ volume: any;
46
+ }): {
47
+ extinction: number;
48
+ overflow: number;
49
+ dummy: number;
50
+ };
51
+ avboit_draw({ graph, view_ctx, camera, depth_texture, warp, integral, volumetrics_lut, volumetrics_metadata, accumulators }: {
52
+ graph: any;
53
+ view_ctx: any;
54
+ camera: any;
55
+ depth_texture: any;
56
+ warp: any;
57
+ integral: any;
58
+ volumetrics_lut: any;
59
+ volumetrics_metadata: any;
60
+ accumulators: any;
61
+ }): {
62
+ color: number;
63
+ norm: number;
64
+ extinction: number;
65
+ emission: number;
66
+ };
67
+ #private;
68
+ }
69
+ //# sourceMappingURL=GPUTrailAVBOITChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GPUTrailAVBOITChannel.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/trails/GPUTrailAVBOITChannel.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH;IAMI;;;;;;;OAOG;IACH,mBALW,MAAM,QACN,OAAO,2BAA2B,EAAE,cAAc,WAClD,OAAO,qBAAqB,EAAE,cAAc,cAC5C,OAAO,mBAAmB,EAAE,sBAAsB,QAI5D;IAED;;OAEG;IACH,kBAEC;IAED;;;OAGG;IACH,sBAHW,OAAO,2BAA2B,EAAE,cAAc,GAChD,OAAO,CAMnB;IAED;;;;;eAaC;IAED;;;;;;;;;;MAeC;IAED;;;;;;;;;;;;;;;MAgCC;;CAYJ"}
@@ -0,0 +1,129 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import { graph_trails_avboit_draw, graph_trails_avboit_segments, graph_trails_avboit_splat } from "./graph_trails_avboit.js";
3
+
4
+ /**
5
+ * The GPU trails as an `AVBOITSideChannel`: drawn inside the transparency pipeline, order-independently
6
+ * against the transparent meshes, the particles, the dynamic meshes and each other.
7
+ *
8
+ * - **occupancy** — the segments pass: a thread per live segment, culled by fade and by the view
9
+ * frustum, marking the depth slices its capsule spans and appending itself to its draw class's list.
10
+ * - **splat** and **draw** — the unlit pair the dynamic meshes draw through, with the tube extruded in
11
+ * the vertex stage: one indexed indirect draw per draw class, a segment an instance.
12
+ *
13
+ * The frame's simulation is recorded before this is asked (the trails' frame extension runs at
14
+ * AfterLighting); {@link begin_frame} hands it over with the view it was recorded for. A registered
15
+ * trail makes the channel non-empty: whether every trail has faded is the GPU's to know, and the CPU
16
+ * does not read it back.
17
+ */
18
+ export class GPUTrailAVBOITChannel {
19
+ /**
20
+ * @type {{graph: object, view: object, runtime: import("./GPUTrailSystem.js").GPUTrailSystem, simulation: import("./graph_trails.js").TrailSimulationHandles, segments: import("./graph_trails_avboit.js").TrailSegmentsHandles|null}|null}
21
+ */
22
+ #frame = null;
23
+
24
+ /**
25
+ * The frame's simulation, for the view it is drawn in.
26
+ *
27
+ * @param {object} graph
28
+ * @param {import("../view/GPUViewContext.js").GPUViewContext} view
29
+ * @param {import("./GPUTrailSystem.js").GPUTrailSystem} runtime
30
+ * @param {import("./graph_trails.js").TrailSimulationHandles} simulation
31
+ */
32
+ begin_frame(graph, view, runtime, simulation) {
33
+ this.#frame = { graph, view, runtime, simulation, segments: null };
34
+ }
35
+
36
+ /**
37
+ * Forget the frame: the passes carry their own references to what they read.
38
+ */
39
+ end_frame() {
40
+ this.#frame = null;
41
+ }
42
+
43
+ /**
44
+ * @param {import("../view/GPUViewContext.js").GPUViewContext} view
45
+ * @returns {boolean}
46
+ */
47
+ avboit_is_empty(view) {
48
+ const frame = this.#frame;
49
+
50
+ return frame === null || frame.view !== view || frame.runtime.count === 0;
51
+ }
52
+
53
+ avboit_occupancy({ graph, camera, cluster_parameters, occupancy }) {
54
+ const frame = this.#frame_for(graph);
55
+
56
+ frame.segments = graph_trails_avboit_segments({
57
+ graph,
58
+ camera,
59
+ cluster_parameters,
60
+ occupancy,
61
+ simulation: frame.simulation,
62
+ runtime: frame.runtime,
63
+ });
64
+
65
+ return frame.segments.occupancy;
66
+ }
67
+
68
+ avboit_splat({ graph, camera, warp, voxel_resolution, volume }) {
69
+ const frame = this.#frame_for(graph);
70
+
71
+ assert.notNull(frame.segments, "the occupancy was not recorded into this graph");
72
+
73
+ return graph_trails_avboit_splat({
74
+ graph,
75
+ camera,
76
+ warp,
77
+ voxel_resolution,
78
+ volume,
79
+ simulation: frame.simulation,
80
+ segments: frame.segments,
81
+ runtime: frame.runtime,
82
+ });
83
+ }
84
+
85
+ avboit_draw({
86
+ graph,
87
+ view_ctx,
88
+ camera,
89
+ depth_texture,
90
+ warp,
91
+ integral,
92
+ volumetrics_lut,
93
+ volumetrics_metadata,
94
+ accumulators
95
+ }) {
96
+ const frame = this.#frame_for(graph);
97
+
98
+ assert.notNull(frame.segments, "the occupancy was not recorded into this graph");
99
+
100
+ // the last of the three: what is left is the passes'
101
+ this.#frame = null;
102
+
103
+ return graph_trails_avboit_draw({
104
+ graph,
105
+ view_ctx,
106
+ camera,
107
+ depth_texture,
108
+ warp,
109
+ integral,
110
+ volumetrics_lut,
111
+ volumetrics_metadata,
112
+ accumulators,
113
+ simulation: frame.simulation,
114
+ segments: frame.segments,
115
+ runtime: frame.runtime,
116
+ });
117
+ }
118
+
119
+ /**
120
+ * @param {object} graph
121
+ */
122
+ #frame_for(graph) {
123
+ const frame = this.#frame;
124
+
125
+ assert.ok(frame !== null && frame.graph === graph, "the trails' simulation was not recorded into this graph");
126
+
127
+ return frame;
128
+ }
129
+ }