@woosh/meep-engine 3.39.0 → 3.40.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 (367) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/engine/EngineHarness.d.ts.map +1 -1
  4. package/src/engine/EngineHarness.js +17 -4
  5. package/src/engine/asset/loaders/image/avif/threaded_image_encoder.js +1 -1
  6. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  7. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  8. package/src/engine/graphics/ecs/water/Water.d.ts +14 -17
  9. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  10. package/src/engine/graphics/ecs/water/Water.js +100 -110
  11. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
  12. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +36 -38
  13. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.d.ts +6 -0
  14. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.d.ts.map +1 -0
  15. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.js +10 -0
  16. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +3 -3
  17. package/src/engine/graphics/ecs/water/WaterWaves.js +46 -46
  18. package/src/engine/graphics/texture/sampler/sampler2d_to_avif.d.ts.map +1 -1
  19. package/src/engine/graphics/texture/sampler/sampler2d_to_avif.js +8 -5
  20. package/src/engine/graphics3/WaterSystem.d.ts +21 -74
  21. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  22. package/src/engine/graphics3/WaterSystem.js +174 -367
  23. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  24. package/src/format/image/avif/api/convert_to_rgba.d.ts +2 -2
  25. package/src/format/image/avif/api/convert_to_rgba.d.ts.map +1 -1
  26. package/src/format/image/avif/api/convert_to_rgba.js +10 -9
  27. package/src/format/image/avif/api/decode_avif.d.ts +2 -2
  28. package/src/format/image/avif/api/decode_avif.d.ts.map +1 -1
  29. package/src/format/image/avif/api/decode_avif.js +1 -1
  30. package/src/shade/playground/ssr_reprojection/README.md +111 -103
  31. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +68 -68
  32. package/src/shade/playground/ssr_reprojection/index.html +80 -79
  33. package/src/shade/playground/ssr_reprojection/main.js +256 -247
  34. package/src/shade/playground/ssr_variance/capture.js +96 -96
  35. package/src/shade/playground/ssr_variance/reference.js +78 -78
  36. package/src/shade/playground/vsm/README.md +96 -0
  37. package/src/shade/playground/vsm/VSMDebugOverlay.d.ts +49 -0
  38. package/src/shade/playground/vsm/VSMDebugOverlay.d.ts.map +1 -0
  39. package/src/shade/playground/vsm/VSMDebugOverlay.js +351 -0
  40. package/src/shade/playground/vsm/clipmap_panel.d.ts +8 -0
  41. package/src/shade/playground/vsm/clipmap_panel.d.ts.map +1 -0
  42. package/src/shade/playground/vsm/clipmap_panel.js +138 -0
  43. package/src/shade/playground/vsm/index.html +170 -0
  44. package/src/shade/playground/vsm/main.d.ts +2 -0
  45. package/src/shade/playground/vsm/main.d.ts.map +1 -0
  46. package/src/shade/playground/vsm/main.js +389 -0
  47. package/src/shade/playground/vsm/scenes.d.ts +52 -0
  48. package/src/shade/playground/vsm/scenes.d.ts.map +1 -0
  49. package/src/shade/playground/vsm/scenes.js +320 -0
  50. package/src/shade/playground/vsm/verify_vsm.d.ts +38 -0
  51. package/src/shade/playground/vsm/verify_vsm.d.ts.map +1 -0
  52. package/src/shade/playground/vsm/verify_vsm.js +305 -0
  53. package/src/shade/playground/water_refraction/README.md +57 -9
  54. package/src/shade/playground/water_refraction/main.js +12 -3
  55. package/src/shade/playground/water_refraction/world.d.ts +1 -0
  56. package/src/shade/playground/water_refraction/world.d.ts.map +1 -1
  57. package/src/shade/playground/water_refraction/world.js +15 -5
  58. package/src/shade/renderer/Renderer.d.ts +19 -0
  59. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  60. package/src/shade/renderer/Renderer.js +72 -1
  61. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +8 -0
  62. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  63. package/src/shade/renderer/animation/GPUAnimationManager.js +18 -0
  64. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +7 -0
  65. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  66. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -0
  67. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts +3 -1
  68. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
  69. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +10 -1
  70. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.d.ts.map +1 -1
  71. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.js +28 -0
  72. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.d.ts.map +1 -1
  73. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.js +31 -1
  74. package/src/shade/renderer/geometry/MeshletGeometry.d.ts +3 -0
  75. package/src/shade/renderer/geometry/MeshletGeometry.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/MeshletGeometry.js +1 -0
  77. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  78. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +62 -4
  79. package/src/shade/renderer/light/environment/rgbe/parse_rgbe.d.ts +1 -1
  80. package/src/shade/renderer/light/environment/rgbe/parse_rgbe.js +2 -2
  81. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.d.ts +2 -2
  82. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.d.ts.map +1 -1
  83. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.js +6 -14
  84. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.d.ts.map +1 -1
  85. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.js +5 -1
  86. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  87. package/src/shade/renderer/medium/ParticipatingMedium.d.ts +3 -0
  88. package/src/shade/renderer/medium/ParticipatingMedium.d.ts.map +1 -1
  89. package/src/shade/renderer/medium/ParticipatingMedium.js +7 -0
  90. package/src/shade/renderer/postprocess/eye/shader_autoexposure_build_histogram.d.ts.map +1 -1
  91. package/src/shade/renderer/postprocess/eye/shader_autoexposure_build_histogram.js +5 -35
  92. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  93. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +12 -4
  94. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  95. package/src/shade/renderer/postprocess/ssr/SSR.js +36 -8
  96. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.d.ts +3 -0
  97. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.d.ts.map +1 -0
  98. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.js +2 -0
  99. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.d.ts +8 -0
  100. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.d.ts.map +1 -0
  101. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.js +40 -0
  102. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  103. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +150 -137
  104. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.d.ts +3 -0
  105. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.d.ts.map +1 -0
  106. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.js +44 -0
  107. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.d.ts +5 -0
  108. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.d.ts.map +1 -0
  109. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.js +35 -0
  110. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.d.ts +26 -0
  111. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.d.ts.map +1 -0
  112. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.js +42 -0
  113. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +1 -0
  114. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  115. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +113 -105
  116. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts +2 -0
  117. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  118. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +177 -167
  119. package/src/shade/renderer/rasterize/DEPTH_STENCIL_STATE_SHADOW.d.ts.map +1 -1
  120. package/src/shade/renderer/rasterize/DEPTH_STENCIL_STATE_SHADOW.js +10 -0
  121. package/src/shade/renderer/rasterize/RasterizationJob.d.ts +1 -2
  122. package/src/shade/renderer/rasterize/RasterizationJob.d.ts.map +1 -1
  123. package/src/shade/renderer/rasterize/RasterizationJob.js +1 -2
  124. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +5 -6
  125. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  126. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +5 -6
  127. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +2 -2
  128. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  129. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +1 -1
  130. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  131. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +11 -0
  132. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/build_lut_fog_parameters_jendersie_deon.d.ts.map +1 -1
  133. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/build_lut_fog_parameters_jendersie_deon.js +4 -5
  134. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts.map +1 -1
  135. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.js +1 -5
  136. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.d.ts +30 -0
  137. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.d.ts.map +1 -0
  138. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.js +54 -0
  139. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.d.ts.map +1 -1
  140. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js +3 -2
  141. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.d.ts +19 -0
  142. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.d.ts.map +1 -0
  143. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.js +27 -0
  144. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +1 -0
  145. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  146. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +4 -0
  147. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +54 -0
  148. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  149. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +502 -10
  150. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +3 -2
  151. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  152. package/src/shade/renderer/shadow/map/Shadowmap.js +3 -2
  153. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts +8 -0
  154. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts.map +1 -1
  155. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.js +34 -3
  156. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +3 -2
  157. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  158. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +17 -2
  159. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  160. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +137 -133
  161. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.d.ts +15 -0
  162. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.d.ts.map +1 -0
  163. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.js +14 -0
  164. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.d.ts +16 -0
  165. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.d.ts.map +1 -0
  166. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.js +15 -0
  167. package/src/shade/renderer/shadow/vsm/PLAN.md +440 -0
  168. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +43 -0
  169. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts +42 -0
  170. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts.map +1 -0
  171. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.js +153 -0
  172. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +327 -0
  173. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -0
  174. package/src/shade/renderer/shadow/vsm/VSMPageManager.js +1408 -0
  175. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.d.ts +14 -0
  176. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.d.ts.map +1 -0
  177. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.js +13 -0
  178. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.d.ts +63 -0
  179. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.d.ts.map +1 -0
  180. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.js +70 -0
  181. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.d.ts +11 -0
  182. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.d.ts.map +1 -0
  183. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.js +10 -0
  184. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts +54 -0
  185. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts.map +1 -0
  186. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.js +75 -0
  187. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.d.ts +23 -0
  188. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.d.ts.map +1 -0
  189. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.js +85 -0
  190. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.d.ts +16 -0
  191. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.d.ts.map +1 -0
  192. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.js +29 -0
  193. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts +136 -25
  194. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts.map +1 -1
  195. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.js +282 -116
  196. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.d.ts +39 -0
  197. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.d.ts.map +1 -0
  198. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.js +289 -0
  199. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.d.ts +18 -0
  200. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.d.ts.map +1 -0
  201. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.js +65 -0
  202. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.d.ts +17 -0
  203. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.d.ts.map +1 -0
  204. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.js +75 -0
  205. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +14 -0
  206. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +1 -0
  207. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.js +45 -0
  208. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.d.ts +17 -0
  209. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.d.ts.map +1 -0
  210. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.js +100 -0
  211. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.d.ts +15 -0
  212. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.d.ts.map +1 -0
  213. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.js +47 -0
  214. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.d.ts +26 -0
  215. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.d.ts.map +1 -0
  216. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.js +156 -0
  217. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.d.ts +13 -0
  218. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.d.ts.map +1 -0
  219. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.js +65 -0
  220. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts +30 -0
  221. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts.map +1 -0
  222. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.js +184 -0
  223. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts +23 -0
  224. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts.map +1 -0
  225. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.js +109 -0
  226. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.d.ts +56 -0
  227. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.d.ts.map +1 -0
  228. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.js +211 -0
  229. package/src/shade/renderer/texture/format/decode_typed_gpu_data.d.ts +1 -1
  230. package/src/shade/renderer/texture/format/decode_typed_gpu_data.d.ts.map +1 -1
  231. package/src/shade/renderer/texture/format/decode_typed_gpu_data.js +3 -13
  232. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -1
  233. package/src/shade/renderer/texture/format/infer_format_from_parameters.js +2 -3
  234. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
  235. package/src/shade/renderer/texture/texture_write_to_gpu.js +16 -16
  236. package/src/shade/renderer/texture/virtual/VTPhysicalCache.d.ts +4 -90
  237. package/src/shade/renderer/texture/virtual/VTPhysicalCache.d.ts.map +1 -1
  238. package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +6 -210
  239. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.d.ts +119 -0
  240. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.d.ts.map +1 -0
  241. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.js +245 -0
  242. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.d.ts +1 -1
  243. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.d.ts.map +1 -1
  244. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +3 -19
  245. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.d.ts +13 -0
  246. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.d.ts.map +1 -0
  247. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.js +34 -0
  248. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +7 -2
  249. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  250. package/src/shade/renderer/water/GPUWaterRenderer.js +49 -49
  251. package/src/shade/renderer/water/chunk_water_transport.js +3 -3
  252. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +11 -25
  253. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  254. package/src/shade/renderer/water/medium/GPUWaterBodies.js +64 -116
  255. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts +1 -20
  256. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts.map +1 -1
  257. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.js +10 -42
  258. package/src/shade/renderer/water/medium/chunk_water_bodies.d.ts +3 -0
  259. package/src/shade/renderer/water/medium/chunk_water_bodies.d.ts.map +1 -0
  260. package/src/shade/renderer/water/medium/chunk_water_bodies.js +3 -0
  261. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +1 -5
  262. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +1 -1
  263. package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +32 -30
  264. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +4 -0
  265. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -0
  266. package/src/shade/renderer/water/medium/shader_water_meshlets.js +69 -0
  267. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts.map +1 -1
  268. package/src/shade/renderer/water/optics/chunk_water_inscatter.js +124 -123
  269. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  270. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +75 -74
  271. package/src/shade/renderer/water/shader_water.d.ts +1 -1
  272. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  273. package/src/shade/renderer/water/shader_water.js +490 -406
  274. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +12 -85
  275. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +1 -1
  276. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +128 -408
  277. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +6 -0
  278. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -0
  279. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +23 -0
  280. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +9 -0
  281. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +1 -0
  282. package/src/shade/renderer/water/surface/chunk_water_tessellation.js +144 -0
  283. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +3 -5
  284. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +1 -1
  285. package/src/shade/renderer/water/surface/chunk_water_wave.js +40 -48
  286. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +14 -0
  287. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -0
  288. package/src/shade/renderer/water/surface/graph_water_tessellation.js +34 -0
  289. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +4 -0
  290. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +1 -0
  291. package/src/shade/renderer/water/surface/shader_water_tiles.js +123 -0
  292. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +6 -0
  293. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +1 -0
  294. package/src/shade/renderer/water/surface/shader_water_wave_batch.js +85 -0
  295. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +6 -0
  296. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +1 -0
  297. package/src/shade/renderer/water/surface/shader_water_wave_domain.js +83 -0
  298. package/src/shade/renderer/water/water_height_texture_from_sampler.d.ts.map +1 -1
  299. package/src/shade/renderer/water/water_height_texture_from_sampler.js +4 -3
  300. package/src/engine/graphics/ecs/water/WATER_SIZE.d.ts +0 -2
  301. package/src/engine/graphics/ecs/water/WATER_SIZE.d.ts.map +0 -1
  302. package/src/engine/graphics/ecs/water/WATER_SIZE.js +0 -1
  303. package/src/shade/renderer/light/GPUViewLightContext.d.ts +0 -22
  304. package/src/shade/renderer/light/GPUViewLightContext.d.ts.map +0 -1
  305. package/src/shade/renderer/light/GPUViewLightContext.js +0 -62
  306. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts +0 -14
  307. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts.map +0 -1
  308. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.js +0 -20
  309. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts +0 -27
  310. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts.map +0 -1
  311. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.js +0 -147
  312. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.d.ts +0 -7
  313. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.d.ts.map +0 -1
  314. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.js +0 -10
  315. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.d.ts +0 -2
  316. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.d.ts.map +0 -1
  317. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.js +0 -1
  318. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.d.ts +0 -3
  319. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.d.ts.map +0 -1
  320. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.js +0 -8
  321. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts +0 -27
  322. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts.map +0 -1
  323. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.js +0 -102
  324. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.d.ts +0 -8
  325. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.d.ts.map +0 -1
  326. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.js +0 -34
  327. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.d.ts +0 -10
  328. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.d.ts.map +0 -1
  329. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.js +0 -64
  330. package/src/shade/renderer/shadow/vsm/decode_tile_address.d.ts +0 -11
  331. package/src/shade/renderer/shadow/vsm/decode_tile_address.d.ts.map +0 -1
  332. package/src/shade/renderer/shadow/vsm/decode_tile_address.js +0 -26
  333. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.d.ts +0 -2
  334. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.d.ts.map +0 -1
  335. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.js +0 -11
  336. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.d.ts +0 -20
  337. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.d.ts.map +0 -1
  338. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.js +0 -184
  339. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.d.ts +0 -25
  340. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.d.ts.map +0 -1
  341. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.js +0 -230
  342. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.d.ts +0 -19
  343. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.d.ts.map +0 -1
  344. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.js +0 -127
  345. package/src/shade/renderer/texture/encode/ENCODE_NOTES_2026_09_02.md +0 -462
  346. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts +0 -23
  347. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts.map +0 -1
  348. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts +0 -18
  349. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts.map +0 -1
  350. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts +0 -12
  351. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts.map +0 -1
  352. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.js +0 -27
  353. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts +0 -14
  354. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts.map +0 -1
  355. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.js +0 -49
  356. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts +0 -9
  357. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts.map +0 -1
  358. package/src/shade/renderer/water/surface/chunk_water_wave_grid.js +0 -47
  359. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts +0 -10
  360. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts.map +0 -1
  361. package/src/shade/renderer/water/surface/shader_water_surface_write.js +0 -51
  362. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts +0 -12
  363. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts.map +0 -1
  364. package/src/shade/renderer/water/surface/shader_water_wave_step.js +0 -54
  365. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts +0 -13
  366. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts.map +0 -1
  367. package/src/shade/renderer/water/surface/water_surface_grid_indices.js +0 -39
