@woosh/meep-engine 3.28.0 → 3.30.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 (685) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  5. package/src/core/binary/BinaryBuffer.js +14 -2
  6. package/src/core/binary/BitSet.d.ts +16 -0
  7. package/src/core/binary/BitSet.d.ts.map +1 -1
  8. package/src/core/binary/BitSet.js +159 -49
  9. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  10. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  11. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  12. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  13. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  14. package/src/core/binary/compression/compress_bytes.js +35 -0
  15. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  16. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  17. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  18. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  19. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  20. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  21. package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
  22. package/src/core/bvh2/bvh3/BVH.js +14 -1
  23. package/src/core/cache/FrequencySketch.d.ts +3 -1
  24. package/src/core/cache/FrequencySketch.d.ts.map +1 -1
  25. package/src/core/cache/FrequencySketch.js +10 -4
  26. package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
  27. package/src/core/cache/wtinylfu/CacheWTinylfu.js +24 -2
  28. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  36. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  37. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  38. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  39. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  40. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  41. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  42. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  43. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  44. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  45. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  46. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  47. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  48. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  49. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  50. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  51. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts +20 -0
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +69 -4
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +93 -17
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  60. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +930 -69
  61. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  62. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  63. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  64. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  65. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  66. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  67. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts +25 -0
  68. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts.map +1 -0
  69. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.js +228 -0
  70. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts +13 -0
  71. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts.map +1 -1
  72. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js +10 -128
  73. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.d.ts.map +1 -1
  74. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js +11 -1
  75. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  76. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  77. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  78. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  79. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  80. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  81. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  82. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  83. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  84. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  85. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  86. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  87. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  88. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  89. package/src/core/graph/mn_graph_collapse_weighted_edge.js +6 -6
  90. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
  91. package/src/core/math/lookup/ParameterLookupTable.js +10 -5
  92. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  93. package/src/core/math/noise/sdnoise.js +16 -10
  94. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  95. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  96. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  97. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  98. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  99. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  100. package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
  101. package/src/core/model/object/ImmutableObjectPool.js +17 -7
  102. package/src/core/process/executor/ConcurrentExecutor.d.ts +1 -5
  103. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  104. package/src/core/process/executor/ConcurrentExecutor.js +95 -1
  105. package/src/core/process/task/task_find_dependency_cycle.d.ts +17 -0
  106. package/src/core/process/task/task_find_dependency_cycle.d.ts.map +1 -0
  107. package/src/core/process/task/task_find_dependency_cycle.js +81 -0
  108. package/src/core/wfc/WFCCellChoice.d.ts +17 -0
  109. package/src/core/wfc/WFCCellChoice.d.ts.map +1 -0
  110. package/src/core/wfc/WFCCellChoice.js +36 -0
  111. package/src/core/wfc/WFCLattice.d.ts +105 -0
  112. package/src/core/wfc/WFCLattice.d.ts.map +1 -0
  113. package/src/core/wfc/WFCLattice.js +235 -0
  114. package/src/core/wfc/WFCRuleTable.d.ts +172 -0
  115. package/src/core/wfc/WFCRuleTable.d.ts.map +1 -0
  116. package/src/core/wfc/WFCRuleTable.js +334 -0
  117. package/src/core/wfc/WFCState.d.ts +273 -0
  118. package/src/core/wfc/WFCState.d.ts.map +1 -0
  119. package/src/core/wfc/WFCState.js +552 -0
  120. package/src/core/wfc/WFCStatus.d.ts +11 -0
  121. package/src/core/wfc/WFCStatus.d.ts.map +1 -0
  122. package/src/core/wfc/WFCStatus.js +28 -0
  123. package/src/core/wfc/WFCTileWeights.d.ts +48 -0
  124. package/src/core/wfc/WFCTileWeights.d.ts.map +1 -0
  125. package/src/core/wfc/WFCTileWeights.js +86 -0
  126. package/src/core/wfc/WFC_UNRESOLVED.d.ts +12 -0
  127. package/src/core/wfc/WFC_UNRESOLVED.d.ts.map +1 -0
  128. package/src/core/wfc/WFC_UNRESOLVED.js +11 -0
  129. package/src/core/wfc/wfc_estimate_bytes.d.ts +24 -0
  130. package/src/core/wfc/wfc_estimate_bytes.d.ts.map +1 -0
  131. package/src/core/wfc/wfc_estimate_bytes.js +47 -0
  132. package/src/core/wfc/wfc_rule_table_tile_components.d.ts +27 -0
  133. package/src/core/wfc/wfc_rule_table_tile_components.d.ts.map +1 -0
  134. package/src/core/wfc/wfc_rule_table_tile_components.js +80 -0
  135. package/src/core/wfc/wfc_solve.d.ts +21 -0
  136. package/src/core/wfc/wfc_solve.d.ts.map +1 -0
  137. package/src/core/wfc/wfc_solve.js +154 -0
  138. package/src/core/wfc/wfc_state_apply_boundary.d.ts +18 -0
  139. package/src/core/wfc/wfc_state_apply_boundary.d.ts.map +1 -0
  140. package/src/core/wfc/wfc_state_apply_boundary.js +61 -0
  141. package/src/core/wfc/wfc_state_assign.d.ts +11 -0
  142. package/src/core/wfc/wfc_state_assign.d.ts.map +1 -0
  143. package/src/core/wfc/wfc_state_assign.js +36 -0
  144. package/src/core/wfc/wfc_state_ban_bits.d.ts +17 -0
  145. package/src/core/wfc/wfc_state_ban_bits.d.ts.map +1 -0
  146. package/src/core/wfc/wfc_state_ban_bits.js +81 -0
  147. package/src/core/wfc/wfc_state_collapse.d.ts +12 -0
  148. package/src/core/wfc/wfc_state_collapse.d.ts.map +1 -0
  149. package/src/core/wfc/wfc_state_collapse.js +73 -0
  150. package/src/core/wfc/wfc_state_flush_dirty.d.ts +12 -0
  151. package/src/core/wfc/wfc_state_flush_dirty.d.ts.map +1 -0
  152. package/src/core/wfc/wfc_state_flush_dirty.js +39 -0
  153. package/src/core/wfc/wfc_state_propagate.d.ts +14 -0
  154. package/src/core/wfc/wfc_state_propagate.d.ts.map +1 -0
  155. package/src/core/wfc/wfc_state_propagate.js +155 -0
  156. package/src/core/wfc/wfc_state_read.d.ts +11 -0
  157. package/src/core/wfc/wfc_state_read.d.ts.map +1 -0
  158. package/src/core/wfc/wfc_state_read.js +38 -0
  159. package/src/core/wfc/wfc_state_restrict.d.ts +18 -0
  160. package/src/core/wfc/wfc_state_restrict.d.ts.map +1 -0
  161. package/src/core/wfc/wfc_state_restrict.js +39 -0
  162. package/src/core/wfc/wfc_state_set_eligible.d.ts +24 -0
  163. package/src/core/wfc/wfc_state_set_eligible.d.ts.map +1 -0
  164. package/src/core/wfc/wfc_state_set_eligible.js +49 -0
  165. package/src/core/wfc/wfc_state_undo_to.d.ts +13 -0
  166. package/src/core/wfc/wfc_state_undo_to.d.ts.map +1 -0
  167. package/src/core/wfc/wfc_state_undo_to.js +84 -0
  168. package/src/core/wfc/wfc_words_per_cell.d.ts +11 -0
  169. package/src/core/wfc/wfc_words_per_cell.d.ts.map +1 -0
  170. package/src/core/wfc/wfc_words_per_cell.js +16 -0
  171. package/src/engine/ecs/EntityComponentDataset.d.ts +8 -0
  172. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  173. package/src/engine/ecs/EntityComponentDataset.js +37 -14
  174. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +8 -1
  175. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  176. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +37 -2
  177. package/src/engine/ecs/guid/UUID.d.ts.map +1 -1
  178. package/src/engine/ecs/guid/UUID.js +45 -17
  179. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +1 -1
  180. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +3 -1
  181. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  182. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +366 -360
  183. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.d.ts.map +1 -1
  184. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +24 -10
  185. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  186. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  187. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  188. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  189. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  190. package/src/engine/graphics3/DecalSystem.js +5 -5
  191. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  192. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  193. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  194. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  195. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  196. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +24 -5
  197. package/src/engine/interpolation/Interpoland.d.ts +7 -1
  198. package/src/engine/interpolation/Interpoland.d.ts.map +1 -1
  199. package/src/engine/interpolation/Interpoland.js +8 -1
  200. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  201. package/src/engine/interpolation/InterpolationSystem.js +3 -0
  202. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +5 -3
  203. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
  204. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -3
  205. package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -1
  206. package/src/engine/interpolation/pose_interpoland.js +2 -0
  207. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  208. package/src/engine/network/orchestrator/NetworkPeer.js +15 -10
  209. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  210. package/src/engine/physics/cloth/ecs/ClothWorld.js +17 -0
  211. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
  212. package/src/engine/physics/mls-mpm/MLS_MPM.js +14 -0
  213. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +2 -1
  214. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
  215. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +1 -1
  216. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -0
  217. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
  218. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -0
  219. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
  220. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +2 -1
  221. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
  222. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +12 -3
  223. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -0
  224. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -1
  225. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -0
  226. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  227. package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
  228. package/src/engine/sound/sopra/runtime/EventInstance.js +4 -1
  229. package/src/format/image/avif/av1/decode/decode_coefficients.d.ts.map +1 -1
  230. package/src/format/image/avif/av1/decode/decode_coefficients.js +248 -259
  231. package/src/format/image/avif/av1/decode/read_golomb.d.ts +21 -0
  232. package/src/format/image/avif/av1/decode/read_golomb.d.ts.map +1 -0
  233. package/src/format/image/avif/av1/decode/read_golomb.js +49 -0
  234. package/src/format/image/avif/av1/filter/loop_restoration.js +461 -451
  235. package/src/format/image/avif/av1/util/round2.d.ts +19 -2
  236. package/src/format/image/avif/av1/util/round2.d.ts.map +1 -1
  237. package/src/format/image/avif/av1/util/round2.js +51 -27
  238. package/src/format/image/avif/heif/parse_avif_file.js +24 -0
  239. package/src/shade/RENDERER_CONTRACT.md +12 -7
  240. package/src/shade/playground/caldera/README.md +529 -0
  241. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  242. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  243. package/src/shade/playground/caldera/caldera_format.js +241 -0
  244. package/src/shade/playground/caldera/index.html +126 -0
  245. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  246. package/src/shade/playground/caldera/main.js +1565 -0
  247. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  248. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  249. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  250. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  251. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  252. package/src/shade/playground/vgeo_runtime/README.md +5 -3
  253. package/src/shade/playground/vgeo_runtime/main.js +3 -2
  254. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
  255. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
  256. package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
  257. package/src/shade/playground/vgeo_scene/README.md +103 -24
  258. package/src/shade/playground/vgeo_scene/main.js +525 -24
  259. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  260. package/src/shade/renderer/GraphicsContext.js +6 -0
  261. package/src/shade/renderer/Renderer.d.ts +2 -0
  262. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  263. package/src/shade/renderer/Renderer.js +23 -0
  264. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  265. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  266. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  267. package/src/shade/renderer/buffer/table/GPUTypedTable.js +14 -0
  268. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
  269. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  270. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  271. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  272. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  273. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  274. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  275. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  276. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  277. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  278. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  279. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  280. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  281. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  282. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  283. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  284. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
  285. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +76 -16
  286. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
  287. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +448 -0
  288. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +44 -7
  289. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  290. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +48 -9
  291. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  292. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  293. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  294. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  295. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  296. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  297. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  298. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  299. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  300. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  301. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  303. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
  304. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
  306. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  307. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  309. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  310. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  311. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  312. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  313. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  314. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  315. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  316. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  317. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  318. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
  319. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
  320. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
  321. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  322. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  323. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  324. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  325. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  326. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  327. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  328. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  329. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  330. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  331. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  332. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  333. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  334. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  335. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  336. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  337. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  338. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  339. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  340. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  341. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +74 -0
  342. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  343. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +78 -0
  344. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
  345. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
  346. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
  347. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  348. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  349. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  350. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  351. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  352. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  353. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  354. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  355. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  356. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +32 -7
  357. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
  358. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +243 -24
  359. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
  360. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
  361. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
  362. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +5 -0
  363. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
  364. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +13 -1
  365. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  366. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  367. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  368. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
  369. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
  370. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
  371. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
  372. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  373. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
  374. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
  375. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
  376. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
  377. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
  378. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
  379. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
  380. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
  381. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
  382. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
  383. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
  384. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
  385. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
  386. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  387. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  388. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +27 -4
  389. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  390. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  391. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  392. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  393. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  394. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  395. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  396. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  397. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  398. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  399. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  400. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  401. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  402. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  403. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  404. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  405. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  406. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  407. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  408. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  409. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  410. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  411. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  412. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  413. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  414. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  415. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  416. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  417. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  418. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  419. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  420. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  421. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  422. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  423. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  424. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  425. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  426. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  427. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  428. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  429. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  430. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  431. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  432. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  433. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  434. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  435. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  436. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  437. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  438. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  439. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  440. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  441. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  442. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  443. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  444. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  445. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  446. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  447. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
  448. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  449. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +8 -4
  450. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  451. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  452. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  453. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  454. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  455. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  456. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  457. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  458. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  459. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  460. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  461. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  462. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  463. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  464. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  465. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  466. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  467. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  468. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  469. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  470. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +111 -33
  471. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  472. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  473. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +112 -42
  474. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  475. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  476. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +51 -21
  477. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  478. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  479. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  480. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  481. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +14 -1
  482. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  483. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +34 -0
  484. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  485. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
  486. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  487. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +47 -19
  488. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  489. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  490. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  491. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  492. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  493. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  494. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  495. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  496. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  497. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  498. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  499. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  500. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  501. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
  502. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +12 -3
  503. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  504. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  505. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  506. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  507. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  508. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  509. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  510. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  511. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.d.ts.map +1 -1
  512. package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.js +7 -1
  513. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  514. package/src/shade/renderer/lightmap/GPULightMap.js +349 -336
  515. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  516. package/src/shade/renderer/loader/gltf/load_gltf.js +1137 -1128
  517. package/src/shade/renderer/particles/DESIGN.md +14 -5
  518. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +25 -10
  519. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  520. package/src/shade/renderer/particles/GPUParticleSystem.js +182 -38
  521. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  522. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +16 -10
  523. package/src/shade/renderer/particles/graph_particles.d.ts +4 -2
  524. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  525. package/src/shade/renderer/particles/graph_particles.js +8 -2
  526. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  527. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +8 -2
  528. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  529. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +10 -4
  530. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  531. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  532. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +31 -0
  533. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +1 -0
  534. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.js +62 -0
  535. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  536. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  537. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +13 -0
  538. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  539. package/src/shade/renderer/particles/vm/ParticleVMReference.js +95 -17
  540. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  541. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  542. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +21 -0
  543. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -0
  544. package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +28 -0
  545. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  546. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  547. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  548. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  549. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  550. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  551. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  552. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  553. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  554. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  555. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  556. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  557. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  558. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  559. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  560. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  561. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  562. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  563. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  564. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  565. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  566. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  567. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  568. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  569. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  570. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  571. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  572. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  573. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  574. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  575. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  576. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  577. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +19 -2
  578. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  579. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +4 -8
  580. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  581. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -8
  582. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  583. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +19 -2
  584. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  585. package/src/shade/renderer/shader/type/WebGPUStruct.js +12 -0
  586. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  587. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  588. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  589. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  590. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  591. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  592. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts +8 -2
  593. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
  594. package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +41 -6
  595. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2383 -2356
  596. package/src/view/tooltip/DomTooltipManager.d.ts +7 -0
  597. package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
  598. package/src/view/tooltip/DomTooltipManager.js +22 -0
  599. package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
  600. package/src/view/tooltip/DomTooltipObserver.js +13 -3
  601. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  602. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  603. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  604. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  605. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  606. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  607. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  608. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  609. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  610. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  611. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
  612. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  613. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  614. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  615. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
  616. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  617. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  618. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  619. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
  620. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  621. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
  622. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  623. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
  624. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  625. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  626. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  627. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
  628. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  629. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
  630. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  631. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
  632. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  633. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  634. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  635. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
  636. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  637. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
  638. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  639. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  640. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  641. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
  642. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  643. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
  644. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  645. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  646. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  647. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  648. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  649. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
  650. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  651. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
  652. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  653. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
  654. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  655. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
  656. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  657. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
  658. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  659. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
  660. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  661. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
  662. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  663. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
  664. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  665. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  666. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  667. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  668. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  669. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  670. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  671. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  672. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  673. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  674. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  675. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  676. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  677. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  678. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  679. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  680. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  681. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  682. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  683. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  684. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  685. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
