@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,98 +1,25 @@
1
1
  /**
2
- * Slope variance of the waves a grid does not resolve, from the wind: the Cox-Munk total,
3
- * 0.003 + 5.12e-3·U for wind speed U in m/s (Ocean Optics Web Book, "Cox-Munk sea surface slope
4
- * statistics"). The fit's intercept is ramped in below 1 m/s, where it has no data, so still water
5
- * is a mirror rather than carrying the open sea's background slopes.
6
- *
7
- * @param {number} wind_speed m/s
8
- * @returns {number}
9
- */
10
- export function wind_unresolved_variance(wind_speed: number): number;
11
- /**
12
- * What one body holds on the GPU.
13
- *
14
- * @typedef {Object} WaterWaveBody
15
- * @property {number} resolution
16
- * @property {GPUBuffer[]} state the two alternating height buffers
17
- * @property {number} parity which of {@link state} holds the current heights
18
- * @property {GPUBuffer} vertices
19
- * @property {boolean} written
20
- */
21
- /**
22
- * The primitive surface producer (WATER_OPTICS_PLAN_2026_10_02.md §7.2): a damped linear wave
23
- * equation on a regular grid over each water body, written out as the surface interface — a
24
- * vertex buffer and a shared index buffer.
25
- *
26
- * It owns its GPU resources, keyed by device so a restart rebuilds them, and records its work at
27
- * the head of a frame's graph: everything that reads the surface is recorded after it, and the graph
28
- * runs passes in insertion order. Time advances through {@link advance}, once per tick, and is
29
- * consumed by the first view to record, so several views of one frame step the simulation once.
2
+ * A shared wave atlas, indexed by occupied water_waves rows. Calm bodies allocate no grid.
3
+ * Each fixed step dispatches the whole atlas once; tessellated vertices sample it in local xz.
4
+ * The regular grid is a displacement field, never the rendered water footprint.
30
5
  */