@@ -1,423 +1,230 @@
1
1
  import { assert } from "../../core/assert.js";
2
2
  import Water from "../graphics/ecs/water/Water.js";
3
3
  import WaterWaves from "../graphics/ecs/water/WaterWaves.js";
4
- import { WATER_SIZE } from "../graphics/ecs/water/WATER_SIZE.js";
5
- import { obtainTerrain } from "../ecs/terrain/util/obtainTerrain.js";
6
4
  import { System } from "../ecs/System.js";
5
+ import { EventType } from "../ecs/EventType.js";
6
+ import { Transform64 } from "../ecs/transform/Transform64.js";
7
+ import { TransformAttachment } from "../ecs/transform-attachment/TransformAttachment.js";
8
+ import { TRANSFORM64_EVENT_CHANGE } from "../ecs/transform/TRANSFORM64_EVENT_CHANGE.js";
9
+ import { TRANSFORM_ATTACHMENT_EVENT_CHANGE } from "../ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js";
10
+ import { MeshletGeometry } from "../../shade/renderer/geometry/MeshletGeometry.js";
7
11
  import { ResourceAccessKind } from "../../core/model/ResourceAccessKind.js";
8
12
  import { ResourceAccessSpecification } from "../../core/model/ResourceAccessSpecification.js";