@@ -284,7 +284,12 @@ export function evaluate_particle_operation(op, a, b, c) {
284
284
  // the whole of what the option trades; anything an executor could disagree about by more
285
285
  // than a rounding is refused below rather than folded.
286
286
  case VM_OP.MAD: return Math.fround(a * b + c);
287
- case VM_OP.MIX: return Math.fround(a + (b - a) * c);
287
+ case VM_OP.MIX: {
288
+ const from = Math.fround(a * Math.fround(1 - c));
289
+ const to = Math.fround(b * c);
290
+
291
+ return Math.fround(from + to);
292
+ }
288
293
  case VM_OP.SIN: return Math.fround(Math.sin(a));
289
294
  case VM_OP.COS: return Math.fround(Math.cos(a));
290
295
  case VM_OP.TAN: return Math.fround(Math.tan(a));
@@ -294,7 +299,7 @@ export function evaluate_particle_operation(op, a, b, c) {
294
299
  case VM_OP.LOG: return Math.fround(Math.log(a));
295
300
  // `1 / sqrt(a)` for `a <= 0` is an infinity or a `NaN`, and `finite` drops both — the same
296
301
  // rule that keeps `SQRT` next door out of trouble, so there is nothing to say here.
297
- case VM_OP.RSQRT: return Math.fround(1 / Math.sqrt(a));
302
+ case VM_OP.RSQRT: return Math.fround(1 / Math.fround(Math.sqrt(a)));
298
303
  // WGSL's `pow` is `exp2(e2 * log2(e1))`, which is a `NaN` for every base at or below zero
299
304
  // — including `pow(0, 0)`, where JS says 1. A fold that turned the hardware's `NaN` into a
300
305
  // number would not be a rounding, so the non-positive bases are not folded at all.
@@ -306,9 +311,10 @@ export function evaluate_particle_operation(op, a, b, c) {
306
311
  return NaN;
307
312
  }
308
313
 
309
- const t = Math.min(Math.max((c - a) / (b - a), 0), 1);
314
+ const span = Math.fround(b - a);
315
+ const t = Math.min(Math.max(Math.fround(Math.fround(c - a) / span), 0), 1);
310
316
 
311
- return Math.fround(t * t * (3 - 2 * t));
317
+ return Math.fround(Math.fround(t * t) * Math.fround(3 - Math.fround(2 * t)));
312
318
  }
313
319
  // `atan2(0, 0)` is 0 in JS and left to the implementation in WGSL. Every other pair is an
314
320
  // angle both agree on to a rounding.
@@ -1 +1 @@
1
- {"version":3,"file":"shader_particle_emit.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,kDAA8E;AAE9E;;;;;;;;GAQG;AACH,4BAFU,YAAY,CAOK;AAuD3B,iDAIG;6BA3G0B,mCAAmC;8BAGlC,+BAA+B"}
1
+ {"version":3,"file":"shader_particle_emit.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,kDAA8E;AAE9E;;;;;;;;GAQG;AACH,4BAFU,YAAY,CAOK;AA2D3B,iDAIG;6BAhH0B,mCAAmC;8BAIlC,+BAA+B"}
@@ -3,6 +3,7 @@ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
3
3
  import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
4
4
  import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
5
5
  import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
6
+ import { chunk_grid3d_to_index } from "../../shader/chunk/grid/chunk_grid3d_to_index.js";
6
7
  import { ComputeShader } from "../../shader/ComputeShader.js";
7
8
  import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
8
9
  import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
@@ -52,9 +53,8 @@ export const EMIT_SETTINGS = WebGPUStruct.from({
52
53
 
53
54
  const resources = new ShaderResourceSetDescriptor();
54
55
 
55
- // TODO(chrome-153): uniform, not immediate — Dawn 153 overwrites immediate data on
56
- // dispatchWorkgroupsIndirect, so this reads garbage. The graph pass turns the plain
57
- // value into a transient uniform, so no call site changes.
56
+ resources.setImmediate('settings', EMIT_SETTINGS);
57
+
58
58
  resources.createGroup()
59
59
  .addStorageBuffer("scene_database", WebGPUArray.u32, false)
60
60
  .addStorageBuffer("emitter_database", WebGPUArray.u32, false)
@@ -63,9 +63,7 @@ resources.createGroup()
63
63
  .addStorageBuffer("pool", WebGPUArray.u32, true)
64
64
  .addStorageBuffer("alive_out", WebGPUArray.u32, true)
65
65
  .addStorageBuffer("dead", WebGPUArray.u32, true)
66
- .addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true)
67
- // last in the group, so the storage bindings keep the indices the specs read by
68
- .addUniform('settings', EMIT_SETTINGS);
66
+ .addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true);
69
67
 
70
68
  const body = CodeChunk.from(
71
69
  /* language=wgsl */
@@ -74,8 +72,14 @@ const COUNTER_ALIVE : u32 = ${PARTICLE_COUNTER.ALIVE}u;
74
72
  const COUNTER_DEAD : u32 = ${PARTICLE_COUNTER.DEAD}u;
75
73
 
76
74
  @compute @workgroup_size(${PARTICLE_EMIT_WORKGROUP_SIZE}, 1, 1)
77
- fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
78
- let i = gid.x;
75
+ fn main(
76
+ @builtin(workgroup_id) workgroup_id : vec3<u32>,
77
+ @builtin(num_workgroups) group_count : vec3<u32>,
78
+ @builtin(local_invocation_index) local_index : u32,
79
+ ) {
80
+ // shader_prefix_sum_to_command folds its count over three dimensions, so the newborn this lane
81
+ // belongs to is the flattened workgroup, not gid.x. Identical while y and z are 1.
82
+ let i = grid3d_to_index(workgroup_id, group_count.xy) * ${PARTICLE_EMIT_WORKGROUP_SIZE}u + local_index;
79
83
 
80
84
  let assignment = particle_emit_assignment(&spawn_prefix.elements, spawn_prefix.count, i);
81
85
  if (!assignment.valid) { return; }
@@ -99,6 +103,7 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
99
103
  alive_out[a] = slot;
100
104
  }
101
105
  `, [
106
+ chunk_grid3d_to_index,
102
107
  chunk_particle_emit_step,
103
108
  chunk_particle_vm_registers_fast,
104
109
  ]);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The free list as a fresh pool leaves it: every slot free, `dead[i] = i`, bottom to top.
3
+ *
4
+ * It is a stack of slot indices — the emit pass pops `dead[--DEAD]` — so the order within it is
5
+ * arbitrary and identity is simply the cheapest arrangement to write. What matters is that every
6
+ * slot appears exactly once: a repeat hands two particles one record, and a gap strands a slot for
7
+ * the lifetime of the system.
8
+ *
9
+ * ## Why this is a pass and not a host write
10
+ *
11
+ * Zero is not a valid free list — `dead[i] = 0` for every `i` is the same slot half a million times
12
+ * over — so the buffer WebGPU hands back has to be written before the first emit. Writing it from
13
+ * the host means a typed array the size of the list (2 MiB at the default capacity), a loop over
14
+ * every element of it, and a staged upload, all on the frame the system is constructed. Here it is
15
+ * one store per slot with no host memory involved at all, and it leaves the free list `STORAGE`
16
+ * only: nothing else ever writes it from the host, so it needs no `COPY_DST` and stays off the
17
+ * driver's upload-friendly — and slower — path.
18
+ *
19
+ * ## Bounded launch, strided loop
20
+ *
21
+ * The pool capacity belongs to whoever constructs the system, and `capacity / workgroup_size` can
22
+ * pass `maxComputeWorkgroupsPerDimension` — a validation error for a direct dispatch, and worse
23
+ * than that for the indirect ones elsewhere in the engine, which simply do not run. So the caller
24
+ * clamps the launch and every lane strides through the list by the whole grid: the fill covers any
25
+ * capacity, and a grid that happens to cover it in one pass costs one comparison to find out.
26
+ */
27
+ /** Lanes per workgroup. One store each, so this is sized for occupancy and nothing else. */
28
+ export const PARTICLE_INIT_FREE_LIST_WORKGROUP_SIZE: 256;
29
+ export const shader_particle_init_free_list: ComputeShader;
30
+ import { ComputeShader } from "../../shader/ComputeShader.js";
31
+ //# sourceMappingURL=shader_particle_init_free_list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_particle_init_free_list.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_init_free_list.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,4FAA4F;AAC5F,yDAA0D;AAQ1D,2DAmBG;8BA3D2B,+BAA+B"}
@@ -0,0 +1,62 @@
1
+ import { u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
3
+ import { ComputeShader } from "../../shader/ComputeShader.js";
4
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
5
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
6
+
7
+ /**
8
+ * The free list as a fresh pool leaves it: every slot free, `dead[i] = i`, bottom to top.
9
+ *
10
+ * It is a stack of slot indices — the emit pass pops `dead[--DEAD]` — so the order within it is
11
+ * arbitrary and identity is simply the cheapest arrangement to write. What matters is that every
12
+ * slot appears exactly once: a repeat hands two particles one record, and a gap strands a slot for
13
+ * the lifetime of the system.
14
+ *
15
+ * ## Why this is a pass and not a host write
16
+ *
17
+ * Zero is not a valid free list — `dead[i] = 0` for every `i` is the same slot half a million times
18
+ * over — so the buffer WebGPU hands back has to be written before the first emit. Writing it from
19
+ * the host means a typed array the size of the list (2 MiB at the default capacity), a loop over
20
+ * every element of it, and a staged upload, all on the frame the system is constructed. Here it is
21
+ * one store per slot with no host memory involved at all, and it leaves the free list `STORAGE`
22
+ * only: nothing else ever writes it from the host, so it needs no `COPY_DST` and stays off the
23
+ * driver's upload-friendly — and slower — path.
24
+ *
25
+ * ## Bounded launch, strided loop
26
+ *
27
+ * The pool capacity belongs to whoever constructs the system, and `capacity / workgroup_size` can
28
+ * pass `maxComputeWorkgroupsPerDimension` — a validation error for a direct dispatch, and worse
29
+ * than that for the indirect ones elsewhere in the engine, which simply do not run. So the caller
30
+ * clamps the launch and every lane strides through the list by the whole grid: the fill covers any
31
+ * capacity, and a grid that happens to cover it in one pass costs one comparison to find out.
32
+ */
33
+
34
+ /** Lanes per workgroup. One store each, so this is sized for occupancy and nothing else. */
35
+ export const PARTICLE_INIT_FREE_LIST_WORKGROUP_SIZE = 256;
36
+
37
+ const resources = new ShaderResourceSetDescriptor();
38
+
39
+ // per-dispatch, four bytes, read-only: immediate data rather than a uniform buffer holding one u32
40
+ resources.setImmediate("u_capacity", u32);
41
+ resources.createGroup().addStorageBuffer("dead", WebGPUArray.u32, true);
42
+
43
+ export const shader_particle_init_free_list = ComputeShader.from({
44
+ label: "Particle Init Free List",
45
+ resources,
46
+ body: CodeChunk.from(
47
+ /* language=wgsl */
48
+ `
49
+ @compute @workgroup_size(${PARTICLE_INIT_FREE_LIST_WORKGROUP_SIZE}, 1, 1)
50
+ fn main(
51
+ @builtin(global_invocation_id) global_id : vec3<u32>,
52
+ @builtin(num_workgroups) group_count : vec3<u32>,
53
+ ) {
54
+ // The grid may be smaller than the list; every lane keeps taking the next slot a whole grid on.
55
+ let stride = group_count.x * ${PARTICLE_INIT_FREE_LIST_WORKGROUP_SIZE}u;
56
+
57
+ for (var slot = global_id.x; slot < u_capacity; slot += stride) {
58
+ dead[slot] = slot;
59
+ }
60
+ }
61
+ `),
62
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";AAuDA;;;;;GAKG;AACH,gCAFU,YAAY,CAMS;AAyD/B,qDAIG;iDAvH8C,yBAAyB;6BAJ7C,mCAAmC;8BAClC,+BAA+B"}
1
+ {"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";AAuDA;;;;;GAKG;AACH,gCAFU,YAAY,CAMS;AAsD/B,qDAIG;iDApH8C,yBAAyB;6BAJ7C,mCAAmC;8BAClC,+BAA+B"}
@@ -67,9 +67,8 @@ export const SIMULATE_SETTINGS = WebGPUStruct.from({
67
67
 
68
68
  const resources = new ShaderResourceSetDescriptor();
69
69
 
70
- // TODO(chrome-153): uniform, not immediate — Dawn 153 overwrites immediate data on
71
- // dispatchWorkgroupsIndirect, so this reads garbage. The graph pass turns the plain
72
- // value into a transient uniform, so no call site changes.
70
+ resources.setImmediate('settings', SIMULATE_SETTINGS);
71
+
73
72
  resources.createGroup()
74
73
  .addStorageBuffer("scene_database", WebGPUArray.u32, false)
75
74
  .addStorageBuffer("emitter_database", WebGPUArray.u32, false)
@@ -78,9 +77,7 @@ resources.createGroup()
78
77
  .addStorageBuffer("sim_list", WebGPUArray.u32, false)
79
78
  .addStorageBuffer("alive_out", WebGPUArray.u32, true)
80
79
  .addStorageBuffer("dead", WebGPUArray.u32, true)
81
- .addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true)
82
- // last in the group, so the storage bindings keep the indices the specs read by
83
- .addUniform('settings', SIMULATE_SETTINGS);
80
+ .addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true);
84
81
 
85
82
 
86
83
  const body = CodeChunk.from(/* language=wgsl */ `
@@ -29,6 +29,19 @@ export function u32_to_unit_f32(u: number): number;
29
29
  * so a source may overlap the destination in any way and still mean what it held before the
30
30
  * instruction.
31
31
  *
32
+ * ## Every step is an f32 step
33
+ *
34
+ * The register file is `f32`, and so is the shader's. An opcode that takes more than one arithmetic
35
+ * step to reach its result therefore rounds at every one of them, through `Math.fround`, rather
36
+ * than computing wide and rounding on the way out. Rounding only at the end gives f32 RESULTS
37
+ * without f32 RANGE, and the range is where the two executors part company: a product that is
38
+ * `inf` on the device is an ordinary number in `f64`, a difference that saturates there is finite
39
+ * here, and neither is a rounding apart. `CROSS` answered 0 where the device answers NaN, and
40
+ * `SMOOTHSTEP` answered the midpoint where the device answers the near edge.
41
+ *
42
+ * Two opcodes are deliberately outside that rule, and each says why where it is written: `MAD`,
43
+ * which models the fused product, and `FRACT`, whose subtraction cannot round twice.
44
+ *
32
45
  * @param {object} params
33
46
  * @param {Uint32Array} params.words instruction words for the section (SPAWN or UPDATE)
34
47
  * @param {Float32Array} params.constants constant pool, one float per word
@@ -1 +1 @@
1
- {"version":3,"file":"ParticleVMReference.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/ParticleVMReference.js"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,gCAHW,MAAM,GACJ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAW5C;AAED;;;;;GAKG;AACH,mCAHW,MAAM,GACJ,MAAM,CAIlB;AA8DD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAR+B,KAAK,EAAzB,WAAW;IACU,SAAS,EAA9B,YAAY;IACG,cAAc,EAA7B,MAAM;IACc,MAAM,EAA1B,WAAW;IACS,QAAQ,GAA5B,MAAM,EAAE,EAAE;IACM,SAAS,GAAzB,MAAM;IACJ;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAuRlD"}
1
+ {"version":3,"file":"ParticleVMReference.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/vm/ParticleVMReference.js"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,gCAHW,MAAM,GACJ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAW5C;AAED;;;;;GAKG;AACH,mCAHW,MAAM,GACJ,MAAM,CAIlB;AA8DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH;IAR+B,KAAK,EAAzB,WAAW;IACU,SAAS,EAA9B,YAAY;IACG,cAAc,EAA7B,MAAM;IACc,MAAM,EAA1B,WAAW;IACS,QAAQ,GAA5B,MAAM,EAAE,EAAE;IACM,SAAS,GAAzB,MAAM;IACJ;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAyUlD"}
@@ -125,6 +125,19 @@ const LITERAL_U32 = new Uint32Array(LITERAL_F32.buffer);
125
125
  * so a source may overlap the destination in any way and still mean what it held before the
126
126
  * instruction.
127
127
  *
128
+ * ## Every step is an f32 step
129
+ *
130
+ * The register file is `f32`, and so is the shader's. An opcode that takes more than one arithmetic
131
+ * step to reach its result therefore rounds at every one of them, through `Math.fround`, rather
132
+ * than computing wide and rounding on the way out. Rounding only at the end gives f32 RESULTS
133
+ * without f32 RANGE, and the range is where the two executors part company: a product that is
134
+ * `inf` on the device is an ordinary number in `f64`, a difference that saturates there is finite
135
+ * here, and neither is a rounding apart. `CROSS` answered 0 where the device answers NaN, and
136
+ * `SMOOTHSTEP` answered the midpoint where the device answers the near edge.
137
+ *
138
+ * Two opcodes are deliberately outside that rule, and each says why where it is written: `MAD`,
139
+ * which models the fused product, and `FRACT`, whose subtraction cannot round twice.
140
+ *
128
141
  * @param {object} params
129
142
  * @param {Uint32Array} params.words instruction words for the section (SPAWN or UPDATE)
130
143
  * @param {Float32Array} params.constants constant pool, one float per word
@@ -263,6 +276,18 @@ export function execute_particle_vm({
263
276
  case DIV:
264
277
  for (let i = 0; i < w; i++) d[i] = a[i] / b[i];
265
278
  break;
279
+ // The exception to the rule above, and the only one that is a choice. `MAD` models the
280
+ // FUSED form: the product reaches the addition unrounded, which is what makes it more
281
+ // than `MUL` then `ADD`. {@link ../optimizer/pass_peephole.js} refuses to fuse that
282
+ // pair into a `MAD` by default for exactly this reason, and
283
+ // {@link ../optimizer/particle_integer_bounds.js} exists only to prove the cases where
284
+ // the product needs no rounding and the two forms therefore agree; rounding it here
285
+ // would make both of those dead weight.
286
+ //
287
+ // The shader spells this `a * b + c`, which a driver is free to contract into an FMA
288
+ // or not, so it is a reading rather than a certainty — `VM_OP.MAD` is INEXACT in
289
+ // {@link ../optimizer/particle_vm_semantics.js} to say so. Spelling the shader
290
+ // `fma(a, b, c)` would settle it in this reading's favour on every device.
266
291
  case MAD:
267
292
  for (let i = 0; i < w; i++) d[i] = a[i] * b[i] + c[i];
268
293
  break;
@@ -272,8 +297,21 @@ export function execute_particle_vm({
272
297
  case MAX:
273
298
  for (let i = 0; i < w; i++) d[i] = Math.max(a[i], b[i]);
274
299
  break;
300
+ // WGSL defines `mix(e1, e2, e3)` as `e1 * (1 - e3) + e2 * e3`, and this used to spell
301
+ // it as the lerp `a + (b - a) * c`. The two are the same number only where the span
302
+ // `b - a` loses nothing, and at the ends of the f32 range it loses everything:
303
+ // `mix(1e20, 1, 1)` is 1 on the device and was 0 here, because `1 - 1e20` IS `-1e20`
304
+ // in f32. Rounding the lerp's steps without changing its shape would have made it
305
+ // worse — the span of (3e38, -3e38) is not an f32 at all, so a blend both of whose
306
+ // ends are finite would have come out infinite. Scaling each end on its own is what
307
+ // the shader does and it cannot overflow where the result does not.
275
308
  case MIX:
276
- for (let i = 0; i < w; i++) d[i] = a[i] + (b[i] - a[i]) * c[i];
309
+ for (let i = 0; i < w; i++) {
310
+ const from = Math.fround(a[i] * Math.fround(1 - c[i]));
311
+ const to = Math.fround(b[i] * c[i]);
312
+
313
+ d[i] = Math.fround(from + to);
314
+ }
277
315
  break;
278
316
  case CLAMP:
279
317
  for (let i = 0; i < w; i++) d[i] = Math.min(Math.max(a[i], b[i]), c[i]);
@@ -288,6 +326,12 @@ export function execute_particle_vm({
288
326
  case FLOOR:
289
327
  for (let i = 0; i < w; i++) d[i] = Math.floor(a[i]);
290
328
  break;
329
+ // The other exception, and this one is free: `a - floor(a)` cannot round twice. For
330
+ // |a| >= 1 the fractional part is a run of at most 23 of a's own mantissa bits and is
331
+ // an f32 exactly; for |a| < 1 it is a itself, or `1 + a`, which only becomes inexact
332
+ // in f64 once |a| falls below about 2^-29 — by which point it is far inside the last
333
+ // f32 step below 1 and rounds to 1.0 either way. The two conditions a double rounding
334
+ // would need cannot hold at once, which the spec checks rather than assumes.
291
335
  case FRACT:
292
336
  for (let i = 0; i < w; i++) d[i] = a[i] - Math.floor(a[i]);
293
337
  break;
@@ -316,9 +360,13 @@ export function execute_particle_vm({
316
360
  for (let i = 0; i < w; i++) d[i] = smoothstep(a[i], b[i], c[i]);
317
361
  break;
318
362
  // WGSL's `inverseSqrt`. Spelled as the reciprocal of a root rather than approximated,
319
- // because the reference is the definition the hardware's estimate is measured against.
363
+ // because the reference is the definition the hardware's estimate is measured against
364
+ // — which is also why the root is rounded before the division reads it. A definition
365
+ // carried out in f64 is not the thing `inverseSqrt` is allowed to be 2 ULP away from:
366
+ // 1 / sqrt(0.0009) is 33.33333206176758 taken wide and 33.333335876464844 taken the
367
+ // way the device takes it, and the slack is measured from the second.
320
368
  case RSQRT:
321
- for (let i = 0; i < w; i++) d[i] = 1 / Math.sqrt(a[i]);
369
+ for (let i = 0; i < w; i++) d[i] = Math.fround(1 / Math.fround(Math.sqrt(a[i])));
322
370
  break;
323
371
  case TAN:
324
372
  for (let i = 0; i < w; i++) d[i] = Math.tan(a[i]);
@@ -336,40 +384,55 @@ export function execute_particle_vm({
336
384
 
337
385
  // The reductions write a single lane; whatever wants the result wider reads it through
338
386
  // an `.xxxx` swizzle.
387
+ //
388
+ // Every step goes through `Math.fround`, because a plain `let sum = 0` is an f64
389
+ // accumulator and only the store into the register file rounds — which gives f32
390
+ // RESULTS without f32 RANGE, and the range is not recovered at the end. The shader
391
+ // computes `dot(a, a)` entirely in f32, where 1e20 squared is already `inf` and
392
+ // 1e-25 squared is already zero, so the two sides answered `inf` against 1.00000002e20
393
+ // and, through NORMALIZE's `len > 0`, the zero vector against a unit one.
339
394
  case DOT: {
340
395
  let dp = 0;
341
- for (let i = 0; i < w; i++) dp += a[i] * b[i];
396
+ for (let i = 0; i < w; i++) dp = Math.fround(dp + Math.fround(a[i] * b[i]));
342
397
  d[0] = dp;
343
398
  break;
344
399
  }
400
+ // Six products and three differences, every one of them in f32. Taken wide, a lane
401
+ // whose two products both overflow cancelled to exactly 0 — the mathematically right
402
+ // answer for a vector crossed with itself — where the device subtracts `inf - inf` and
403
+ // gets NaN. a = b = (0, 1e20, 1e20) is the shortest witness, and a NaN that exists
404
+ // only on the GPU is the worst shape this takes: invisible in the editor preview, and
405
+ // loose in a position attribute from the first frame it appears.
345
406
  case CROSS:
346
- d[0] = a[1] * b[2] - a[2] * b[1];
347
- d[1] = a[2] * b[0] - a[0] * b[2];
348
- d[2] = a[0] * b[1] - a[1] * b[0];
407
+ d[0] = Math.fround(Math.fround(a[1] * b[2]) - Math.fround(a[2] * b[1]));
408
+ d[1] = Math.fround(Math.fround(a[2] * b[0]) - Math.fround(a[0] * b[2]));
409
+ d[2] = Math.fround(Math.fround(a[0] * b[1]) - Math.fround(a[1] * b[0]));
349
410
  // A fourth lane, if asked for, is the zero the opcode used to append.
350
411
  d[3] = 0;
351
412
  break;
352
413
  case LENGTH: {
353
414
  let sum = 0;
354
- for (let i = 0; i < w; i++) sum += a[i] * a[i];
355
- d[0] = Math.sqrt(sum);
415
+ for (let i = 0; i < w; i++) sum = Math.fround(sum + Math.fround(a[i] * a[i]));
416
+ d[0] = Math.fround(Math.sqrt(sum));
356
417
  break;
357
418
  }
358
419
  case NORMALIZE: {
359
420
  let sum = 0;
360
- for (let i = 0; i < w; i++) sum += a[i] * a[i];
361
- const len = Math.sqrt(sum);
362
- const inv = len > 0 ? 1 / len : 0;
421
+ for (let i = 0; i < w; i++) sum = Math.fround(sum + Math.fround(a[i] * a[i]));
422
+ const len = Math.fround(Math.sqrt(sum));
423
+ // the shader's `select(0.0, 1.0 / len, len > 0.0)` — the same test, over a length
424
+ // that has now underflowed on the same inputs
425
+ const inv = len > 0 ? Math.fround(1 / len) : 0;
363
426
  for (let i = 0; i < w; i++) d[i] = a[i] * inv;
364
427
  break;
365
428
  }
366
429
  case DISTANCE: {
367
430
  let sum = 0;
368
431
  for (let i = 0; i < w; i++) {
369
- const e = a[i] - b[i];
370
- sum += e * e;
432
+ const e = Math.fround(a[i] - b[i]);
433
+ sum = Math.fround(sum + Math.fround(e * e));
371
434
  }
372
- d[0] = Math.sqrt(sum);
435
+ d[0] = Math.fround(Math.sqrt(sum));
373
436
  break;
374
437
  }
375
438
 
@@ -414,6 +477,18 @@ export function execute_particle_vm({
414
477
  }
415
478
 
416
479
  /**
480
+ * WGSL's `smoothstep`, which is `t * t * (3 - 2t)` over `t = clamp((x - low) / (high - low), 0, 1)`.
481
+ *
482
+ * Every step is an f32 step, for the reason the executor's docblock gives, and here it is the SPAN
483
+ * that carries it: with the edges at ±3e38 the divisor is 6e38, which is `inf` in f32, so the
484
+ * device divides by an infinity, gets 0, and returns the near edge. Taken wide the divisor is
485
+ * finite and the answer was the midpoint — a ramp authored across a range wider than f32 reaches
486
+ * read as half-way in the editor preview and as not started at all in the game.
487
+ *
488
+ * The equal-edges guard stands in for a division by zero the device would do instead. It is the one
489
+ * place this function is not the shader's arithmetic, and it only differs from it at `x === edge0`,
490
+ * where the device's `0 / 0` is a NaN that WGSL does not define the clamp of.
491
+ *
417
492
  * @param {number} edge0
418
493
  * @param {number} edge1
419
494
  * @param {number} x
@@ -421,6 +496,9 @@ export function execute_particle_vm({
421
496
  */
422
497
  function smoothstep(edge0, edge1, x) {
423
498
  if (edge0 === edge1) return x < edge0 ? 0 : 1;
424
- const t = Math.min(Math.max((x - edge0) / (edge1 - edge0), 0), 1);
425
- return t * t * (3 - 2 * t);
499
+
500
+ const span = Math.fround(edge1 - edge0);
501
+ const t = Math.min(Math.max(Math.fround(Math.fround(x - edge0) / span), 0), 1);
502
+
503
+ return Math.fround(Math.fround(t * t) * Math.fround(3 - Math.fround(2 * t)));
426
504
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prepare_meshlet_draw_commands_by_material.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;GAeG;AACH,uKAJa;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,wBAAwB,EAAE,MAAM,CAAA;CAAC,CAwUnH"}
1
+ {"version":3,"file":"prepare_meshlet_draw_commands_by_material.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;GAeG;AACH,uKAJa;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,wBAAwB,EAAE,MAAM,CAAA;CAAC,CAgUnH"}
@@ -2,7 +2,7 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { ceilPowerOfTwo } from "../../../../core/binary/operations/ceilPowerOfTwo.js";
3
3
  import { round_up } from "../../../../core/math/round_up.js";
4
4
  import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
5
- import { u32, vec2u } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
5
+ import { u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
6
6
  import { STRUCT_UNINDEXED_DRAW_COMMAND } from "../../gpu_primitive/indirect/STRUCT_UNINDEXED_DRAW_COMMAND.js";
7
7
  import { cpu_build_hash_table } from "../../gpu_primitive/hash_table/cpu_build_hash_table.js";
8
8
  import { graph_prefix_scan_csdldf } from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
@@ -22,7 +22,7 @@ import { shader_count_meshlets_by_material } from "./shader_count_meshlets_by_ma
22
22
  import {
23
23
  shader_make_meshlet_indirect_draw_commands_by_material
24
24
  } from "./shader_make_meshlet_indirect_draw_commands_by_material.js";
25
- import { PUSH_CONSTANTS, shader_read_out_bucket } from "./shader_read_out_bucket.js";
25
+ import { shader_read_out_bucket } from "./shader_read_out_bucket.js";
26
26
  import { shader_sort_meshlets_by_material } from "./shader_sort_meshlets_by_material.js";
27
27
 
28
28
  /**
@@ -83,16 +83,11 @@ export function graph_prepare_meshlet_draw_commands_by_material({
83
83
  0
84
84
  );
85
85
 
86
- // TODO(chrome-153): transient uniform, not an immediate value — see the shader.
87
- const u_settings = encoder.allocateTransientValueBuffer(PUSH_CONSTANTS, {
88
- bucket_id,
89
- });
90
-
91
86
  shader_read_out_bucket.dispatchIndirect({
92
87
  encoder,
93
88
  command,
94
89
  bindings: {
95
- settings: u_settings,
90
+ settings: { bucket_id },
96
91
  input: buckets_buffer,
97
92
  output,
98
93
  }
@@ -165,15 +160,12 @@ export function graph_prepare_meshlet_draw_commands_by_material({
165
160
  const hzb = resources.get(data.texture_hzb);
166
161
  const command = resources.get(data.command);
167
162
 
168
- // TODO(chrome-153): transient uniform, not an immediate value — see the shader.
169
- const u_resolution = encoder.allocateTransientValueBuffer(vec2u, resolution);
170
-
171
163
  shader_hzb_meshlet_filter_1way_full.dispatchIndirect({
172
164
  encoder,
173
165
  command,
174
166
  bindings: {
175
167
  camera: camera_state,
176
- resolution: u_resolution,
168
+ resolution,
177
169
  scene_database: scene.scene_database_buffer,
178
170
  meshlet_metadata: scene.geometries.meshlets.buffer_metadata,
179
171
  texture_hzb: hzb.obtainView(),
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Whether the scene has anything in an opaque rasterization bucket.
3
+ *
4
+ * The opaque path clears the visibility-buffer colour attachments and the depth attachment on its
5
+ * first draw, and it is the only thing that does — every later pass is recorded with `load`. So a
6
+ * scene whose materials are all alpha-tested or transparent, which is an ordinary thing (a
7
+ * foliage-only vegetation view, a glass preview, a point light whose only casters are billboards),
8
+ * used to draw over the previous frame's contents: geometry depth-tested against stale occluders,
9
+ * and every pixel the alpha-tested pass did not cover keeping last frame's mesh and triangle ids for
10
+ * the deferred shading to resolve as real surfaces.
11
+ *
12
+ * This is what lets the composer hand the clear to the first pass that will actually run.
13
+ *
14
+ * @param {Set<number>} active_buckets bucket ids any material in the scene asks for
15
+ * @returns {boolean}
16
+ *
17
+ * @author Alex Goldring
18
+ * @copyright Company Named Limited (c) 2026
19
+ */
20
+ export function rasterization_has_opaque_bucket(active_buckets: Set<number>): boolean;
21
+ //# sourceMappingURL=rasterization_has_opaque_bucket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rasterization_has_opaque_bucket.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,gEANW,IAAI,MAAM,CAAC,GACT,OAAO,CAWnB"}
@@ -0,0 +1,28 @@
1
+ import { rasterization_opaque_buckets } from "./rasterization_opaque_buckets.js";
2
+
3
+ /**
4
+ * Whether the scene has anything in an opaque rasterization bucket.
5
+ *
6
+ * The opaque path clears the visibility-buffer colour attachments and the depth attachment on its
7
+ * first draw, and it is the only thing that does — every later pass is recorded with `load`. So a
8
+ * scene whose materials are all alpha-tested or transparent, which is an ordinary thing (a
9
+ * foliage-only vegetation view, a glass preview, a point light whose only casters are billboards),
10
+ * used to draw over the previous frame's contents: geometry depth-tested against stale occluders,
11
+ * and every pixel the alpha-tested pass did not cover keeping last frame's mesh and triangle ids for
12
+ * the deferred shading to resolve as real surfaces.
13
+ *
14
+ * This is what lets the composer hand the clear to the first pass that will actually run.
15
+ *
16
+ * @param {Set<number>} active_buckets bucket ids any material in the scene asks for
17
+ * @returns {boolean}
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2026
21
+ */
22
+ export function rasterization_has_opaque_bucket(active_buckets) {
23
+ for (const _bucket of rasterization_opaque_buckets(active_buckets)) {
24
+ return true;
25
+ }
26
+
27
+ return false;
28
+ }
@@ -1,5 +1,3 @@
1
- export const PUSH_CONSTANTS: WebGPUStruct;
2
1
  export const shader_read_out_bucket: ComputeShader;
3
- import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
4
2
  import { ComputeShader } from "../../shader/ComputeShader.js";
5
3
  //# sourceMappingURL=shader_read_out_bucket.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shader_read_out_bucket.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js"],"names":[],"mappings":"AAcA,0CAEG;AAsCH,mDAIE;6BAzD2B,mCAAmC;8BAIlC,+BAA+B"}
1
+ {"version":3,"file":"shader_read_out_bucket.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js"],"names":[],"mappings":"AAqDA,mDAIE;8BApD4B,+BAA+B"}
@@ -12,14 +12,13 @@ import {
12
12
 
13
13
  const resources = new ShaderResourceSetDescriptor();
14
14
 
15
- export const PUSH_CONSTANTS = WebGPUStruct.from({
15
+ const PUSH_CONSTANTS = WebGPUStruct.from({
16
16
  bucket_id: u32,
17
17
  });
18
18
 
19
- // TODO(chrome-153): uniform, not immediate — Dawn 153 overwrites immediate data on
20
- // dispatchWorkgroupsIndirect, so this reads 65535 and culls everything. Revert 7c9700b87.
21
- resources.createGroup()
22
- .addUniform("settings", PUSH_CONSTANTS);
19
+ // per-dispatch, four bytes, read-only: immediate data rather than a pooled buffer, a staging copy
20
+ // and a bind group of its own
21
+ resources.setImmediate("settings", PUSH_CONSTANTS);
23
22
 
24
23
  resources.createGroup()
25
24
  .addStorageBuffer("input", RASTERIZATION_BUCKET_SORT_OUTPUT_STRUCT_READ)
@@ -1 +1 @@
1
- {"version":3,"file":"shader_hzb_mesh_filter_2way.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js"],"names":[],"mappings":"AA4GA,wDAIG;8BA/F2B,kCAAkC"}
1
+ {"version":3,"file":"shader_hzb_mesh_filter_2way.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js"],"names":[],"mappings":"AA8GA,wDAIG;8BAjG2B,kCAAkC"}
@@ -21,10 +21,12 @@ import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderReso
21
21
 
22
22
  const resources = new ShaderResourceSetDescriptor();
23
23
 
24
- // TODO(chrome-153): uniform, not immediate — Dawn 153 overwrites immediate data on
25
- // dispatchWorkgroupsIndirect, so this reads 65535 and culls everything. Revert 22893f0a7.
24
+ // per-dispatch, four bytes, read-only: immediate data rather than a uniform buffer — the same
25
+ // shape shader_read_out_bucket already uses. camera_previous stays a uniform: it is a scene buffer,
26
+ // not a per-dispatch value.
27
+ resources.setImmediate("bucket_index", U32_CONTAINER_STRUCT);
28
+
26
29
  resources.createGroup()
27
- .addUniform("bucket_index", U32_CONTAINER_STRUCT)
28
30
  .addStorageBuffer("bucket_data", RASTERIZATION_BUCKET_SORT_OUTPUT_STRUCT_READ)
29
31
 
30
32
  resources.createGroup()
@@ -1 +1 @@
1
- {"version":3,"file":"shader_hzb_meshlet_filter_1way.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js"],"names":[],"mappings":"AAyFA,2DAIG;8BA/E2B,kCAAkC"}
1
+ {"version":3,"file":"shader_hzb_meshlet_filter_1way.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js"],"names":[],"mappings":"AAgGA,2DAIG;8BArF2B,kCAAkC"}