31
6
  export class GPUWaterWaveSimulation {
32
- /**
33
- * Vertices along each side of a body's grid. Changing it rebuilds every body.
34
- * @type {number}
35
- */
7
+ onInputsConsumed: Signal;
36
8
  resolution: number;
37
- /**
38
- * Fixed step, s. Explicit and fixed, so a frame-rate change does not change the waves.
39
- * @type {number}
40
- */
41
9
  step: number;
42
- /**
43
- * Most steps one frame takes; time beyond it is dropped rather than queued, so a stall does not
44
- * turn into a burst.
45
- * @type {number}
46
- */
47
10
  max_steps_per_frame: number;
48
- /**
49
- * Damping everywhere, 1/s.
50
- * @type {number}
51
- */
52
11
  damping: number;
53
- /**
54
- * Simulated time, s.
55
- * @returns {number}
56
- */
57
12
  get time(): number;
58
- /**
59
- * @param {number} dt seconds of simulation to add
60
- */
61
- advance(dt: number): void;
62
- /**
63
- * Release every GPU resource.
64
- */
13
+ get buffer(): any;
14
+ get grid_resolution(): number;
15
+ advance(dt: any): void;
65
16
  dispose(): void;
66
- /**
67
- * Record this frame's steps and surface writes, and publish each surface's interface on it as
68
- * `surface.gpu_surface`.
69
- *
70
- * @param {Object} options
71
- * @param {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} options.graph
72
- * @param {GPUDevice} options.device
73
- * @param {Object[]} options.surfaces bodies with a terrain height texture, as the water system keeps them
74
- */
75
- record({ graph, device, surfaces }: {
76
- graph: import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
77
- device: GPUDevice;
78
- surfaces: any[];
17
+ record({ graph, device, scene }: {
18
+ graph: any;
19
+ device: any;
20
+ scene: any;
79
21
  }): void;
80
22
  #private;
81
23
  }
82
- /**
83
- * What one body holds on the GPU.
84
- */
85
- export type WaterWaveBody = {
86
- resolution: number;
87
- /**
88
- * the two alternating height buffers
89
- */
90
- state: GPUBuffer[];
91
- /**
92
- * which of {@link state } holds the current heights
93
- */
94
- parity: number;
95
- vertices: GPUBuffer;
96
- written: boolean;
97
- };
24
+ import Signal from "../../../../core/events/signal/Signal.js";
98
25
  //# sourceMappingURL=GPUWaterWaveSimulation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GPUWaterWaveSimulation.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/surface/GPUWaterWaveSimulation.js"],"names":[],"mappings":"AA2YA;;;;;;;;GAQG;AACH,qDAHW,MAAM,GACJ,MAAM,CAKlB;AAhYD;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH;IACI;;;OAGG;IACH,YAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,MAFU,MAAM,CAED;IAEf;;;;OAIG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,SAFU,MAAM,CAED;IAwCf;;;OAGG;IACH,mBAEC;IAED;;OAEG;IACH,YAFW,MAAM,QAQhB;IAED;;OAEG;IACH,gBAaC;IAED;;;;;;;;OAQG;IACH;QAJsG,KAAK,EAAhG,OAAO,8DAA8D,EAAE,UAAU;QAC9D,MAAM;QACP,QAAQ,EAA1B,KAAQ;aAiDlB;;CAgMJ;;;;;gBA9Wa,MAAM;;;;WACN,WAAW;;;;YACX,MAAM;;aAEN,OAAO"}
1
+ {"version":3,"file":"GPUWaterWaveSimulation.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/surface/GPUWaterWaveSimulation.js"],"names":[],"mappings":"AAKA;;;;GAIG;AACH;IACI,yBAAgC;IAChC,mBAAiB;IACjB,aAAe;IACf,4BAAwB;IACxB,gBAAe;IAYf,mBAAiC;IACjC,kBAAkD;IAClD,8BAAqE;IAErE,uBAIC;IAED,gBAMC;IAED;;;;aAiFC;;CACJ;mBA/HkB,0CAA0C"}
@@ -1,408 +1,128 @@
1
- import { assert } from "../../../../core/assert.js";
2
- import { SAMPLER_LINEAR_UPSCALE } from "../../texture/SAMPLER_LINEAR_UPSCALE.js";
3
- import { shader_water_surface_write } from "./shader_water_surface_write.js";
4
- import { shader_water_wave_step } from "./shader_water_wave_step.js";
5
- import { WATER_WAVE_IMPULSE_LIMIT, WATER_WAVE_PARAMETERS_STRUCT } from "./WATER_WAVE_PARAMETERS_STRUCT.js";
6
- import { water_surface_grid_indices } from "./water_surface_grid_indices.js";
7
-
8
- /**
9
- * Bytes of one {@link WATER_SURFACE_VERTEX_STRUCT}: three vec4f.
10
- * @type {number}
11
- */
12
- const VERTEX_BYTES = 48;
13
-
14
- /**
15
- * Forcing amplitude per (m/s)² of wind, m/s² — wind stress grows as the square of its speed.
16
- *
17
- * Not calibrated to a wave spectrum: chosen so that the playground's 3 m/s breeze gives
18
- * centimetre-scale waves. The production simulation, not this constant, is where calibration
19
- * belongs.
20
- * @type {number}
21
- */
22
- const FORCING_PER_WIND2 = 0.02;
23
-
24
- /**
25
- * What one body holds on the GPU.
26
- *
27
- * @typedef {Object} WaterWaveBody
28
- * @property {number} resolution
29
- * @property {GPUBuffer[]} state the two alternating height buffers
30
- * @property {number} parity which of {@link state} holds the current heights
31
- * @property {GPUBuffer} vertices
32
- * @property {boolean} written
33
- */
34
-
35
- /**
36
- * The primitive surface producer (WATER_OPTICS_PLAN_2026_10_02.md §7.2): a damped linear wave
37
- * equation on a regular grid over each water body, written out as the surface interface — a
38
- * vertex buffer and a shared index buffer.
39
- *
40
- * It owns its GPU resources, keyed by device so a restart rebuilds them, and records its work at
41
- * the head of a frame's graph: everything that reads the surface is recorded after it, and the graph
42
- * runs passes in insertion order. Time advances through {@link advance}, once per tick, and is
43
- * consumed by the first view to record, so several views of one frame step the simulation once.
44
- */
45
- export class GPUWaterWaveSimulation {
46
- /**
47
- * Vertices along each side of a body's grid. Changing it rebuilds every body.
48
- * @type {number}
49
- */
50
- resolution = 512;
51
-
52
- /**
53
- * Fixed step, s. Explicit and fixed, so a frame-rate change does not change the waves.
54
- * @type {number}
55
- */
56
- step = 1 / 120;
57
-
58
- /**
59
- * Most steps one frame takes; time beyond it is dropped rather than queued, so a stall does not
60
- * turn into a burst.
61
- * @type {number}
62
- */
63
- max_steps_per_frame = 8;
64
-
65
- /**
66
- * Damping everywhere, 1/s.
67
- * @type {number}
68
- */
69
- damping = 0.08;
70
-
71
- /**
72
- * @type {GPUDevice|null}
73
- */
74
- #device = null;
75
-
76
- /**
77
- * @type {Map<Object, WaterWaveBody>}
78
- */
79
- #bodies = new Map();
80
-
81
- /**
82
- * @type {GPUBuffer|null}
83
- */
84
- #indices = null;
85
-
86
- #index_resolution = 0;
87
-
88
- #index_count = 0;
89
-
90
- /**
91
- * Simulated time not yet stepped, s.
92
- * @type {number}
93
- */
94
- #pending = 0;
95
-
96
- /**
97
- * Simulated time stepped so far, s.
98
- * @type {number}
99
- */
100
- #time = 0;
101
-
102
- /**
103
- * Whether the next record writes the surface: once per tick, even a tick of zero, so a paused
104
- * frame's previous positions settle onto its current ones.
105
- * @type {boolean}
106
- */
107
- #write_pending = true;
108
-
109
- /**
110
- * Simulated time, s.
111
- * @returns {number}
112
- */
113
- get time() {
114
- return this.#time;
115
- }
116
-
117
- /**
118
- * @param {number} dt seconds of simulation to add
119
- */
120
- advance(dt) {
121
- assert.isFinite(dt, 'dt');
122
- assert.greaterThanOrEqual(dt, 0, 'dt');
123
-
124
- this.#pending += dt;
125
- this.#write_pending = true;
126
- }
127
-
128
- /**
129
- * Release every GPU resource.
130
- */
131
- dispose() {
132
- for (const body of this.#bodies.values()) {
133
- body.state[0].destroy();
134
- body.state[1].destroy();
135
- body.vertices.destroy();
136
- }
137
-
138
- this.#bodies.clear();
139
-
140
- this.#indices?.destroy();
141
- this.#indices = null;
142
- this.#index_resolution = 0;
143
- this.#device = null;
144
- }
145
-
146
- /**
147
- * Record this frame's steps and surface writes, and publish each surface's interface on it as
148
- * `surface.gpu_surface`.
149
- *
150
- * @param {Object} options
151
- * @param {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} options.graph
152
- * @param {GPUDevice} options.device
153
- * @param {Object[]} options.surfaces bodies with a terrain height texture, as the water system keeps them
154
- */
155
- record({ graph, device, surfaces }) {
156
- assert.defined(graph, 'graph');
157
- assert.defined(device, 'device');
158
- assert.isArray(surfaces, 'surfaces');
159
-
160
- if (device !== this.#device) {
161
- this.dispose();
162
- this.#device = device;
163
- }
164
-
165
- this.#release_unused(surfaces);
166
-
167
- if (surfaces.length === 0) {
168
- return;
169
- }
170
-
171
- this.#ensure_indices(device);
172
-
173
- // the epsilon keeps accumulated rounding — two half steps summing to just under one — from
174
- // dropping a step
175
- const steps = Math.min(Math.floor(this.#pending / this.step + 1e-6), this.max_steps_per_frame);
176
- // time past the frame's limit is dropped, so a stall does not come back as a burst
177
- this.#pending = Math.max(0, Math.min(this.#pending - steps * this.step, this.step));
178
-
179
- const write = this.#write_pending;
180
- this.#write_pending = false;
181
-
182
- if (steps === 0 && !write) {
183
- return;
184
- }
185
-
186
- const time_start = this.#time;
187
- this.#time += steps * this.step;
188
-
189
- for (let i = 0; i < surfaces.length; i++) {
190
- const surface = surfaces[i];
191
- const body = this.#ensure_body(device, surface);
192
-
193
- surface.gpu_surface = {
194
- vertices: body.vertices,
195
- indices: this.#indices,
196
- index_count: this.#index_count,
197
- resolution: body.resolution,
198
- };
199
-
200
- this.#record_body(graph, surface, body, steps, time_start);
201
- }
202
- }
203
-
204
- /**
205
- * @param {Object[]} surfaces
206
- */
207
- #release_unused(surfaces) {
208
- for (const [surface, body] of this.#bodies) {
209
- if (surfaces.indexOf(surface) !== -1 && body.resolution === this.resolution) {
210
- continue;
211
- }
212
-
213
- body.state[0].destroy();
214
- body.state[1].destroy();
215
- body.vertices.destroy();
216
-
217
- this.#bodies.delete(surface);
218
-
219
- if (surface.gpu_surface !== undefined && surface.gpu_surface.vertices === body.vertices) {
220
- surface.gpu_surface = undefined;
221
- }
222
- }
223
- }
224
-
225
- /**
226
- * @param {GPUDevice} device
227
- */
228
- #ensure_indices(device) {
229
- if (this.#indices !== null && this.#index_resolution === this.resolution) {
230
- return;
231
- }
232
-
233
- this.#indices?.destroy();
234
-
235
- const indices = water_surface_grid_indices({ resolution: this.resolution });
236
-
237
- this.#indices = device.createBuffer({
238
- label: "Water / surface indices",
239
- size: indices.byteLength,
240
- usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
241
- });
242
-
243
- device.queue.writeBuffer(this.#indices, 0, indices);
244
-
245
- this.#index_resolution = this.resolution;
246
- this.#index_count = indices.length;
247
- }
248
-
249
- /**
250
- * @param {GPUDevice} device
251
- * @param {Object} surface
252
- * @returns {WaterWaveBody}
253
- */
254
- #ensure_body(device, surface) {
255
- const existing = this.#bodies.get(surface);
256
-
257
- if (existing !== undefined) {
258
- return existing;
259
- }
260
-
261
- const resolution = this.resolution;
262
- const vertex_count = resolution * resolution;
263
-
264
- const state_buffer = (label) => device.createBuffer({
265
- label,
266
- size: vertex_count * 4,
267
- usage: GPUBufferUsage.STORAGE,
268
- });
269
-
270
- /** @type {WaterWaveBody} */
271
- const body = {
272
- resolution,
273
- state: [state_buffer("Water / wave state A"), state_buffer("Water / wave state B")],
274
- parity: 0,
275
- vertices: device.createBuffer({
276
- label: "Water / surface vertices",
277
- size: vertex_count * VERTEX_BYTES,
278
- usage: GPUBufferUsage.STORAGE,
279
- }),
280
- written: false,
281
- };
282
-
283
- this.#bodies.set(surface, body);
284
-
285
- return body;
286
- }
287
-
288
- /**
289
- * @param {Object} surface
290
- * @param {WaterWaveBody} body
291
- * @param {number} time
292
- * @param {number} impulse_count
293
- */
294
- #parameters(surface, body, time, impulse_count) {
295
- const extent = surface.extent;
296
- const wind = surface.wind_speed;
297
- const direction = surface.wind_direction;
298
- const spacing = (extent[2] - extent[0]) / (body.resolution - 1);
299
-
300
- return {
301
- extent: Array.from(extent),
302
- height_uv: Array.from(surface.height_uv),
303
- forcing: [Math.cos(direction), Math.sin(direction), FORCING_PER_WIND2 * wind * wind, 0.5 * wind],
304
- impulses: surface.impulses,
305
- level: surface.level,
306
- spacing,
307
- dt: this.step,
308
- time,
309
- damping: this.damping,
310
- sponge_width: Math.max(4, Math.round(body.resolution * 0.04)),
311
- sponge_strength: 4,
312
- // 2-D CFL: c·dt/dx ≤ 1/√2, with a margin
313
- celerity_limit: 0.6 * spacing / this.step,
314
- unresolved_variance: wind_unresolved_variance(wind),
315
- resolution: body.resolution,
316
- impulse_count,
317
- first_write: body.written ? 0 : 1,
318
- };
319
- }
320
-
321
- /**
322
- * @param {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} graph
323
- * @param {Object} surface
324
- * @param {WaterWaveBody} body
325
- * @param {number} steps
326
- * @param {number} time_start
327
- */
328
- #record_body(graph, surface, body, steps, time_start) {
329
- const groups = Math.ceil(body.resolution / 8);
330
- // impulses wait for a frame that steps: a paused frame must not drop them
331
- const impulses = steps > 0 ? surface.impulses.splice(0, WATER_WAVE_IMPULSE_LIMIT) : [];
332
- const parameters = [];
333
-
334
- for (let s = 0; s < steps; s++) {
335
- parameters.push(this.#parameters(surface, body, time_start + s * this.step,
336
- s === 0 ? impulses.length : 0));
337
- }
338
-
339
- while (impulses.length < WATER_WAVE_IMPULSE_LIMIT) {
340
- impulses.push([0, 0, 0, 0]);
341
- }
342
-
343
- for (const p of parameters) { p.impulses = impulses; }
344
-
345
- const write_parameters = this.#parameters(surface, body, time_start + steps * this.step, 0);
346
- write_parameters.impulses = impulses;
347
-
348
- const start_parity = body.parity;
349
- body.parity = (start_parity + steps) % 2;
350
- body.written = true;
351
-
352
- const end_parity = body.parity;
353
-
354
- const pass = graph.add("Water / surface update", {}, (data, resources, { encoder, graphics }) => {
355
- const terrain_height = graphics.textures.obtain(surface.height_texture).obtainView();
356
- const height_sampler = graphics.samplers.obtain(SAMPLER_LINEAR_UPSCALE);
357
-
358
- let parity = start_parity;
359
-
360
- for (let s = 0; s < parameters.length; s++) {
361
- shader_water_wave_step.dispatch({
362
- encoder,
363
- bindings: {
364
- params: encoder.allocateTransientValueBuffer(WATER_WAVE_PARAMETERS_STRUCT, parameters[s]),
365
- terrain_height,
366
- height_sampler,
367
- state_current: body.state[parity],
368
- state_previous: body.state[1 - parity],
369
- },
370
- group_count_x: groups,
371
- group_count_y: groups,
372
- });
373
-
374
- parity = 1 - parity;
375
- }
376
-
377
- shader_water_surface_write.dispatch({
378
- encoder,
379
- bindings: {
380
- params: encoder.allocateTransientValueBuffer(WATER_WAVE_PARAMETERS_STRUCT, write_parameters),
381
- terrain_height,
382
- height_sampler,
383
- state: body.state[end_parity],
384
- vertices: body.vertices,
385
- },
386
- group_count_x: groups,
387
- group_count_y: groups,
388
- });
389
- });
390
-
391
- // writes persistent resources that later passes read directly
392
- pass.make_side_effect();
393
- }
394
- }
395
-
396
- /**
397
- * Slope variance of the waves a grid does not resolve, from the wind: the Cox-Munk total,
398
- * 0.003 + 5.12e-3·U for wind speed U in m/s (Ocean Optics Web Book, "Cox-Munk sea surface slope
399
- * statistics"). The fit's intercept is ramped in below 1 m/s, where it has no data, so still water
400
- * is a mirror rather than carrying the open sea's background slopes.
401
- *
402
- * @param {number} wind_speed m/s
403
- * @returns {number}
404
- */
405
- export function wind_unresolved_variance(wind_speed) {
406
- const u = Math.max(wind_speed, 0);
407
- return 0.003 * Math.min(u, 1) + 5.12e-3 * u;
408
- }
1
+ import Signal from "../../../../core/events/signal/Signal.js";
2
+ import { assert } from "../../../../core/assert.js";
3
+ import { WATER_WAVE_BATCH_STRUCT, shader_water_wave_batch, shader_water_wave_batch_finish } from "./shader_water_wave_batch.js";
4
+ import { shader_water_wave_bounds, shader_water_wave_domain } from "./shader_water_wave_domain.js";
5
+
6
+ /**
7
+ * A shared wave atlas, indexed by occupied water_waves rows. Calm bodies allocate no grid.
8
+ * Each fixed step dispatches the whole atlas once; tessellated vertices sample it in local xz.
9
+ * The regular grid is a displacement field, never the rendered water footprint.
10
+ */
11
+ export class GPUWaterWaveSimulation {
12
+ onInputsConsumed = new Signal();
13
+ resolution = 128;
14
+ step = 1 / 120;
15
+ max_steps_per_frame = 8;
16
+ damping = 0.08;
17
+ #device = null;
18
+ #scene = null;
19
+ #state = [];
20
+ #domain = null;
21
+ #capacity = 0;
22
+ #resolution = 0;
23
+ #parity = 0;
24
+ #pending = 0;
25
+ #time = 0;
26
+ #recorded = new WeakSet();
27
+ #write_pending = true;
28
+ get time() { return this.#time; }
29
+ get buffer() { return this.#state[this.#parity]; }
30
+ get grid_resolution() { return this.#resolution || this.resolution; }
31
+
32
+ advance(dt) {
33
+ assert.isFinite(dt, 'dt'); assert.greaterThanOrEqual(dt, 0, 'dt');
34
+ this.#pending += dt;
35
+ this.#write_pending = true;
36
+ }
37
+
38
+ dispose() {
39
+ for (const buffer of this.#state) { buffer.destroy(); }
40
+ this.#domain?.destroy(); this.#domain = null;
41
+ this.#state = []; this.#capacity = 0; this.#device = null; this.#scene = null;
42
+ this.#recorded = new WeakSet();
43
+ this.#write_pending = true;
44
+ }
45
+
46
+ record({ graph, device, scene }) {
47
+ if (this.#recorded.has(graph)) { return; }
48
+ if (device !== this.#device || scene !== this.#scene) {
49
+ this.dispose(); this.#device = device; this.#scene = scene;
50
+ }
51
+ this.#recorded.add(graph);
52
+ if (!this.#write_pending) { return; }
53
+ this.#write_pending = false;
54
+ const table = scene.scene_database.get('water_waves');
55
+ const capacity = table.count === 0 ? 0 : table.element_capacity;
56
+ assert.isInteger(this.resolution, 'resolution'); assert.greaterThanOrEqual(this.resolution, 2, 'resolution');
57
+ assert.greaterThan(this.step, 0, 'step');
58
+ const resize = capacity > this.#capacity || (capacity === 0 && this.#capacity !== 0) || this.resolution !== this.#resolution;
59
+ const old = this.#state;
60
+ const old_domain = this.#domain;
61
+ if (resize || old.length === 0) {
62
+ const size = Math.max(4, capacity * this.resolution ** 2 * 4);
63
+ assert.lessThanOrEqual(size, device.limits.maxStorageBufferBindingSize, 'Water wave atlas exceeds device storage limit; lower waves.resolution');
64
+ this.#state = [0, 1].map(i => device.createBuffer({ label: `Water / wave state ${i}`, size,
65
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST }));
66
+ this.#domain = device.createBuffer({ label: 'Water / authored footprint', size,
67
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST });
68
+ this.#capacity = capacity;
69
+ }
70
+ const same_resolution = this.#resolution === this.resolution;
71
+ this.#resolution = this.resolution;
72
+ const steps = Math.min(Math.floor(this.#pending / this.step + 1e-6), this.max_steps_per_frame);
73
+ this.#pending = Math.max(0, Math.min(this.#pending - steps * this.step, this.step));
74
+ const start = this.#parity, time = this.#time, state = this.#state, domain = this.#domain;
75
+ this.#parity = (start + steps) % 2;
76
+ this.#time += steps * this.step;
77
+ const n = this.#resolution, dt = this.step, damping = this.damping;
78
+ const pass = graph.add('Water / batched surface update', {}, (_d, _r, { encoder }) => {
79
+ if (state !== old) {
80
+ if (same_resolution && old.length !== 0) {
81
+ for (let i = 0; i < 2; i++) { encoder.copyBufferToBuffer(old[i], 0, state[i], 0, Math.min(old[i].size, state[i].size)); }
82
+ encoder.copyBufferToBuffer(old_domain, 0, domain, 0, Math.min(old_domain.size, domain.size));
83
+ }
84
+ encoder.done.then(() => { for (const buffer of old) { buffer.destroy(); } old_domain?.destroy(); });
85
+ }
86
+ if (capacity === 0) { return; }
87
+ const groups = Math.ceil(capacity * n * n / 128);
88
+ shader_water_wave_domain.dispatch({ encoder, bindings: {
89
+ batch: encoder.allocateTransientValueBuffer(WATER_WAVE_BATCH_STRUCT,
90
+ { resolution: n, capacity, apply_impulses: same_resolution ? 0 : 1 }),
91
+ scene_database: scene.scene_database_buffer, domain,
92
+ geometries: scene.geometries.buffer_metadata,
93
+ blas_lookup: scene.geometries.blas.buffer_metadata, blas_data: scene.geometries.blas.buffer_data,
94
+ meshlet_metadata: scene.geometries.meshlets.buffer_metadata, meshlet_data: scene.geometries.meshlets.buffer_data,
95
+ }, group_count_x: Math.min(groups, 65535), group_count_y: Math.ceil(groups / 65535) });
96
+ const dispatch = (parity, step_dt, step_time, apply_impulses) => {
97
+ shader_water_wave_batch.dispatch({ encoder, bindings: {
98
+ batch: encoder.allocateTransientValueBuffer(WATER_WAVE_BATCH_STRUCT,
99
+ { resolution: n, capacity, dt: step_dt, time: step_time, damping, apply_impulses }),
100
+ scene_database: scene.scene_database_buffer, domain, state_current: state[parity], state_previous: state[1 - parity],
101
+ }, group_count_x: Math.min(groups, 65535), group_count_y: Math.ceil(groups / 65535) });
102
+ };
103
+ // Clear both histories of new/reused slots before advancing, then release the reset flag.
104
+ dispatch(0, 0, time, 0); dispatch(1, 0, time, 0);
105
+ const finish = apply_impulses => {
106
+ const groups = table.dispatch_group_count(64);
107
+ shader_water_wave_batch_finish.dispatch({ encoder, bindings: { scene_database: scene.scene_database_buffer,
108
+ batch: encoder.allocateTransientValueBuffer(WATER_WAVE_BATCH_STRUCT,
109
+ { resolution: n, capacity, dt, time, damping, apply_impulses }) },
110
+ group_count_x: Math.min(groups, 65535), group_count_y: Math.ceil(groups / 65535) });
111
+ };
112
+ finish(0);
113
+ for (let i = 0; i < steps; i++) { dispatch((start + i) % 2, dt, time + i * dt, i === 0 ? 1 : 0); }
114
+ if (steps > 0) {
115
+ finish(1);
116
+ // Submit is the ownership boundary for staged CPU inputs. Use the encoder's
117
+ // existing synchronous signal so a later scene/update cannot be cleared by
118
+ // an old promise callback.
119
+ encoder.onFinished.addOne(() => this.onInputsConsumed.dispatch(scene));
120
+ }
121
+ shader_water_wave_bounds.dispatch({ encoder, bindings: {
122
+ batch: encoder.allocateTransientValueBuffer(WATER_WAVE_BATCH_STRUCT, { resolution: n, capacity }),
123
+ scene_database: scene.scene_database_buffer, state: state[(start + steps) % 2],
124
+ }, group_count_x: Math.min(capacity, 65535), group_count_y: Math.ceil(capacity / 65535) });
125
+ });
126
+ pass.make_side_effect();
127
+ }
128
+ }
@@ -0,0 +1,6 @@
1
+ /** Most impulses one body applies in one step. */
2
+ export const WATER_WAVE_IMPULSE_LIMIT: 16;
3
+ /** Persistent inputs; the shared dispatch owns timestep and grid resolution. */
4
+ export const WATER_WAVE_RECORD_STRUCT: WebGPUStruct;
5
+ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
6
+ //# sourceMappingURL=WATER_WAVE_RECORD_STRUCT.d.ts.map