9
13
  import { GPUWaterRenderer } from "../../shade/renderer/water/GPUWaterRenderer.js";
10
14
  import { GPUWaterBodies } from "../../shade/renderer/water/medium/GPUWaterBodies.js";
11
15
  import { GPUWaterWaveSimulation } from "../../shade/renderer/water/surface/GPUWaterWaveSimulation.js";
12
- import { WATER_WAVE_IMPULSE_LIMIT } from "../../shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.js";
13
- import { water_height_texture_from_sampler } from "../../shade/renderer/water/water_height_texture_from_sampler.js";
14
16
  import { FramePhase } from "../../shade/renderer/extension/FramePhase.js";
15
17
  import { RenderExtension } from "../../shade/renderer/extension/RenderExtension.js";
16
18
  import { SceneColor } from "../../shade/renderer/extension/SceneColor.js";
19
+ import { m4_invert } from "../../core/geom/3d/mat4/m4_invert.js";
20
+ import { generate_record_writer } from "../../shade/renderer/buffer/table/serde/generate_record_writer.js";
21
+ import { WATER_WAVE_IMPULSE_LIMIT, WATER_WAVE_RECORD_STRUCT } from "../../shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js";
22
+
23
+ const WIND_WRITER = generate_record_writer(WATER_WAVE_RECORD_STRUCT, ['forcing', 'unresolved_variance']);
24
+ const IMPULSE_WRITER = generate_record_writer(WATER_WAVE_RECORD_STRUCT, ['impulses', 'impulse_count']);
17
25
 
