@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
@@ -21,15 +21,21 @@ one 1/60-second engine tick. Presets cover the shore, normal incidence, grazing
21
21
  screen edges, the emergent-object/shoreline discontinuity view, and the deliberately unsupported
22
22
  below-interface view. The grazing camera stays over the submerged floor.
23
23
 
24
- Water fields edit the actual component. The surface is a real mesh: a primitive wave simulation on a
25
- 512² grid over the body, driven by the WaterWaves component (wind speed and direction), writes its
26
- its mesh behind the surface interface the production simulation will replace
27
- (WATER_OPTICS_PLAN_2026_10_02.md §7.2). Screen reflections can be disabled while retaining the
24
+ Water is an entity with `Water`, `MeshletGeometry` and `Transform64`. The mesh authors the outline
25
+ and elevations, and the transform places it; Level edits the transform's height. This fixture
26
+ has a curved, coarse authored outline. Optical controls edit Water. Optional WaterWaves supplies wind
27
+ forcing to a persistent shared GPU displacement atlas, with 128² samples per active body. The existing
28
+ geometry BLAS bakes the authored footprint into a simulation mask when a wave row is created;
29
+ dry samples remain zero, including holes and gaps. Vertices sample the field in local xz and move
30
+ along local y. This primitive simulation therefore expects a surface that can be represented as a
31
+ height field in local xz; multiple stacked surfaces sharing that domain also share its displacement.
32
+ Calm meshes allocate no grid. The simulation uses a one-metre reference depth and
33
+ does not infer bathymetry from the mesh. Screen reflections can be disabled while retaining the
28
34
  fallback to the renderer's indirect lighting (IBL, or Brick4 when it is the active mode).
29
35
  The Newton, bounded HZB traversal, and undisplaced control modes all use the same AVBOIT path.
30
36
  The Medium select picks one of the water presets (`shade/renderer/medium/water/water_presets.js`):
31
37
  what fills the body as absorption and scattering in 1/m. The body's colour is not authored — it is the sun
32
- and sky scattered back up the refracted view ray, single scattering for now, and In-scatter segments
38
+ and sky scattered back up the refracted view ray, using the existing water column model. In-scatter segments
33
39
  sets how many steps that integral takes. Seen from above, light leaving the water crosses the surface
34
40
  by Fresnel and the n² law, so the floor reads about half as bright as it would dry.
35
41
 
@@ -62,7 +68,7 @@ Newton miss reason: 0 none/not attempted, 1 bounds/clip, 2 sky, 3 parallel/inval
62
68
  at 65504 for half-float storage. The status display uses green/cyan/purple/orange/pink for those
63
69
  five final classes; red increases with update count.
64
70
 
65
- Compile check compiles all ten production water modules on the active device. Rendering exercises
71
+ Compile check compiles the production water modules on the active device. Rendering exercises
66
72
  their real pipelines and bind groups; the first validation error stops rendering and remains visible
67
73
  in the status panel and console. Restart device resumes after correcting the error. Profile / T
68
74
  uses the existing GPU profiler and exports `.sgpt`. Compare water on/off at a fixed paused camera,
@@ -72,7 +78,7 @@ mode in its note. A device without timestamp-query records structure without tim
72
78
 
73
79
  Copy state writes versioned JSON into the text area and attempts clipboard copying. Apply state
74
80
  restores camera, displayed controls, water/fixture clock, terrain offset and channel order.
75
- GPU particle populations and temporal histories are not serialized: reload/reset them and warm up
81
+ GPU wave fields, particle populations and temporal histories are not serialized: reload/reset them and warm up
76
82
  equally for image/performance comparisons. Probe values describe the captured frame; camera changes
77
83
  require a fresh probe.
78
84
 
@@ -82,8 +88,8 @@ Opaque receiver transport uses the immutable pre-transparency HDR scene. Water c
82
88
  reflection and in-scattered radiance and its RGB transmittance; shared resolve applies the transported opaque background once.
83
89
  Rear transparent surfaces/particles are attenuated at their original screen positions. Their radiance
84
90
  is not sampled through the bent ray. Missing/off-screen receivers get bounded, explicit fallbacks.
85
- Missing receivers use the local terrain column to estimate water thickness; the trace budget is only
86
- an upper bound. Final shading fades the receiver UV toward the control UV around emergent silhouettes,
91
+ Missing receivers use the medium's extinction distance, bounded by the trace budget. Final shading
92
+ fades the receiver UV toward the control UV around emergent silhouettes,
87
93
  shoreline visibility gaps and screen edges, then performs one geometry-aware color lookup. It derives
88
94
  water thickness from that lookup's local receiver plane and builds its complete optical event. It
89
95
  does not crossfade two displaced images. Three quarter-resolution passes form a conservative
@@ -153,6 +159,48 @@ the real GPU; the CPU test does not claim to prove that contract.
153
159
  Blast radius: water lifecycle/shaders/data plus AVBOIT preparation/background plumbing and its
154
160
  tiny-loss resolve guard; existing particle, mesh and ribbon APIs remain intact.
155
161
 