18
26
  /**
19
- * Draws the level's water under Shade.
20
- *
21
- * Water is a shared AVBOIT side channel. The extension is debug presentation only; normal frames
22
- * composite water exactly once alongside particles, meshlets and trails in AVBOIT's resolve.
23
- *
24
- * Registration does not wait for a device. `GraphicsEngine` holds extensions and applies them
25
- * to the renderer when one exists and again after a restart (E9, §4.8).
27
+ * Registers [Water, MeshletGeometry, Transform64] in the scene's existing GPU database. Authored
28
+ * edits queue writes; idle frames never walk bodies. Transform rows follow the same change events
29
+ * and GPU hierarchy as shaded geometry. Water does not enter the opaque mesh table or its TLAS.
26
30
  */
27
31
  export class WaterSystem extends System {
28
- dependencies = [Water];
29
-
30
- components_used = [
31
- // optional: drives the surface producer when present, calm water when not
32
- ResourceAccessSpecification.from(WaterWaves, ResourceAccessKind.Read),
33
- ];
34
-
35
- /**
36
- * @type {GraphicsEngine}
37
- */
32
+ dependencies = [Water, MeshletGeometry, Transform64];
33
+ components_used = [ResourceAccessSpecification.from(WaterWaves, ResourceAccessKind.Read)];
38
34
  #graphics;
39
-
40
- /**
41
- * @type {GPUWaterRenderer}
42
- */
35
+ #scene;
36
+ #context = null;
43
37
  #renderer = new GPUWaterRenderer();
44
-
45
- /**
46
- * The surface producer: the primitive wave simulation, behind the surface interface the water
47
- * draws read (WATER_OPTICS_PLAN_2026_10_02.md §7.2).
48
- *
49
- * @type {GPUWaterWaveSimulation}
50
- */
51
38
  #waves = new GPUWaterWaveSimulation();
52
-
53
- /**
54
- * The frame's water bodies on the GPU: each one's medium and surface optics, read by every pass
55
- * that lights water.
56
- *
57
- * @type {GPUWaterBodies}
58
- */
59
39
  #bodies = new GPUWaterBodies();
60
-
61
- /**
62
- * What the pass draws, in link order.
63
- *
64
- * @type {WaterSurface[]}
65
- */
66
- #surfaces = [];
67
-
68
- /**
69
- * @type {Map<number, WaterSurface>}
70
- */
71
40
  #entries = new Map();
72
-
73
- /**
74
- * @type {RenderExtension|null}
75
- */
76
- #extension = null;
77
-
78
- /**
79
- * Records the surface producer at the head of each frame.
80
- *
81
- * @type {RenderExtension|null}
82
- */
83
- #surface_extension = null;
84
-
41
+ #dirty = new Set();
42
+ #impulses = new Set();
43
+ #extensions = [];
44
+ #time = 0;
85
45
  get settings() { return this.#renderer.settings; }
86
-
87
- /** The surface producer, for settings such as its grid resolution. */
88
46
  get waves() { return this.#waves; }
89
-
90
- /** The registered channel, for diagnostics such as testing registration order. */
91
47
  get transparency_channel() { return this.#renderer; }
92
-
48
+ get scene() { return this.#scene; }
93
49
  request_probe(uv) { return this.#renderer.request_probe(uv); }
94
-
95
50
  get time() { return this.#time; }
96
51
  set time(seconds) {
97
52
  assert.ok(Number.isFinite(seconds) && seconds >= 0, 'water time must be finite and non-negative');
98
53
  this.#time = seconds;
99
- this.update(0);
100
54
  }
101
55
 
102
- /**
103
- * Seconds since startup. Waves are a function of it and nothing else advances it.
104
- *
105
- * @type {number}
106
- */
107
- #time = 0;
108
-
109
- /**
110
- * What the pass draws. Read-only — the surfaces follow the entities, and a harness that wants
111
- * one gone takes its component off.
112
- *
113
- * @returns {WaterSurface[]}
114
- */
115
- get surfaces() {
116
- return this.#surfaces;
117
- }
118
-
119
- /**
120
- * @param {GraphicsEngine} graphics
121
- */
122
- constructor(graphics) {
123
- super();
124
-
125
- assert.defined(graphics, 'graphics');
126
-
127
- this.#graphics = graphics;
56
+ constructor(graphics, scene) {
57
+ super(); assert.defined(graphics, 'graphics'); assert.defined(scene, 'scene');
58
+ this.#graphics = graphics; this.#scene = scene;
59
+ this.#renderer.scene = scene;
60
+ this.#waves.onInputsConsumed.add(context => {
61
+ if (context !== this.#context) { return; }
62
+ for (const entry of this.#impulses) {
63
+ entry.staged.length = 0;
64
+ if (entry.impulses.length !== 0) { this.#dirty.add(entry); }
65
+ else { this.#impulses.delete(entry); }
66
+ }
67
+ });
68
+ this.#renderer.bodies = this.#bodies;
69
+ this.#renderer.waves = this.#waves;
128
70
  }
129
71
 
130
72
  async startup(entityManager) {
131
73
  this.entityManager = entityManager;
132
-
133
- this.#renderer.surfaces = this.#surfaces;
134
- this.#renderer.bodies = this.#bodies;
74
+ assert.ok(this.#scene.dataset == null || this.#scene.dataset === entityManager.dataset, 'scene belongs to another dataset');
75
+ this.#scene.dataset = entityManager.dataset;
135
76
  this.#graphics.add_transparency_channel(this.#renderer);
136
- this.#extension = this.#graphics.add_extension(new WaterExtension(this));
137
- this.#surface_extension = this.#graphics.add_extension(new WaterSurfaceExtension(this));
77
+ this.#extensions = [this.#graphics.add_extension(new WaterExtension(this)),
78
+ this.#graphics.add_extension(new WaterSurfaceExtension(this))];
138
79
  }
139
80
 
140
- async shutdown(entityManager) {
81
+ async shutdown() {
82
+ for (const entry of Array.from(this.#entries.values())) { this.unlink(entry.water, entry.geometry, entry.transform, entry.entity); }
141
83
  this.#graphics.remove_transparency_channel(this.#renderer);
142
- this.#renderer.dispose();
143
- if (this.#extension !== null) {
144
- this.#graphics.remove_extension(this.#extension);
145
-
146
- this.#extension = null;
147
- }
148
- if (this.#surface_extension !== null) {
149
- this.#graphics.remove_extension(this.#surface_extension);
150
-
151
- this.#surface_extension = null;
152
- }
153
- this.#waves.dispose();
154
- this.#bodies.dispose();
155
-
156
- this.#surfaces.length = 0;
157
- this.#entries.clear();
158
- }
159
-
160
- /**
161
- * @param {FrameContext} frame
162
- */
163
- record(frame) {
164
- const inspection = this.#renderer.inspect(frame.graph, frame.view, frame.resolution);
165
- if (inspection !== undefined) { frame.get(SceneColor).color = inspection; }
166
- }
167
-
168
- /**
169
- * Record the surface producer: this frame's wave steps and the surface interface every water
170
- * pass reads. At the head of the frame, so everything that reads it is recorded after.
171
- *
172
- * @param {FrameContext} frame
173
- */
174
- record_surface(frame) {
175
- const renderer = this.#graphics.renderer;
176
-
177
- if (renderer === null || renderer === undefined) {
178
- return;
179
- }
180
-
181
- const device = renderer.graphics.device;
182
-
183
- this.#waves.record({ graph: frame.graph, device, surfaces: this.#surfaces });
184
- this.#bodies.record({ graph: frame.graph, device, surfaces: this.#surfaces });
185
- }
186
-
187
- /**
188
- * Kick the surface of an entity's water, as a boat or a splash would: a vertical velocity
189
- * `strength` m/s at `position`, falling off over `radius` m. Applied on the next frame that
190
- * steps; at most {@link WATER_WAVE_IMPULSE_LIMIT} a frame per body, the rest wait for the
191
- * following frames.
192
- *
193
- * @param {number} entity the entity carrying the {@link Water}
194
- * @param {number[]} position world x, y, z; y is ignored
195
- * @param {number} radius m
196
- * @param {number} strength m/s, positive upwards
197
- */
198
- splash(entity, position, radius, strength) {
199
- assert.isNonNegativeInteger(entity, 'entity');
200
- assert.isArrayLike(position, 'position');
201
- assert.isFinite(position[0], 'position[0]');
202
- assert.isFinite(position[2], 'position[2]');
203
- assert.isFinite(radius, 'radius');
204
- assert.greaterThan(radius, 0, 'radius');
205
- assert.isFinite(strength, 'strength');
206
-
207
- const surface = this.#entries.get(entity);
208
-
209
- assert.defined(surface, 'surface');
210
-
211
- surface.impulses.push([position[0], position[2], radius, strength]);
212
- }
213
-
214
- /**
215
- * @param {Water} water
216
- * @param {number} entity
217
- */
218
- link(water, entity) {
219
- const surface = {
220
- entity,
221
- visible: true,
222
- level: water.level.getValue(),
223
- ior: 1,
224
- roughness: 0,
225
- medium: water.medium,
226
- body_index: 0,
227
- time: this.#time,
228
- extent: new Float32Array(4),
229
- height_uv: new Float32Array([0, 0, 1, 1]),
230
- height_texture: null,
231
- height_data: null,
232
- height_version: -1,
233
- wind_speed: 0,
234
- wind_direction: 0,
235
- impulses: [],
236
- gpu_surface: undefined,
237
- component: water
84
+ for (const extension of this.#extensions) { this.#graphics.remove_extension(extension); }
85
+ this.#extensions.length = 0;
86
+ this.#renderer.dispose(); this.#waves.dispose(); this.#context = null;
87
+ }
88
+
89
+ link(water, geometry, transform, entity) {
90
+ const entry = { water, geometry, transform, entity, context: null, row: -1, wave: -1, waves: null,
91
+ impulses: [], staged: [], wave_record: null };
92
+ const dataset = this.entityManager.dataset;
93
+ entry.changed = () => this.#dirty.add(entry);
94
+ entry.world = () => entry.context?.rows.mark_world(entity);
95
+ entry.local = () => entry.context?.rows.mark_local(entity);
96
+ entry.components = ({ klass }) => {
97
+ if (klass === WaterWaves) { this.#watch_waves(entry); entry.changed(); }
98
+ if (klass === TransformAttachment) { entry.local(); }
238
99
  };
239
-
240
- this.#entries.set(entity, surface);
241
-
242
- this.#refresh(surface, water);
243
-
244
- if (surface.height_texture !== null) {
245
- this.#surfaces.push(surface);
100
+ water.onChanged.add(entry.changed);
101
+ dataset.addEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.world);
102
+ dataset.addEntityEventListener(entity, TRANSFORM_ATTACHMENT_EVENT_CHANGE, entry.local);
103
+ dataset.addEntityEventListener(entity, EventType.ComponentAdded, entry.components);
104
+ dataset.addEntityEventListener(entity, EventType.ComponentRemoved, entry.components);
105
+ this.#entries.set(entity, entry);
106
+ this.#watch_waves(entry);
107
+ this.#dirty.add(entry);
108
+ this.#renderer.body_count++;
109
+ }
110
+
111
+ #watch_waves(entry) {
112
+ entry.waves?.windSpeed.onChanged.remove(entry.changed);
113
+ entry.waves?.windDirection.onChanged.remove(entry.changed);
114
+ entry.waves = this.entityManager.dataset.getComponent(entry.entity, WaterWaves);
115
+ entry.waves?.windSpeed.onChanged.add(entry.changed);
116
+ entry.waves?.windDirection.onChanged.add(entry.changed);
117
+ }
118
+
119
+ unlink(water, geometry, transform, entity) {
120
+ const entry = this.#entries.get(entity);
121
+ if (entry === undefined) { return; }
122
+ const dataset = this.entityManager.dataset;
123
+ water.onChanged.remove(entry.changed);
124
+ entry.waves?.windSpeed.onChanged.remove(entry.changed);
125
+ entry.waves?.windDirection.onChanged.remove(entry.changed);
126
+ dataset.removeEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.world);
127
+ dataset.removeEntityEventListener(entity, TRANSFORM_ATTACHMENT_EVENT_CHANGE, entry.local);
128
+ dataset.removeEntityEventListener(entity, EventType.ComponentAdded, entry.components);
129
+ dataset.removeEntityEventListener(entity, EventType.ComponentRemoved, entry.components);
130
+ if (entry.context !== null && entry.context === this.#graphics.scene_context(this.#scene)) {
131
+ entry.context.scene_database.get('water_bodies').remove(entry.row);
132
+ entry.context.rows.release(entity);
246
133
  }
247
- }
248
-
249
- /**
250
- * @param {Water} water
251
- * @param {number} entity
252
- */
253
- unlink(water, entity) {
254
- const surface = this.#entries.get(entity);
255
-
256
- if (surface === undefined) {
257
- return;
134
+ this.#entries.delete(entity); this.#dirty.delete(entry); this.#impulses.delete(entry);
135
+ this.#renderer.body_count--;
136
+ if (entry.context !== null) { this.#renderer.meshlet_capacity -= entry.geometry.meshlets.count; }
137
+ }
138
+
139
+ update(dt) {
140
+ this.#time += dt; this.#renderer.time = this.#time; this.#waves.advance(dt);
141
+ const context = this.#graphics.scene_context(this.#scene);
142
+ if (context === null) { return; }
143
+ if (context !== this.#context) {
144
+ this.#context = context;
145
+ // Device replacement is the only whole-scene rebuild; ordinary frames drain edits.
146
+ for (const entry of this.#entries.values()) {
147
+ entry.context = null; entry.row = -1; entry.wave = -1; entry.wave_record = null;
148
+ entry.impulses.unshift(...entry.staged); entry.staged.length = 0;
149
+ this.#dirty.add(entry);
150
+ }
151
+ this.#renderer.meshlet_capacity = 0;
258
152
  }
259
-
260
- const index = this.#surfaces.indexOf(surface);
261
-
262
- if (index !== -1) {
263
- this.#surfaces.splice(index, 1);
153
+ for (const entry of this.#dirty) { this.#write(entry, context); }
154
+ this.#dirty.clear();
155
+ }
156
+
157
+ #write(entry, context) {
158
+ const bodies = context.scene_database.get('water_bodies');
159
+ const waves = context.scene_database.get('water_waves');
160
+ if (entry.context === null) {
161
+ context.rows.acquire(entry.entity);
162
+ context.geometries.add(entry.geometry);
163
+ entry.context = context;
164
+ this.#renderer.meshlet_capacity += entry.geometry.meshlets.count;
264
165
  }
265
-
266
- this.#entries.delete(entity);
267
- }
268
-
269
- update(timeDelta) {
270
- this.#time += timeDelta;
271
- this.#waves.advance(timeDelta);
272
-
273
- for (const surface of this.#entries.values()) {
274
- surface.time = this.#time;
275
-
276
- this.#refresh(surface, surface.component);
277
-
278
- if (surface.height_texture !== null && this.#surfaces.indexOf(surface) === -1) {
279
- // the terrain arrived after the water did, which is ordinary at level-load rates
280
- this.#surfaces.push(surface);
281
- } else if (surface.height_texture === null) {
282
- const index = this.#surfaces.indexOf(surface);
283
- if (index !== -1) { this.#surfaces.splice(index, 1); }
166
+ if (entry.wave !== -1 || entry.waves != null || entry.impulses.length !== 0) {
167
+ const bounds = entry.geometry.bounding_box;
168
+ if (entry.wave === -1) {
169
+ entry.wave_record = { extent: [bounds[0], bounds[2], bounds[3], bounds[5]],
170
+ forcing: [1, 0, 0, 0], impulses: Array.from({ length: WATER_WAVE_IMPULSE_LIMIT }, () => [0, 0, 0, 0]),
171
+ node: entry.entity + 1, geometry: context.geometries.getAddress(entry.geometry),
172
+ unresolved_variance: 0, impulse_count: 0, first_write: 1, displacement_bounds: [0, 0] };
173
+ entry.wave = waves.add(entry.wave_record);
174
+ }
175
+ const wind = Math.max(0, entry.waves?.windSpeed.getValue() ?? 0);
176
+ const direction = entry.waves?.windDirection.getValue() ?? 0;
177
+ // Patch only authored fields: a full write would restore GPU-consumed impulses/reset flags.
178
+ waves.set_fields(entry.wave, { forcing: [Math.cos(direction), Math.sin(direction), 0.02 * wind * wind, 0.5 * wind],
179
+ unresolved_variance: wind > 0 ? 0.003 + 0.00512 * wind : 0 }, WIND_WRITER);
180
+ if (entry.impulses.length !== 0) {
181
+ entry.staged.push(...entry.impulses.splice(0, WATER_WAVE_IMPULSE_LIMIT - entry.staged.length));
182
+ const impulses = entry.staged.slice();
183
+ const count = impulses.length;
184
+ while (impulses.length < WATER_WAVE_IMPULSE_LIMIT) { impulses.push([0, 0, 0, 0]); }
185
+ waves.set_fields(entry.wave, { impulses, impulse_count: count }, IMPULSE_WRITER);
284
186
  }
285
187
  }
188
+ const water = entry.water;
189
+ const record = { geometry: context.geometries.getAddress(entry.geometry), node: entry.entity + 1,
190
+ dirty: 1,
191
+ wave: entry.wave === -1 ? 0xffffffff : entry.wave, ior: Math.max(1, water.ior.getValue()),
192
+ roughness: Math.min(1, Math.max(0, water.roughness.getValue())), medium: water.medium.to_gpu_record(),
193
+ backscattering: [0, 0, 0, 0], extinction: [0, 0, 0, 0], diffuse_transmittance: 0 };
194
+ if (entry.row === -1) { entry.row = bodies.add(record); } else { bodies.set(entry.row, record); }
286
195
  }
287
196
 
288
- /**
289
- * Copy the component's authored values across, and work out where the surface sits over the
290
- * terrain it is flooding.
291
- *
292
- * @param {WaterSurface} surface
293
- * @param {Water} water
294
- */
295
- #refresh(surface, water) {
296
- surface.level = water.level.getValue();
297
- surface.ior = Math.max(1, water.ior.getValue());
298
- surface.roughness = Math.min(1, Math.max(0, water.roughness.getValue()));
299
- surface.medium = water.medium;
300
-
301
- const waves = this.entityManager.dataset.getComponent(surface.entity, WaterWaves);
302
-
303
- surface.wind_speed = waves === undefined ? 0 : Math.max(0, waves.windSpeed.getValue());
304
- surface.wind_direction = waves === undefined ? 0 : waves.windDirection.getValue();
305
-
306
- const terrain = obtainTerrain(this.entityManager.dataset);
307
-
308
- if (terrain === null || terrain === undefined) {
309
- // no terrain to flood; the shore line has nothing to read and the surface stays out of
310
- // the pass until one exists
311
- surface.height_texture = null;
312
- surface.height_data = null;
313
- surface.height_version = -1;
314
- return;
315
- }
316
-
317
- const width = terrain.size.x * terrain.gridScale;
318
- const height = terrain.size.y * terrain.gridScale;
319
- if (!(width > 0 && height > 0)) {
320
- surface.height_texture = null; surface.height_data = null; surface.height_version = -1;
321
- return;
322
- }
323
-
324
- /*
325
- The legacy placement, read off it rather than derived: an 800-unit plane centred at
326
- `WATER_SIZE / 4` on both axes, so it spans [-200, 600] regardless of how big the terrain is.
327
- The map is an island in an ocean, not a lake fitted to the map, and where the surface hangs
328
- past the terrain the height map clamps — which is what lets the shore line continue instead
329
- of stopping at the boundary.
330
-
331
- The three path stated the same thing as a UV transform,
332
- `(uv - 0.25) * (WATER_SIZE / terrain_size)`, and the two agree by construction: world
333
- position is `(u - 0.25) * WATER_SIZE`, and terrain uv is that over the terrain's own size.
334
- */
335
- const x0 = -WATER_SIZE * 0.25;
336
- const z0 = -WATER_SIZE * 0.25;
337
-
338
- surface.extent[0] = x0;
339
- surface.extent[1] = z0;
340
- surface.extent[2] = x0 + WATER_SIZE;
341
- surface.extent[3] = z0 + WATER_SIZE;
342
-
343
- surface.height_uv[0] = x0 / width;
344
- surface.height_uv[1] = z0 / height;
345
- surface.height_uv[2] = WATER_SIZE / width;
346
- surface.height_uv[3] = WATER_SIZE / height;
347
-
348
- const height_field = terrain.samplerHeight;
349
-
350
- /*
351
- The height field a water surface links against is not the one it will read. A `Terrain`
352
- carries a 512² placeholder from the moment its entity exists, and the level's own field
353
- arrives later — while Shade uploads a texture once and has no notion of one changing. So a
354
- surface linked at load time would read a flat sea floor for the rest of the session.
355
-
356
- Watched on the data array rather than on the sampler: `Sampler2D.fromJSON` replaces `data`
357
- and leaves `version` alone, so deserialization is invisible to the counter. The version is
358
- watched too, for the edits that do bump it and keep the array.
359
- */
360
- if (surface.height_data !== height_field.data || surface.height_version !== height_field.version) {
361
- surface.height_texture = water_height_texture_from_sampler(height_field);
362
- surface.height_data = height_field.data;
363
- surface.height_version = height_field.version;
364
- }
197
+ /** World-space radius and velocity kick; position is interpreted in the CPU-owned pose. */
198
+ splash(entity, position, radius, strength) {
199
+ const entry = this.#entries.get(entity); assert.defined(entry, 'water entity');
200
+ assert.greaterThan(radius, 0, 'radius'); assert.isFinite(radius, 'radius'); assert.isFinite(strength, 'strength');
201
+ for (let i = 0; i < 3; i++) { assert.isFinite(position[i], `position[${i}]`); }
202
+ const inverse = new Float64Array(16);
203
+ assert.ok(m4_invert(inverse, entry.transform), 'water transform is singular');
204
+ const x = inverse[0] * position[0] + inverse[4] * position[1] + inverse[8] * position[2] + inverse[12];
205
+ const z = inverse[2] * position[0] + inverse[6] * position[1] + inverse[10] * position[2] + inverse[14];
206
+ entry.impulses.push([x, z, radius, strength]); this.#impulses.add(entry); this.#dirty.add(entry);
365
207
  }
366
- }
367
-
368
- /**
369
- * Opt-in water inspection after temporal processing. Kept under the exported name
370
- * for compatibility; this never records a water color overlay in normal rendering.
371
- */
372
- export class WaterExtension extends RenderExtension {
373
- name = "water";
374
208
 
375
- // Diagnostics must show this frame's measurements, not temporally accumulated colors.
376
- phase = FramePhase.BeforePresent;
377
-
378
- /**
379
- * @type {WaterSystem}
380
- */
381
- #system;
382
-
383
- /**
384
- * @param {WaterSystem} system
385
- */
386
- constructor(system) {
387
- super();
388
-
389
- this.#system = system;
209
+ record_surface(frame) {
210
+ const scene = frame.view.scene;
211
+ if (scene.scene !== this.#scene) { return; }
212
+ this.#waves.record({ graph: frame.graph, device: this.#graphics.renderer.graphics.device, scene });
213
+ this.#bodies.record({ graph: frame.graph, scene });
390
214
  }
391
-
392
215
  record(frame) {
393
- this.#system.record(frame);
216
+ const inspection = this.#renderer.inspect(frame.graph, frame.view, frame.resolution);
217
+ if (inspection !== undefined) { frame.get(SceneColor).color = inspection; }
394
218
  }
395
219
  }
396
220
 
397
- /**
398
- * Records the water surface producer at {@link FramePhase.FrameStart}, so the surface exists before
399
- * anything in the frame reads it.
400
- */
221
+ export class WaterExtension extends RenderExtension {
222
+ name = 'water'; phase = FramePhase.BeforePresent;
223
+ constructor(system) { super(); this.system = system; }
224
+ record(frame) { this.system.record(frame); }
225
+ }
401
226
  export class WaterSurfaceExtension extends RenderExtension {
402
- name = "water surface";
403
-
404
- phase = FramePhase.FrameStart;
405
-
406
- /**
407
- * @type {WaterSystem}
408
- */
409
- #system;
410
-
411
- /**
412
- * @param {WaterSystem} system
413
- */
414
- constructor(system) {
415
- super();
416
-
417
- this.#system = system;
418
- }
419
-
420
- record(frame) {
421
- this.#system.record_surface(frame);
422
- }
227
+ name = 'water surface'; phase = FramePhase.FrameStart;
228
+ constructor(system) { super(); this.system = system; }
229
+ record(frame) { this.system.record_surface(frame); }
423
230
  }
@@ -66,11 +66,11 @@ export class FluidObstacleSystem extends System<any> {
66
66
  /**
67
67
  * @param {FluidComponent} fluid
68
68
  */
69
- static "__#422@#refresh_masks"(fluid: FluidComponent): void;
69
+ static "__#423@#refresh_masks"(fluid: FluidComponent): void;
70
70
  /**
71
71
  * @param {FluidComponent} fluid
72
72
  */
73
- static "__#422@#clear_field"(fluid: FluidComponent): void;
73
+ static "__#423@#clear_field"(fluid: FluidComponent): void;
74
74
  /**
75
75
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
76
76
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -82,7 +82,7 @@ export class FluidObstacleSystem extends System<any> {
82
82
  * @param {number} inflation world-units SDF threshold
83
83
  * @param {Float64Array} point length-3 scratch
84
84
  */
85
- static "__#422@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
85
+ static "__#423@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
86
86
  /**
87
87
  * Write the obstacle's translation velocity onto every face of every cell
88
88
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -102,7 +102,7 @@ export class FluidObstacleSystem extends System<any> {
102
102
  * @param {number} wvy
103
103
  * @param {number} wvz
104
104
  */
105
- static "__#422@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
105
+ static "__#423@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
106
106
  constructor();
107
107
  dependencies: (typeof FluidObstacle)[];
108
108
  components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];
@@ -14,7 +14,7 @@
14
14
  * for, in nits; defaults to {@link LINEAR_REFERENCE_NITS}. Only read for `COLOUR_SPACE_LINEAR`,
15
15
  * and the exact counterpart of {@link encode_avif}'s option of the same name
16
16
  * @param {number} [options.chroma_upsampling] one of the `CHROMA_UPSAMPLING_*` constants
17
- * @returns {{data: (Uint8ClampedArray|Uint16Array), width: number, height: number}}
17
+ * @returns {{data: (Uint8ClampedArray|Uint16Array|Float16Array), width: number, height: number}}
18
18
  *
19
19
  * @author Alex Goldring
20
20
  * @copyright Company Named Limited (c) 2026
@@ -26,7 +26,7 @@ export function convert_to_rgba(decoder: AvifDecoder, image: YuvImage, options?:
26
26
  linear_reference_nits?: number;
27
27
  chroma_upsampling?: number;
28
28
  }): {
29
- data: (Uint8ClampedArray | Uint16Array);
29
+ data: (Uint8ClampedArray | Uint16Array | Float16Array);
30
30
  width: number;
31
31
  height: number;
32
32
  };
@@ -1 +1 @@
1
- {"version":3,"file":"convert_to_rgba.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/avif/api/convert_to_rgba.js"],"names":[],"mappings":"AAoCA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAZ4B,SAAS,GAA1B,MAAM;IACY,cAAc,GAAhC,OAAO;IACU,mBAAmB,GAApC,MAAM;IACW,qBAAqB,GAAtC,MAAM;IAGW,iBAAiB,GAAlC,MAAM;IACJ;IAAC,IAAI,EAAE,CAAC,iBAAiB,GAAC,WAAW,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAkJlF;AA5LD;;;GAGG;AACH,kCAFU,MAAM,CAEqB;AAErC;;;;;GAKG;AACH,kCAFU,MAAM,CAEqB;AAErC;;;GAGG;AACH,0CAFU,MAAM,CAE6B;AAE7C,uCAAuC;AACvC,wCADW,MAAM,CAC0B;AAE3C,8BAA8B;AAC9B,qCADW,MAAM,CACuB"}
1
+ {"version":3,"file":"convert_to_rgba.d.ts","sourceRoot":"","sources":["../../../../../../src/format/image/avif/api/convert_to_rgba.js"],"names":[],"mappings":"AAmCA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAZ4B,SAAS,GAA1B,MAAM;IACY,cAAc,GAAhC,OAAO;IACU,mBAAmB,GAApC,MAAM;IACW,qBAAqB,GAAtC,MAAM;IAGW,iBAAiB,GAAlC,MAAM;IACJ;IAAC,IAAI,EAAE,CAAC,iBAAiB,GAAC,WAAW,eAAa,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAoJ/F;AA9LD;;;GAGG;AACH,kCAFU,MAAM,CAEqB;AAErC;;;;;GAKG;AACH,kCAFU,MAAM,CAEqB;AAErC;;;GAGG;AACH,0CAFU,MAAM,CAE6B;AAE7C,uCAAuC;AACvC,wCADW,MAAM,CAC0B;AAE3C,8BAA8B;AAC9B,qCADW,MAAM,CACuB"}