162
+ Water bodies occupy persistent rows in the existing scene database. Optical and component edits
163
+ queue CPU writes; idle updates do not enumerate bodies. GPU page iteration, the existing prefix
164
+ scan, ordered meshlet expansion and indirect draws cover the scene. A GPU reduction supplies signed
165
+ local-y displacement bounds after each simulation update. Body frustum culling expands the authored
166
+ bounds by those extrema before applying the GPU world transform.
167
+
168
+ Following Far Cry 5's view-tile approach, each candidate triangle classifies its swept footprint into
169
+ view tiles. A tile contains 16×16 cells; `settings.tessellation_pixels` sets their reference-view spacing
170
+ (4 pixels by default). GPU prefix sums drive one indirect patch draw in each surface pass. Patch
171
+ vertices reconstruct the authored triangle in homogeneous barycentric coordinates, clip each cell
172
+ to its boundary, then sample displacement and transform it into the render view. The mesh supplies
173
+ outline and rest elevations; it does not need wave-scale subdivisions. Holes and disconnected
174
+ surfaces remain separate. Triangle identity survives classification, including overlapping bodies;
175
+ only displaced raster depth selects the nearest interface. Storage scales with source triangles,
176
+ without allocating a triangle×tile list or reading tile counts back to the CPU.
177
+
178
+ Simulated bodies use a shared local-xz reference plane at the displaced authored bound farther
179
+ from the near plane. Classification sweeps rest elevations and both signed displacement endpoints
180
+ against the view planes. Calm bodies project the authored triangles directly. Reference tiles can lie outside the viewport
181
+ when displacement can bring them into view. Opaque depth is tested after displacement, so an
182
+ undisplaced depth rejection cannot hide a crest. Both surface passes share the same patch counts
183
+ and reconstruction inputs. Simulation is independent of camera position and render resolution;
184
+ wave dispatch count depends on fixed steps, not the number of bodies. Device buffer and indirect
185
+ draw limits still bound scene complexity. If the reference is coplanar with the camera, it moves
186
+ farther beyond the displacement envelope to retain a projectable surface. The body's conservative
187
+ swept span sets one shared grid spacing, at least the requested pixel spacing. This bounds each
188
+ triangle's patches to a viewport-sized cell budget per axis, including near-plane displacement,
189
+ and keeps adjacent triangles' edge subdivisions identical. Large envelopes near the camera can
190
+ therefore reduce tessellation detail. Receiver attenuation and column scattering
191
+ use the displaced surface's world normal and local tangent plane, so placement can rotate the body.
192
+
193
+ Reference: Branislav Grujic, *Water Rendering in Far Cry 5*, GDC 2018,
194
+ [presentation](https://media.gdcvault.com/gdc2018/presentations/Grujic_Branislav_WaterRenderingFarCry5.pdf),
195
+ slides 49–56. This implementation reconstructs each retained triangle directly rather than keeping
196
+ only the nearest rest-depth sample, to preserve overlap candidates and exact authored boundaries.
197
+
198
+ Water binary version 4 stores optics only. Version 3 and earlier, and JSON with level or size,
199
+ require asset migration before loading: generate the old footprint as MeshletGeometry and place
200
+ it with Transform64. A component-only upgrader cannot create sibling components or split water
201
+ from an entity whose transform places terrain or another object; it reports that requirement
202
+ instead of silently losing placement. MeshletGeometry uses its existing binary adapter as an ECS component.
203
+
156
204
  Reference: Mayer, Assarsson and Sintorn, *Ultrafast Screen-Space Refractions and Caustics via Newton's
157
205
  Method*, JCGT 15(1), 2026, [paper](https://jcgt.org/published/0015/01/03/paper-lowres.pdf).
158
206
  See [the integration plan](../../../../WATER_MAYER2026_INTEGRATION_PLAN.md) for the transport contract.
@@ -8,6 +8,7 @@ import { EntityComponentDataset } from "../../../engine/ecs/EntityComponentDatas
8
8
  import { EntityManager } from "../../../engine/ecs/EntityManager.js";
9
9
  import { Entity } from "../../../engine/ecs/Entity.js";
10
10
  import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
11
+ import { t64_announce_change } from "../../../engine/ecs/transform/t64_announce_change.js";
11
12
  import { Light } from "../../../engine/graphics/ecs/light/Light.js";
12
13
  import { GPUParticleEmitterSystem } from "../../../engine/graphics3/GPUParticleEmitterSystem.js";
13
14
  import { GraphicsEngine } from "../../../engine/graphics3/GraphicsEngine.js";
@@ -24,6 +25,11 @@ import { ParticipatingMediaVolume } from "../../renderer/volumetrics/Participati
24
25
  import { water_medium_preset } from "../../renderer/medium/water/water_presets.js";
25
26
  import { water_finalize_shader_brick4, water_finalize_shader_ibl, water_shader } from "../../renderer/water/shader_water.js";
26
27
  import * as water_shaders from "../../renderer/water/shader_water_avboit.js";
28
+ import { shader_water_bodies_derive } from "../../renderer/water/medium/shader_water_bodies_derive.js";
29
+ import { shader_water_meshlet_counts, shader_water_meshlets_expand } from "../../renderer/water/medium/shader_water_meshlets.js";
30
+ import { shader_water_wave_batch, shader_water_wave_batch_finish } from "../../renderer/water/surface/shader_water_wave_batch.js";
31
+ import { shader_water_wave_domain, shader_water_wave_bounds } from "../../renderer/water/surface/shader_water_wave_domain.js";
32
+ import { shader_water_tiles } from "../../renderer/water/surface/shader_water_tiles.js";
27
33
  import { install_profile_hotkey } from "../profile_hotkey.js";
28
34
  import { build_world } from "./world.js";
29
35
 
@@ -47,7 +53,7 @@ async function main() {
47
53
  const assets = new AssetManager({context:{},executor:new ConcurrentExecutor()});
48
54
  await assets.registerLoader(GameAssetType.Image,new ImageRGBADataLoader()); assets.startup();
49
55
  const dataset = new EntityComponentDataset(), entities = new EntityManager();
50
- const water_system = new WaterSystem(graphics);
56
+ const water_system = new WaterSystem(graphics,scene);
51
57
  entities.addSystem(new ShadedGeometrySystem(graphics,scene)); entities.addSystem(new LightSystem(graphics,scene));
52
58
  entities.addSystem(new GPUParticleEmitterSystem(graphics,scene,assets)); entities.addSystem(water_system);
53
59
  entities.attachDataset(dataset);
@@ -73,7 +79,7 @@ async function main() {
73
79
  function configure() {
74
80
  revision++;
75
81
  const w=world.water,s=water_system.settings,r=graphics.renderer;
76
- w.level.set(number("level"));w.ior.set(number("ior"));w.roughness.set(number("roughness"));
82
+ world.water_transform.setTranslation(16,number("level"),16);t64_announce_change(dataset,world.water_entity);w.ior.set(number("ior"));w.roughness.set(number("roughness"));
77
83
  world.waves.windSpeed.set(number("wind"));world.waves.windDirection.set(number("wind_direction")*Math.PI/180);
78
84
  w.medium=water_medium_preset({preset:element("medium").value});
79
85
  Object.assign(s,{enabled:checked("enabled"),mode:number("mode"),max_updates:number("iterations"),
@@ -157,7 +163,10 @@ async function main() {
157
163
  element("compile").onclick=async()=>{
158
164
  if(!ready)return;
159
165
  const device=graphics.renderer.graphics.device,errors=[];
160
- for(const shader of [water_shader,water_finalize_shader_ibl,water_finalize_shader_brick4,...Object.values(water_shaders).map(s=>s.descriptor)]){
166
+ for(const shader of [water_shader,water_finalize_shader_ibl,water_finalize_shader_brick4,
167
+ ...[shader_water_bodies_derive,shader_water_meshlet_counts,shader_water_meshlets_expand,
168
+ shader_water_wave_batch,shader_water_wave_batch_finish,shader_water_wave_domain,shader_water_wave_bounds,
169
+ shader_water_tiles,...Object.values(water_shaders)].map(s=>s.descriptor)]){
161
170
  if(typeof shader?.source!=="string")continue;
162
171
  const module=device.createShaderModule({code:shader.source});const info=await module.getCompilationInfo();
163
172
  errors.push(...info.messages.filter(m=>m.type==="error").map(m=>`${m.lineNum}: ${m.message}`));
@@ -4,6 +4,7 @@ export function build_world(dataset: any): Promise<{
4
4
  water: Water;
5
5
  waves: WaterWaves;
6
6
  water_entity: any;
7
+ water_transform: Transform64;
7
8
  card: {
8
9
  transform: Transform64;
9
10
  component: ShadedGeometry;
@@ -1 +1 @@
1
- {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/water_refraction/world.js"],"names":[],"mappings":"AA4DA,+FAA+F;AAC/F;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EC;AA9GM,mEAAsE;oBAzBzD,4CAA4C;kBAI9C,6CAA6C;uBACxC,kDAAkD;4BAJ7C,8CAA8C;+BAE3C,wDAAwD;iCAetD,0CAA0C;4BAD/C,qCAAqC;+BAXlC,0DAA0D"}
1
+ {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/water_refraction/world.js"],"names":[],"mappings":"AA4DA,+FAA+F;AAC/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFC;AAxHM,mEAAsE;oBAzBzD,4CAA4C;kBAI9C,6CAA6C;uBACxC,kDAAkD;4BAJ7C,8CAA8C;+BAE3C,wDAAwD;iCAetD,0CAA0C;4BAD/C,qCAAqC;+BAXlC,0DAA0D"}
@@ -82,10 +82,20 @@ export async function build_world(dataset) {
82
82
  const floor_material=material([1,1,1]); floor_material.texture_albedo=checker();
83
83
  const floor_transform=pose(0,0,0);
84
84
  const floor_entity=build(new Entity().add(floor_transform).add(shaded(meshlets(floor_geo),floor_material)));
85
- const water=new Water(); water.level.set(0);
85
+ const water=new Water();
86
+ const water_plane=make_plane_geometry(40,40,8,8);
87
+ const water_positions=water_plane.getAttribute(StandardAttributes.Position).data;
88
+ const water_normals=water_plane.getAttribute(StandardAttributes.Normal).data;
89
+ for(let i=0;i<water_positions.length;i+=3) {
90
+ water_positions[i+2]=-water_positions[i+1];water_positions[i+1]=0;
91
+ // An authored outline: the displacement grid never supplies the rendered boundary.
92
+ water_positions[i]*=0.75+0.2*Math.cos(water_positions[i+2]*Math.PI/20);
93
+ water_normals[i]=0;water_normals[i+1]=1;water_normals[i+2]=0;
94
+ }
95
+ const water_geometry=meshlets(water_plane),water_transform=pose(16,0,16);
86
96
  // the primitive wave simulation's forcing; the overlapping second body below has none and stays calm
87
97
  const waves=new WaterWaves();
88
- const water_entity=build(new Entity().add(water).add(waves));
98
+ const water_entity=build(new Entity().add(water).add(waves).add(water_geometry).add(water_transform));
89
99
  const add_mesh=(geo,m,x,y,z,rotation)=>{
90
100
  const t=pose(x,y,z,rotation);const component=shaded(meshlets(geo),m);
91
101
  const entity=build(new Entity().add(t).add(component)); return {transform:t,component,entity};
@@ -106,7 +116,7 @@ export async function build_world(dataset) {
106
116
  const batch=new DynamicMeshBatch(); batch.add(ribbon);
107
117
  let secondary=null;
108
118
  let last_update=null;
109
- return {terrain,water,waves,water_entity,card,submerged,batch,ribbon,effects:live_effects,entities,
119
+ return {terrain,water,waves,water_entity,water_transform,card,submerged,batch,ribbon,effects:live_effects,entities,
110
120
  reset_particles() {
111
121
  particle_transforms.forEach(({entity},i)=>{
112
122
  const replacement=live_effects[i].clone();
@@ -132,8 +142,8 @@ export async function build_world(dataset) {
132
142
  terrain.samplerHeight=sampler(offset); floor_transform.setTranslation(0,offset,0);t64_announce_change(dataset,floor_entity);
133
143
  },
134
144
  overlap(enabled) {
135
- if(enabled&&secondary===null) {const other=new Water();other.level.set(water.level.getValue()-0.4);
136
- other.medium=water_medium_preset({preset:'turbid_river'});secondary=build(new Entity().add(other));}
145
+ if(enabled&&secondary===null) {const other=new Water();const placement=pose(16,water_transform.translation_y-0.4,16);
146
+ other.medium=water_medium_preset({preset:'turbid_river'});secondary=build(new Entity().add(other).add(water_geometry).add(placement));}
137
147
  if(!enabled&&secondary!==null) {dataset.removeEntity(secondary);secondary=null;}
138
148
  },
139
149
  dispose() {entities.forEach(id=>{if(dataset.entityExists(id)) dataset.removeEntity(id);});batch.clear();},
@@ -75,6 +75,25 @@ export class Renderer {
75
75
  get shadow_update_budget(): number;
76
76
  set shadow_cascade_count(v: number);
77
77
  get shadow_cascade_count(): number;
78
+ /**
79
+ * Give directional lights virtual shadow maps — a clipmap of pages rendered as the view asks for
80
+ * them and as moving casters make them stale — instead of cascades. Pushed to the scene's shadow
81
+ * context each frame; a flip rebuilds every directional map. See
82
+ * {@link GPUSceneShadowmapContext.use_virtual_shadow_maps}.
83
+ * @type {boolean}
84
+ */
85
+ feature_virtual_shadow_maps: boolean;
86
+ set shadow_virtual_page_budget(v: number);
87
+ get shadow_virtual_page_budget(): number;
88
+ /**
89
+ * Added to the clipmap level every point of a virtual shadow map selects; positive is coarser,
90
+ * fewer pages and softer shadows. Pushed each frame; see
91
+ * {@link GPUSceneShadowmapContext.virtual_lod_bias}.
92
+ * @type {number}
93
+ */
94
+ shadow_virtual_lod_bias: number;
95
+ set shadow_virtual_first_texel_size(v: number);
96
+ get shadow_virtual_first_texel_size(): number;
78
97
  feature_bloom_enabled: boolean;
79
98
  feature_automatic_exposure_enabled: boolean;
80
99
  set exposure_compensation(v: number);
@@ -1 +1 @@
1
- {"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
@@ -78,6 +78,8 @@ import { graph_import_texture } from "./shader/graph/graph_import_texture.js";
78
78
  import { ShadeUpscalerType } from "./ShadeUpscalerType.js";
79
79
  import { DEFAULT_SHADOWMAP_UPDATE_BUDGET } from "./shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js";
80
80
  import { SHADOWMAP_CSM_DEFAULT_CASCADE_COUNT } from "./shadow/map/csm/SHADOWMAP_CSM_DEFAULT_CASCADE_COUNT.js";
81
+ import { DEFAULT_VSM_FIRST_TEXEL_SIZE } from "./shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.js";
82
+ import { DEFAULT_VSM_PAGE_BUDGET } from "./shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.js";
81
83
  import { CascadedSceneSDF } from "./shadow/sdf/cascade/CascadedSceneSDF.js";
82
84
  import { STATIC_GRAPHICS_ENGINE_ASSETS } from "./STATIC_GRAPHICS_ENGINE_ASSETS.js";
83
85
  import { GPUTextureContext } from "./texture/GPUTextureContext.js";
@@ -271,6 +273,58 @@ export class Renderer {
271
273
  return this.#shadow_cascade_count;
272
274
  }
273
275
 
276
+ /**
277
+ * Give directional lights virtual shadow maps — a clipmap of pages rendered as the view asks for
278
+ * them and as moving casters make them stale — instead of cascades. Pushed to the scene's shadow
279
+ * context each frame; a flip rebuilds every directional map. See
280
+ * {@link GPUSceneShadowmapContext.use_virtual_shadow_maps}.
281
+ * @type {boolean}
282
+ */
283
+ feature_virtual_shadow_maps = false;
284
+
285
+ /**
286
+ * Virtual shadow map pages a scene may render per frame, pushed to the scene's shadow context
287
+ * each frame; see {@link DEFAULT_VSM_PAGE_BUDGET} for what a page costs and what waits.
288
+ * @type {number}
289
+ */
290
+ #shadow_virtual_page_budget = DEFAULT_VSM_PAGE_BUDGET;
291
+
292
+ set shadow_virtual_page_budget(v) {
293
+ assert.isNonNegativeInteger(v, 'shadow_virtual_page_budget');
294
+
295
+ this.#shadow_virtual_page_budget = v;
296
+ }
297
+
298
+ get shadow_virtual_page_budget() {
299
+ return this.#shadow_virtual_page_budget;
300
+ }
301
+
302
+ /**
303
+ * Added to the clipmap level every point of a virtual shadow map selects; positive is coarser,
304
+ * fewer pages and softer shadows. Pushed each frame; see
305
+ * {@link GPUSceneShadowmapContext.virtual_lod_bias}.
306
+ * @type {number}
307
+ */
308
+ shadow_virtual_lod_bias = 0;
309
+
310
+ /**
311
+ * World size of a virtual shadow map's finest texel, in metres. Pushed each frame; a change
312
+ * rebuilds the maps. See {@link DEFAULT_VSM_FIRST_TEXEL_SIZE}.
313
+ * @type {number}
314
+ */
315
+ #shadow_virtual_first_texel_size = DEFAULT_VSM_FIRST_TEXEL_SIZE;
316
+
317
+ set shadow_virtual_first_texel_size(v) {
318
+ assert.isNumber(v, 'shadow_virtual_first_texel_size');
319
+ assert.greaterThan(v, 0, 'shadow_virtual_first_texel_size');
320
+
321
+ this.#shadow_virtual_first_texel_size = v;
322
+ }
323
+
324
+ get shadow_virtual_first_texel_size() {
325
+ return this.#shadow_virtual_first_texel_size;
326
+ }
327
+
274
328
  feature_bloom_enabled = true;
275
329
  feature_automatic_exposure_enabled = true;
276
330
 
@@ -2116,6 +2170,12 @@ export class Renderer {
2116
2170
  sm.update_budget = this.#shadow_update_budget;
2117
2171
  // How many cascades a directional map has; a change rebuilds the maps inside process_lights.
2118
2172
  sm.cascade_count = this.#shadow_cascade_count;
2173
+ // Virtual shadow maps for directional lights, and what they may spend; a flip of the flag or
2174
+ // of the first texel rebuilds the maps inside process_lights.
2175
+ sm.use_virtual_shadow_maps = this.feature_virtual_shadow_maps;
2176
+ sm.virtual_page_budget = this.#shadow_virtual_page_budget;
2177
+ sm.virtual_lod_bias = this.shadow_virtual_lod_bias;
2178
+ sm.virtual_first_texel_size = this.#shadow_virtual_first_texel_size;
2119
2179
 
2120
2180
  const taa = this.#taa;
2121
2181
 
@@ -2271,6 +2331,17 @@ export class Renderer {
2271
2331
  });
2272
2332
  }
2273
2333
 
2334
+ // Virtual shadow map feedback: the casters that moved, the pages they left stale, and the
2335
+ // pages this view's depth asks for, read back for the maps' next frames. No-op unless a
2336
+ // directional light has a virtual map.
2337
+ if (this.#feature_shadows_enabled) {
2338
+ sm.graph_virtual_feedback({
2339
+ graph,
2340
+ view: view_ctx,
2341
+ depth: gr_raster_depth,
2342
+ });
2343
+ }
2344
+
2274
2345
  // run materials
2275
2346
  const mat_g = graphics.materials.graph_viz_render({
2276
2347
  graph,
@@ -2675,7 +2746,7 @@ export class Renderer {
2675
2746
  for (let i = 0; i < transparency_channels.length; i++) {
2676
2747
  const channel = transparency_channels[i];
2677
2748
 
2678
- if (channel.avboit_is_empty !== undefined && channel.avboit_is_empty()) {
2749
+ if (channel.avboit_is_empty !== undefined && channel.avboit_is_empty(view_ctx)) {
2679
2750
  continue;
2680
2751
  }
2681
2752
 
@@ -125,6 +125,14 @@ export class GPUAnimationManager {
125
125
  * @returns {number}
126
126
  */
127
127
  get_skin_matrix_offset(skin_id: number): number;
128
+ /**
129
+ * How many joints the skin has — rows of the `skin_matrices` scratch buffer from
130
+ * {@link get_skin_matrix_offset}. Fixed once the skin is registered.
131
+ *
132
+ * @param {number} skin_id
133
+ * @returns {number}
134
+ */
135
+ get_skin_joint_count(skin_id: number): number;
128
136
  /**
129
137
  * Add an animation curve. Its keyframes go into `animation_keyframes` as one run of rows, in
130
138
  * order, and the curve's header names the run.
@@ -1 +1 @@
1
- {"version":3,"file":"GPUAnimationManager.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/GPUAnimationManager.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GPUAnimationManager.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/GPUAnimationManager.js"],"names":[],"mappings":"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"}
@@ -100,6 +100,7 @@ const CLIP_FLAGS_WORD = ANIMATION_CLIP_STATE_STRUCT.get('flags').offset / 4;
100
100
  * Word of a skin record holding its first joint row — where its matrices start.
101
101
  */
102
102
  const SKIN_JOINTS_FIRST_WORD = ANIMATION_SKIN_STRUCT.get('joints_first').offset / 4;
103
+ const SKIN_JOINT_COUNT_WORD = ANIMATION_SKIN_STRUCT.get('joint_count').offset / 4;
103
104
 
104
105
  /**
105
106
  * A joint's `node` alone — what naming a pending skin's nodes writes, and all it uploads.
@@ -580,6 +581,23 @@ export class GPUAnimationManager {
580
581
  return joints_first;
581
582
  }
582
583
 
584
+ /**
585
+ * How many joints the skin has — rows of the `skin_matrices` scratch buffer from
586
+ * {@link get_skin_matrix_offset}. Fixed once the skin is registered.
587
+ *
588
+ * @param {number} skin_id
589
+ * @returns {number}
590
+ */
591
+ get_skin_joint_count(skin_id) {
592
+ assert.isNonNegativeInteger(skin_id, 'skin_id');
593
+
594
+ const joint_count = this.#database.get('animation_skins').get_word(skin_id, SKIN_JOINT_COUNT_WORD);
595
+
596
+ assert.defined(joint_count, `unknown skin_id ${skin_id}`);
597
+
598
+ return joint_count;
599
+ }
600
+
583
601
  /**
584
602
  * Add an animation curve. Its keyframes go into `animation_keyframes` as one run of rows, in
585
603
  * order, and the curve's header names the run.
@@ -65,6 +65,13 @@ export class GPUMeshSkinningContext {
65
65
  * @returns {GPUBuffer|null}
66
66
  */
67
67
  get bindings_buffer(): any;
68
+ /**
69
+ * Bound {@link SkinnedMesh}es — the records {@link bindings_buffer} holds once {@link update} has
70
+ * uploaded them, which it does on the frame they change.
71
+ *
72
+ * @returns {number}
73
+ */
74
+ get binding_count(): number;
68
75
  /**
69
76
  * Per-meshlet base offsets into {@link prev_positions_buffer},
70
77
  * indexed by absolute meshlet metadata row. Non-clone meshlets
@@ -1 +1 @@
1
- {"version":3,"file":"GPUMeshSkinningContext.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js"],"names":[],"mappings":"AAmFA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;IAgNI;;;;;;;OAOG;IACH,sEAPW;QACV,UAAgB,EAAE,kBAAkB,CAAC;QACrC,iBAAuB,EAAE,mBAAmB,CAAC;QAC7C,aAAmB,EAAE,eAAe,CAAC;QACrC,MAAY,YAAY;KACrB,EAcH;IAED;;;;;;OAMG;IACH,iCAEC;IAED;;;;;;;OAOG;IACH,yCAEC;IAED;;;;;;OAMG;IACH,2BAEC;IAED;;;;;;;OAOG;IACH,wCAEC;IAED;;;;;;;;;;;;OAYG;IACH,qBAJW,MAAM,YACN,eAAe,GACb,mBAAmB,CAqB/B;IAED;;;;;OAKG;IACH,iBAHW,MAAM,GACJ,mBAAmB,GAAC,SAAS,CAMzC;IAED;;;;;;;;;;OAUG;IACH,aAHW,MAAM,WACN,MAAM,QAwBhB;IAED;;;;;;;OAOG;IACH,oBAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;;;;OAUG;IACH,eAFW,MAAM,QAYhB;IAED;;;;;;;;OAQG;IACH,4BAFW,MAAM,QAUhB;IA4FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,sBAFW,MAAM,QAqBhB;IAuBD;;;;;;;;;;;;;;;;;OAiBG;IACH,gBAJW,sBAAsB,GACpB,OAAO,CA0NnB;IAkXD;;;;;;;OAOG;IACH,gBA+BC;;CACJ;qCA/wCY,OAAO,2CAA2C,EAAE,sBAAsB;iCAC1E,OAAO,sCAAsC,EAAE,kBAAkB;8BACjE,OAAO,gCAAgC,EAAE,eAAe;8BACxD,OAAO,mCAAmC,EAAE,eAAe;kCAC3D,OAAO,uCAAuC,EAAE,mBAAmB;kCACnE,OAAO,2BAA2B,EAAE,mBAAmB"}
1
+ {"version":3,"file":"GPUMeshSkinningContext.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js"],"names":[],"mappings":"AAmFA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;IAgNI;;;;;;;OAOG;IACH,sEAPW;QACV,UAAgB,EAAE,kBAAkB,CAAC;QACrC,iBAAuB,EAAE,mBAAmB,CAAC;QAC7C,aAAmB,EAAE,eAAe,CAAC;QACrC,MAAY,YAAY;KACrB,EAcH;IAED;;;;;;OAMG;IACH,iCAEC;IAED;;;;;;;OAOG;IACH,yCAEC;IAED;;;;;;OAMG;IACH,2BAEC;IAED;;;;;OAKG;IACH,4BAEC;IAED;;;;;;;OAOG;IACH,wCAEC;IAED;;;;;;;;;;;;OAYG;IACH,qBAJW,MAAM,YACN,eAAe,GACb,mBAAmB,CAqB/B;IAED;;;;;OAKG;IACH,iBAHW,MAAM,GACJ,mBAAmB,GAAC,SAAS,CAMzC;IAED;;;;;;;;;;OAUG;IACH,aAHW,MAAM,WACN,MAAM,QAwBhB;IAED;;;;;;;OAOG;IACH,oBAHW,MAAM,GACJ,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;;;;OAUG;IACH,eAFW,MAAM,QAYhB;IAED;;;;;;;;OAQG;IACH,4BAFW,MAAM,QAUhB;IA4FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,sBAFW,MAAM,QAqBhB;IAuBD;;;;;;;;;;;;;;;;;OAiBG;IACH,gBAJW,sBAAsB,GACpB,OAAO,CA0NnB;IAmXD;;;;;;;OAOG;IACH,gBA+BC;;CACJ;qCA1xCY,OAAO,2CAA2C,EAAE,sBAAsB;iCAC1E,OAAO,sCAAsC,EAAE,kBAAkB;8BACjE,OAAO,gCAAgC,EAAE,eAAe;8BACxD,OAAO,mCAAmC,EAAE,eAAe;kCAC3D,OAAO,uCAAuC,EAAE,mBAAmB;kCACnE,OAAO,2BAA2B,EAAE,mBAAmB"}
@@ -372,6 +372,16 @@ export class GPUMeshSkinningContext {
372
372
  return this.#bindings_buffer;
373
373
  }
374
374
 
375
+ /**
376
+ * Bound {@link SkinnedMesh}es — the records {@link bindings_buffer} holds once {@link update} has
377
+ * uploaded them, which it does on the frame they change.
378
+ *
379
+ * @returns {number}
380
+ */
381
+ get binding_count() {
382
+ return this.#bindings.length;
383
+ }
384
+
375
385
  /**
376
386
  * Per-meshlet base offsets into {@link prev_positions_buffer},
377
387
  * indexed by absolute meshlet metadata row. Non-clone meshlets
@@ -1233,6 +1243,7 @@ export class GPUMeshSkinningContext {
1233
1243
 
1234
1244
  write_gpu_typed_buffer({
1235
1245
  skin_matrix_offset: this.#animation_manager.get_skin_matrix_offset(b.skin_id),
1246
+ skin_matrix_count: this.#animation_manager.get_skin_joint_count(b.skin_id),
1236
1247
  source_meshlet_metadata_offset: b.source_meshlet_metadata_offset,
1237
1248
  clone_meshlet_metadata_offset: b.clone_meshlet_metadata_offset,
1238
1249
  meshlet_count: b.meshlet_count,
@@ -9,7 +9,9 @@
9
9
  * - `skin_matrix_offset` is the skin's first joint row, read from the
10
10
  * animation manager's {@link GPUAnimationManager#get_skin_matrix_offset}
11
11
  * — a joint's matrix sits at its row — so the shader can index
12
- * `skin_matrices` directly without dereferencing the skin record.
12
+ * `skin_matrices` directly without dereferencing the skin record;
13
+ * `skin_matrix_count`, its number of joints, from
14
+ * {@link GPUAnimationManager#get_skin_joint_count}.
13
15
  * - The two `*_meshlet_metadata_offset` values are the starts of the
14
16
  * source's and clone's meshlet ranges in the meshlet metadata
15
17
  * buffer; combined with `meshlet_count`, they bound the per-binding
@@ -1 +1 @@
1
- {"version":3,"file":"SKINNING_BINDING_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,mDAwDsB;6BA3EO,mCAAmC"}
1
+ {"version":3,"file":"SKINNING_BINDING_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,mDA+DsB;6BApFO,mCAAmC"}
@@ -12,7 +12,9 @@ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
12
12
  * - `skin_matrix_offset` is the skin's first joint row, read from the
13
13
  * animation manager's {@link GPUAnimationManager#get_skin_matrix_offset}
14
14
  * — a joint's matrix sits at its row — so the shader can index
15
- * `skin_matrices` directly without dereferencing the skin record.
15
+ * `skin_matrices` directly without dereferencing the skin record;
16
+ * `skin_matrix_count`, its number of joints, from
17
+ * {@link GPUAnimationManager#get_skin_joint_count}.
16
18
  * - The two `*_meshlet_metadata_offset` values are the starts of the
17
19
  * source's and clone's meshlet ranges in the meshlet metadata
18
20
  * buffer; combined with `meshlet_count`, they bound the per-binding
@@ -26,6 +28,13 @@ export const SKINNING_BINDING_STRUCT = WebGPUStruct.from({
26
28
  */
27
29
  skin_matrix_offset: u32,
28
30
 
31
+ /**
32
+ * How many joints the skin has: its matrices are `skin_matrix_count` rows from
33
+ * `skin_matrix_offset`. The skinning shader needs no count — a vertex names its joints — but a
34
+ * pass over the skin's pose does, such as the virtual shadow map's test of whether it moved.
35
+ */
36
+ skin_matrix_count: u32,
37
+
29
38
  /**
30
39
  * First source meshlet record in the meshlet metadata buffer. The
31
40
  * skinning shader reads attributes (position / normal / tangent /
@@ -1 +1 @@
1
- {"version":3,"file":"table_wgsl_gen_read_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.js"],"names":[],"mappings":"AAyKA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,uEAZW,MAAM,eACN,MAAM,qBAEJ,IAAI,CA8BhB"}
1
+ {"version":3,"file":"table_wgsl_gen_read_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.js"],"names":[],"mappings":"AAqMA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,uEAZW,MAAM,eACN,MAAM,qBAEJ,IAAI,CA8BhB"}
@@ -1,13 +1,17 @@
1
1
  import { assert } from "../../../../../core/assert.js";
2
2
  import {
3
3
  f32,
4
+ i32,
4
5
  mat4x4f,
5
6
  u32,
6
7
  vec2f,
8
+ vec2i,
7
9
  vec2u,
8
10
  vec3f,
11
+ vec3i,
9
12
  vec3u,
10
13
  vec4f,
14
+ vec4i,
11
15
  vec4u
12
16
  } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
13
17
 
@@ -50,6 +54,30 @@ function table_wgsl_gen_read_code_primitive(
50
54
  case f32:
51
55
  builder.extend(`bitcast<f32>(${buffer_name}[base_offset + ${offset}])`);
52
56
  return;
57
+ case i32:
58
+ builder.extend(`bitcast<i32>(${buffer_name}[base_offset + ${offset}])`);
59
+ return;
60
+ case vec2i:
61
+ builder.extend(`vec2<i32>(`);
62
+ builder.indent();
63
+ read_multiple(builder, offset, buffer_name, i32, 2);
64
+ builder.dedent();
65
+ builder.extend(')');
66
+ return;
67
+ case vec3i:
68
+ builder.extend(`vec3<i32>(`);
69
+ builder.indent();
70
+ read_multiple(builder, offset, buffer_name, i32, 3);
71
+ builder.dedent();
72
+ builder.extend(')');
73
+ return;
74
+ case vec4i:
75
+ builder.extend(`vec4<i32>(`);
76
+ builder.indent();
77
+ read_multiple(builder, offset, buffer_name, i32, 4);
78
+ builder.dedent();
79
+ builder.extend(')');
80
+ return;
53
81
  case vec2f:
54
82
  builder.extend(`vec2<f32>(`);
55
83
  builder.indent();
@@ -1 +1 @@
1
- {"version":3,"file":"table_wgsl_gen_write_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.js"],"names":[],"mappings":"AAoHA;;;;;;;;;;;;;;GAcG;AACH,wEANW,MAAM,eACN,MAAM,iCAEN,MAAM,GACJ,IAAI,CAyBhB"}
1
+ {"version":3,"file":"table_wgsl_gen_write_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.js"],"names":[],"mappings":"AAkJA;;;;;;;;;;;;;;GAcG;AACH,wEANW,MAAM,eACN,MAAM,iCAEN,MAAM,GACJ,IAAI,CAyBhB"}
@@ -1,5 +1,19 @@
1
1
  import { assert } from "../../../../../core/assert.js";
2
- import { f32, mat4x4f, u32, vec2f, vec2u, vec3f, vec3u, vec4f, vec4u } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import {
3
+ f32,
4
+ i32,
5
+ mat4x4f,
6
+ u32,
7
+ vec2f,
8
+ vec2i,
9
+ vec2u,
10
+ vec3f,
11
+ vec3i,
12
+ vec3u,
13
+ vec4f,
14
+ vec4i,
15
+ vec4u
16
+ } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
3
17
 
4
18
  /**
5
19
  *
@@ -21,8 +35,24 @@ function table_wgsl_gen_write_code_primitive(
21
35
  builder.add(`${buffer_name}[base_offset + ${offset}] = ${value_expr};`);
22
36
  return;
23
37
  case f32:
38
+ case i32:
24
39
  builder.add(`${buffer_name}[base_offset + ${offset}] = bitcast<u32>(${value_expr});`);
25
40
  return;
41
+ case vec2i:
42
+ for (let i = 0; i < 2; i++) {
43
+ table_wgsl_gen_write_code_primitive(builder, offset + i, buffer_name, i32, `${value_expr}[${i}]`);
44
+ }
45
+ return;
46
+ case vec3i:
47
+ for (let i = 0; i < 3; i++) {
48
+ table_wgsl_gen_write_code_primitive(builder, offset + i, buffer_name, i32, `${value_expr}[${i}]`);
49
+ }
50
+ return;
51
+ case vec4i:
52
+ for (let i = 0; i < 4; i++) {
53
+ table_wgsl_gen_write_code_primitive(builder, offset + i, buffer_name, i32, `${value_expr}[${i}]`);
54
+ }
55
+ return;
26
56
  case vec2f:
27
57
  for (let i = 0; i < 2; i++) {
28
58
  table_wgsl_gen_write_code_primitive(builder, offset + i, buffer_name, f32, `${value_expr}[${i}]`);