@woosh/meep-engine 3.41.0 → 3.43.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 (384) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/selection/editor_pick.d.ts.map +1 -1
  4. package/editor/selection/editor_pick.js +2 -1
  5. package/editor/tools/TransformToolV2.d.ts.map +1 -1
  6. package/editor/tools/TransformToolV2.js +7 -1
  7. package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
  8. package/editor/tools/engine/ToolEngine.js +10 -0
  9. package/editor/tools/v2/TransformControls.d.ts.map +1 -1
  10. package/editor/tools/v2/TransformControls.js +7 -20
  11. package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
  12. package/editor/tools/v2/handle/gizmo_drag_plane.js +4 -0
  13. package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
  14. package/editor/view/ecs/EntityEditor.js +3 -1
  15. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  16. package/editor/view/node-graph/NodeGraphView.js +28 -12
  17. package/package.json +91 -96
  18. package/samples/engine/first-scene/index.html +4 -1
  19. package/samples/engine/first-scene/main.js +14 -9
  20. package/src/core/binary/utf8/utf8_decode.js +3 -3
  21. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.d.ts.map +1 -1
  22. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +112 -113
  23. package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js +2 -2
  24. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +14 -14
  25. package/src/core/collection/RingBuffer.d.ts.map +1 -1
  26. package/src/core/collection/RingBuffer.js +4 -0
  27. package/src/core/collection/array/array_contains_duplicates.d.ts.map +1 -1
  28. package/src/core/collection/array/array_contains_duplicates.js +2 -1
  29. package/src/core/collection/array/array_copy.d.ts.map +1 -1
  30. package/src/core/collection/array/array_copy.js +23 -0
  31. package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts +2 -2
  32. package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts.map +1 -1
  33. package/src/core/collection/array/typed/sparse_typed_array_hash.js +9 -8
  34. package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -2
  35. package/src/core/collection/array/typed/uint16_array_hash.js +4 -4
  36. package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -2
  37. package/src/core/collection/array/typed/uint8_array_hash.js +4 -4
  38. package/src/core/collection/array/weightedRandomFromArray.d.ts +1 -0
  39. package/src/core/collection/array/weightedRandomFromArray.d.ts.map +1 -1
  40. package/src/core/collection/array/weightedRandomFromArray.js +9 -1
  41. package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
  42. package/src/core/collection/heap/BinaryHeap.js +4 -0
  43. package/src/core/collection/list/List.d.ts.map +1 -1
  44. package/src/core/collection/list/List.js +4 -2
  45. package/src/core/collection/set/ArraySet.js +1 -1
  46. package/src/core/collection/set/HashSet.d.ts +1 -1
  47. package/src/core/collection/set/HashSet.d.ts.map +1 -1
  48. package/src/core/collection/set/HashSet.js +4 -2
  49. package/src/core/debug/matchers/IsEqual.js +1 -1
  50. package/src/core/debug/matchers/IsIterableContaining.d.ts.map +1 -1
  51. package/src/core/debug/matchers/IsIterableContaining.js +61 -74
  52. package/src/core/events/signal/SignalBinding.js +101 -101
  53. package/src/core/function/extractFunctionBody.js +13 -13
  54. package/src/core/function/objectsEqual.d.ts.map +1 -1
  55. package/src/core/function/objectsEqual.js +15 -14
  56. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.d.ts.map +1 -1
  57. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +207 -172
  58. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -1
  59. package/src/core/geom/3d/gjk/gjk_epa_penetration.js +5 -4
  60. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
  61. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +8 -2
  62. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts +20 -0
  63. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
  64. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +182 -0
  65. package/src/core/math/noise/curl_noise_3dt.d.ts.map +1 -1
  66. package/src/core/math/noise/curl_noise_3dt.js +20 -10
  67. package/src/core/math/noise/sdnoise.d.ts +16 -5
  68. package/src/core/math/noise/sdnoise.d.ts.map +1 -1
  69. package/src/core/math/noise/sdnoise.js +43 -9
  70. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -1
  71. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
  72. package/src/core/math/spline/spline3_hermite_nearest_point.js +44 -3
  73. package/src/engine/Engine.d.ts.map +1 -1
  74. package/src/engine/Engine.js +6 -2
  75. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +9 -0
  76. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  77. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +26 -0
  78. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +2 -0
  80. package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -1
  81. package/src/engine/control/first-person/abilities/AbilitySet.js +9 -0
  82. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  83. package/src/engine/control/first-person/abilities/LedgeGrab.js +6 -0
  84. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
  85. package/src/engine/control/first-person/abilities/Slide.js +1 -0
  86. package/src/engine/control/first-person/abilities/WallRun.d.ts +4 -1
  87. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
  88. package/src/engine/control/first-person/abilities/WallRun.js +13 -1
  89. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +1 -1
  90. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -1
  91. package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +6 -5
  92. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +3 -3
  93. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -1
  94. package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +9 -8
  95. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  96. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +13 -4
  97. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  98. package/src/engine/ecs/EntityManager.js +18 -15
  99. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.d.ts.map +1 -1
  100. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +2 -1
  101. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.d.ts.map +1 -1
  102. package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.js +1 -0
  103. package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
  104. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +3 -0
  105. package/src/engine/ecs/parent/EntityNode.js +3 -3
  106. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  107. package/src/engine/ecs/speaker/VoiceSystem.js +4 -0
  108. package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +5 -5
  109. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
  110. package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +3 -2
  111. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +1 -1
  112. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.d.ts.map +1 -1
  113. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +8 -1
  114. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  115. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +8 -0
  116. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  117. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +5 -2
  118. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
  119. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +3 -0
  120. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
  121. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -0
  122. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
  123. package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
  124. package/src/engine/ecs/terrain/tiles/TerrainTile.js +13 -1
  125. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  126. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +1 -0
  127. package/src/engine/graphics/ecs/light/LightSerializationAdapter.d.ts.map +1 -1
  128. package/src/engine/graphics/ecs/light/LightSerializationAdapter.js +13 -1
  129. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts +5 -0
  130. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts.map +1 -0
  131. package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.js +27 -0
  132. package/src/engine/graphics/ecs/water/Water.d.ts +11 -0
  133. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  134. package/src/engine/graphics/ecs/water/Water.js +17 -0
  135. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
  136. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +3 -1
  137. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts +9 -0
  138. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts.map +1 -0
  139. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.js +24 -0
  140. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +30 -9
  141. package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
  142. package/src/engine/graphics/ecs/water/WaterWaves.js +41 -9
  143. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
  144. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +30 -26
  145. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts +6 -0
  146. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts.map +1 -0
  147. package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.js +22 -0
  148. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.d.ts.map +1 -1
  149. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +3 -5
  150. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +20 -0
  151. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
  152. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +36 -0
  153. package/src/engine/graphics3/WaterSystem.d.ts +12 -3
  154. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  155. package/src/engine/graphics3/WaterSystem.js +78 -46
  156. package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
  157. package/src/engine/input/devices/PointerDevice.js +29 -4
  158. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts +1 -0
  159. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts.map +1 -1
  160. package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +14 -3
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -1
  163. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +12 -3
  164. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -1
  165. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +8 -2
  166. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts +19 -0
  167. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts.map +1 -1
  168. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +41 -2
  169. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts.map +1 -1
  170. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +9 -3
  171. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts.map +1 -1
  172. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +26 -10
  173. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +3 -6
  174. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
  175. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +22 -9
  176. package/src/engine/ui/DraggableAspect.d.ts +5 -1
  177. package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
  178. package/src/engine/ui/DraggableAspect.js +61 -4
  179. package/src/format/image/avif/heif/ItemProperty.d.ts +1 -1
  180. package/src/format/image/avif/heif/ItemProperty.js +1 -1
  181. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  182. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +17 -6
  183. package/src/shade/device/mock/SoftwareGPUDevice.d.ts +2 -4
  184. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  185. package/src/shade/device/mock/SoftwareGPUDevice.js +20 -13
  186. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
  187. package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -1
  188. package/src/shade/playground/vgeo_runtime/README.md +5 -4
  189. package/src/shade/playground/water_refraction/README.md +10 -11
  190. package/src/shade/playground/water_refraction/main.js +9 -8
  191. package/src/shade/playground/water_refraction/world.js +1 -1
  192. package/src/shade/playground/water_surface/README.md +43 -0
  193. package/src/shade/playground/water_surface/index.html +30 -0
  194. package/src/shade/playground/water_surface/main.d.ts +2 -0
  195. package/src/shade/playground/water_surface/main.d.ts.map +1 -0
  196. package/src/shade/playground/water_surface/main.js +154 -0
  197. package/src/shade/playground/water_surface/world.d.ts +44 -0
  198. package/src/shade/playground/water_surface/world.d.ts.map +1 -0
  199. package/src/shade/playground/water_surface/world.js +160 -0
  200. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  201. package/src/shade/renderer/Renderer.js +6 -5
  202. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  203. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +5 -0
  204. package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
  205. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  206. package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
  207. package/src/shade/renderer/binding/BufferBinding.js +2 -2
  208. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  209. package/src/shade/renderer/buffer/table/GPUTypedTable.js +5 -3
  210. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +10 -3
  211. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
  212. package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +17 -9
  213. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +3 -0
  214. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +1 -1
  215. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +16 -0
  216. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +2 -0
  217. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
  218. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +11 -0
  219. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +1 -1
  220. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
  221. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +9 -3
  222. package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.d.ts.map +1 -1
  223. package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.js +2 -2
  224. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  225. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +85 -0
  226. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  227. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +12 -6
  228. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  229. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +7 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  231. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +3 -1
  232. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
  233. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
  234. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  235. package/src/shade/renderer/particles/DESIGN.md +13 -9
  236. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
  237. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
  238. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  239. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  240. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  241. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  242. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  243. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  244. package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
  245. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +2 -1
  246. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts +13 -0
  247. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts.map +1 -0
  248. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.js +42 -0
  249. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts +15 -0
  250. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts.map +1 -0
  251. package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.js +39 -0
  252. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  253. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +2 -0
  254. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
  255. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  256. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
  257. package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
  258. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
  259. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
  260. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
  261. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
  262. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
  263. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
  264. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
  265. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
  266. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
  267. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
  268. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
  269. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  270. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
  271. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
  272. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
  273. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
  274. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  275. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
  276. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +15 -0
  277. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  278. package/src/shade/renderer/water/GPUWaterRenderer.js +110 -30
  279. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +16 -8
  280. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  281. package/src/shade/renderer/water/medium/GPUWaterBodies.js +31 -26
  282. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +0 -1
  283. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -1
  284. package/src/shade/renderer/water/medium/shader_water_meshlets.js +1 -39
  285. package/src/shade/renderer/water/shader_water.d.ts +0 -1
  286. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  287. package/src/shade/renderer/water/shader_water.js +201 -72
  288. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +70 -0
  289. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -0
  290. package/src/shade/renderer/water/surface/GPUWaterSurface.js +199 -0
  291. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +5 -2
  292. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
  293. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +32 -12
  294. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +23 -0
  295. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -0
  296. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +227 -0
  297. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +65 -11
  298. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  299. package/src/shade/renderer/water/surface/graph_water_tessellation.js +163 -28
  300. package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts +51 -0
  301. package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts.map +1 -0
  302. package/src/shade/renderer/water/surface/lod/WATER_LOD.js +95 -0
  303. package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts +10 -0
  304. package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts.map +1 -0
  305. package/src/shade/renderer/water/surface/lod/chunk_water_lod.js +127 -0
  306. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts +17 -0
  307. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts.map +1 -0
  308. package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.js +246 -0
  309. package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts +118 -0
  310. package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts.map +1 -0
  311. package/src/shade/renderer/water/surface/lod/shader_water_lod.js +727 -0
  312. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts +60 -0
  313. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -0
  314. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +274 -0
  315. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts +17 -0
  316. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -0
  317. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +57 -0
  318. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +43 -0
  319. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -0
  320. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +268 -0
  321. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +20 -0
  322. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -0
  323. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +239 -0
  324. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +153 -0
  325. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -0
  326. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +874 -0
  327. package/src/shade/renderer/water/surface/shader_water_cull.d.ts +42 -0
  328. package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -0
  329. package/src/shade/renderer/water/surface/shader_water_cull.js +269 -0
  330. package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts +15 -0
  331. package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts.map +1 -0
  332. package/src/shade/renderer/water/surface/shader_water_waves_combine.js +73 -0
  333. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +11 -0
  334. package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -0
  335. package/src/shade/renderer/water/surface/shader_water_waves_derive.js +78 -0
  336. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts +35 -0
  337. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts.map +1 -0
  338. package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.js +103 -0
  339. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts +22 -0
  340. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts.map +1 -0
  341. package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.js +57 -0
  342. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts +22 -0
  343. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts.map +1 -0
  344. package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.js +25 -0
  345. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts +14 -0
  346. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts.map +1 -0
  347. package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.js +48 -0
  348. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts +23 -0
  349. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts.map +1 -0
  350. package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.js +169 -0
  351. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts +26 -0
  352. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts.map +1 -0
  353. package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.js +161 -0
  354. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  355. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +29 -9
  356. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  357. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +14 -3
  358. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts +0 -28
  359. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts.map +0 -1
  360. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +0 -86
  361. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts +0 -29
  362. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts.map +0 -1
  363. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +0 -44
  364. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +0 -4
  365. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +0 -1
  366. package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +0 -32
  367. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +0 -25
  368. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +0 -1
  369. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +0 -128
  370. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +0 -9
  371. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +0 -1
  372. package/src/shade/renderer/water/surface/chunk_water_tessellation.js +0 -144
  373. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +0 -13
  374. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +0 -1
  375. package/src/shade/renderer/water/surface/chunk_water_wave.js +0 -40
  376. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +0 -4
  377. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +0 -1
  378. package/src/shade/renderer/water/surface/shader_water_tiles.js +0 -123
  379. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +0 -6
  380. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +0 -1
  381. package/src/shade/renderer/water/surface/shader_water_wave_batch.js +0 -85
  382. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +0 -6
  383. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +0 -1
  384. package/src/shade/renderer/water/surface/shader_water_wave_domain.js +0 -83
@@ -25,11 +25,12 @@ import { ParticipatingMediaVolume } from "../../renderer/volumetrics/Participati
25
25
  import { water_medium_preset } from "../../renderer/medium/water/water_presets.js";
26
26
  import { water_finalize_shader_brick4, water_finalize_shader_ibl, water_shader } from "../../renderer/water/shader_water.js";
27
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";
28
+ import { shader_water_meshlets_expand } from "../../renderer/water/medium/shader_water_meshlets.js";
29
+ import * as spectrum_shaders from "../../renderer/water/surface/spectrum/shader_water_spectrum.js";
30
+ import * as particle_shaders from "../../renderer/water/surface/particles/shader_water_particles.js";
31
+ import * as cull_shaders from "../../renderer/water/surface/shader_water_cull.js";
32
+ import * as lod_shaders from "../../renderer/water/surface/lod/shader_water_lod.js";
33
+ import { shader_water_waves_combine } from "../../renderer/water/surface/shader_water_waves_combine.js";
33
34
  import { install_profile_hotkey } from "../profile_hotkey.js";
34
35
  import { build_world } from "./world.js";
35
36
 
@@ -164,9 +165,9 @@ async function main() {
164
165
  if(!ready)return;
165
166
  const device=graphics.renderer.graphics.device,errors=[];
166
167
  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)]){
168
+ ...[shader_water_meshlets_expand,shader_water_waves_combine,...Object.values(spectrum_shaders),
169
+ ...Object.values(particle_shaders),...Object.values(cull_shaders),...Object.values(lod_shaders),
170
+ ...Object.values(water_shaders)].map(s=>s?.descriptor)]){
170
171
  if(typeof shader?.source!=="string")continue;
171
172
  const module=device.createShaderModule({code:shader.source});const info=await module.getCompilationInfo();
172
173
  errors.push(...info.messages.filter(m=>m.type==="error").map(m=>`${m.lineNum}: ${m.message}`));
@@ -93,7 +93,7 @@ export async function build_world(dataset) {
93
93
  water_normals[i]=0;water_normals[i+1]=1;water_normals[i+2]=0;
94
94
  }
95
95
  const water_geometry=meshlets(water_plane),water_transform=pose(16,0,16);
96
- // the primitive wave simulation's forcing; the overlapping second body below has none and stays calm
96
+ // the wind that raises its waves; the overlapping second body below has none and stays calm
97
97
  const waves=new WaterWaves();
98
98
  const water_entity=build(new Entity().add(water).add(waves).add(water_geometry).add(water_transform));
99
99
  const add_mesh=(geo,m,x,y,z,rotation)=>{
@@ -0,0 +1,43 @@
1
+ # Water / surface
2
+
3
+ One scene, four bodies of water, from a cup to an ocean: the surface simulation of
4
+ `WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md` at every scale it has to work at.
5
+
6
+ | Stop | Body | Mesh | Wind | What to look for |
7
+ |---|---|---|---|---|
8
+ | Cup | 4 cm of tea on a table | a 32-segment disk | 2 m/s | centimetre ripples at most; a click rings the cup and the wall sends it back |
9
+ | Puddle | 2 m across, 1 cm deep | a wobbly disk | 4 m/s | rain (the checkbox) is the point here: rings of a few millimetres that die within a second |
10
+ | Lake | 120 × 60 m in a basin | its outline only | 6 m/s | short wind waves over the checkered bed; splashes reflect off the shore at 0.3 |
11
+ | Ocean | 5 km disk round an island hole | an annulus | 10 m/s, 200 km of sea upwind | swell; the island's outline reflects particles |
12
+
13
+ Every body is an ordinary entity: `Water` + `WaterWaves` + `MeshletGeometry` + `Transform64`. The meshes
14
+ author outlines; the surface's detail comes from the waves. Nothing in the scene is specific to its scale: the
15
+ wind and the fetch set each body's spectrum (fetch-limited JONSWAP over the body's extent along the wind,
16
+ plus `upwindFetch`), and all four share the same 18 spectral bands and one wave-particle pool.
17
+
18
+ ## Controls
19
+
20
+ - **Scale** buttons move the camera and set its near and far planes for the stop.
21
+ - **Wind ×** scales every body's own wind speed; **Direction** turns all of them. A change of direction
22
+ turns the waves over four seconds.
23
+ - **Click** the water to splash it, with a radius suited to the stop and the **Kick** speed. **Rain** drops
24
+ splashes on the current stop's body at the chosen rate.
25
+ - **Measure GPU** records 2.5 s of frames and lists the surface passes in µs per frame. **Profile (T)**
26
+ saves a full `.sgpt` capture.
27
+
28
+ ## What it shows and what it does not
29
+
30
+ The floors under the water are checkered so refraction shows the slopes without a sky. The page asks for the
31
+ default octahedral sky (`/test_assets/environments/octahedral/rustig_koppie_puresky_2k.hdr`); without it,
32
+ reflections show the procedural sky only, and the ocean, seen from above its deep water, reads dark and flat
33
+ except where it refracts the island's slope.
34
+
35
+ The ocean stop puts the camera 9 m above the sea; at the wind slider's top (20 m/s) the camera is among the waves.
36
+ The surface is cut from a distance-LOD lattice (`WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md`), so the waves
37
+ near the camera keep their cells however tall they are.
38
+
39
+ Measured on an RTX 4090, 1058 × 746 (headless Chrome, 2026-10-06), the ocean at 20 m/s from 9 m, with a fixed load
40
+ holding the GPU's clocks: culling 17 µs, band spectrum 30 µs (the bands the view can draw), bounds 7 µs, lattice passes
41
+ 232 µs and scans 61 µs for 2,820 patches, 176,000 interior and 146,000 boundary cells; the two surface passes 1.06 and
42
+ 1.50 ms, of which ~0.25 ms each shades the waves too short for the cells per pixel. Bodies out of view cost one culling thread each: 4,000 added under 2 µs. The GPU lowers its clocks on a light
43
+ frame, so time a pass against another setting in the same capture, or with a fixed load beside it.
@@ -0,0 +1,30 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Water · surface at every scale</title>
4
+ <style>
5
+ :root{color-scheme:dark;font:14px/1.45 system-ui,sans-serif;color:#d6e4ea;background:#10161b}*{box-sizing:border-box}
6
+ body{margin:0;display:grid;grid-template-columns:minmax(0,1fr) 320px;grid-template-rows:minmax(0,1fr);height:100vh;overflow:hidden}
7
+ #viewport{min-width:0;min-height:0;overflow:hidden;position:relative;outline:none}#viewport canvas{width:100%;height:100%}
8
+ aside{padding:20px;overflow:auto;border-left:1px solid #2d3a42;background:#151e25}h1{font-size:20px;margin:0 0 6px}h2{font-size:13px;color:#8cb9bf;text-transform:uppercase;letter-spacing:.07em;margin:22px 0 9px}
9
+ p{margin:8px 0;color:#9faeb9;font-size:12px}label{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:8px 0}
10
+ input[type=range]{width:130px}input,select,button{font:inherit;background:#202d36;border:1px solid #3c505e;border-radius:5px;color:#e2edf0;padding:5px}button{cursor:pointer}button:hover{background:#304753}
11
+ .row{display:flex;gap:6px;flex-wrap:wrap}pre{white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.5 monospace;color:#8bd3d5;background:#0c151b;padding:10px;border-radius:5px}
12
+ #status{border-left:3px solid #70b8b5;padding:10px;font-size:12px;background:#1d2c32}#badge{position:absolute;top:16px;left:16px;pointer-events:none;background:#13242cd9;padding:8px 12px;border-radius:5px;color:#c7eff0;font-size:12px}
13
+ </style></head>
14
+ <body tabindex="0"><div id="viewport" tabindex="0"><div id="badge">Drag to orbit · wheel to zoom · click the water to splash</div></div>
15
+ <aside><h1>Water / surface</h1><p>One spectrum and one particle pool for a cup, a puddle, a lake and an ocean.</p><div id="status">Starting renderer…</div>
16
+ <h2>Scale</h2>
17
+ <div class="row"><button class="stop" data-stop="cup">Cup</button><button class="stop" data-stop="puddle">Puddle</button><button class="stop" data-stop="lake">Lake</button><button class="stop" data-stop="ocean">Ocean</button><button class="stop" data-stop="aerial">Ocean, aerial</button></div>
18
+ <h2>Wind</h2>
19
+ <label>Wind × each body's own<input id="wind" type="range" min="0" max="2" step=".05" value="1"></label>
20
+ <label>Direction °<input id="direction" type="range" min="0" max="360" step="1" value="30"></label>
21
+ <pre id="winds"></pre>
22
+ <h2>Splashes</h2>
23
+ <label>Kick m/s<input id="kick" type="range" min="0.1" max="4" step=".1" value="1.5"></label>
24
+ <label>Rain on this body<input id="rain" type="checkbox"></label>
25
+ <label>Drops per second<input id="rate" type="range" min="1" max="200" step="1" value="40"></label>
26
+ <div class="row"><button id="pause">Pause</button><button id="measure">Measure GPU</button><button id="profile">Profile (T)</button></div>
27
+ <pre id="report">Measure records 2.5 s of frames and lists the surface passes, µs per frame.</pre>
28
+ </aside>
29
+ <script type="module" src="./main.js"></script>
30
+ </body></html>
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/water_surface/main.js"],"names":[],"mappings":""}
@@ -0,0 +1,154 @@
1
+ import Quaternion from "../../../core/geom/Quaternion.js";
2
+ import Vector3 from "../../../core/geom/Vector3.js";
3
+ import { m4_invert } from "../../../core/geom/3d/mat4/m4_invert.js";
4
+ import { EntityComponentDataset } from "../../../engine/ecs/EntityComponentDataset.js";
5
+ import { EntityManager } from "../../../engine/ecs/EntityManager.js";
6
+ import { Entity } from "../../../engine/ecs/Entity.js";
7
+ import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
8
+ import { Light } from "../../../engine/graphics/ecs/light/Light.js";
9
+ import { GraphicsEngine } from "../../../engine/graphics3/GraphicsEngine.js";
10
+ import { LightSystem } from "../../../engine/graphics3/LightSystem.js";
11
+ import { ShadedGeometrySystem } from "../../../engine/graphics3/ShadedGeometrySystem.js";
12
+ import { WaterSystem } from "../../../engine/graphics3/WaterSystem.js";
13
+ import { GPUProfileLevel } from "../../device/timing/profile/GPUProfileLevel.js";
14
+ import { GPUProfileSession } from "../../device/timing/profile/GPUProfileSession.js";
15
+ import { sgpt_read_capture } from "../../device/timing/profile/sgpt_read_capture.js";
16
+ import { OrbitalCameraController } from "../../renderer/camera/OrbitalCameraController.js";
17
+ import { create_frame_loop } from "../../renderer/create_frame_loop.js";
18
+ import { Scene } from "../../renderer/scene/Scene.js";
19
+ import { load_default_environment } from "../load_default_environment.js";
20
+ import { install_profile_hotkey } from "../profile_hotkey.js";
21
+ import { build_world } from "./world.js";
22
+
23
+ const element = id => document.getElementById(id);
24
+ const number = id => Number(element(id).value);
25
+
26
+ /** Where each stop looks from, its near and far planes, and the splash and raindrop radii there. */
27
+ const STOPS = {
28
+ cup: { body: 'cup', eye: [0.16, 0.98, 0.16], target: [0, 0.83, 0], near: 0.003, far: 400, splash: 0.005, drop: 0.002 },
29
+ puddle: { body: 'puddle', eye: [5.0, 0.9, 2.3], target: [4, 0, 1], near: 0.02, far: 2000, splash: 0.03, drop: 0.004 },
30
+ lake: { body: 'lake', eye: [22, 4, 188], target: [0, -1, 166], near: 0.1, far: 6000, splash: 0.3, drop: 0.01 },
31
+ ocean: { body: 'ocean', eye: [0, 9, 5000 + 150], target: [25, 0, 5000 + 230], near: 0.2, far: 12000, splash: 3, drop: 0.02 },
32
+ aerial: { body: 'ocean', eye: [700, 320, 4300], target: [0, 0, 5000], near: 0.5, far: 12000, splash: 3, drop: 0.02 },
33
+ };
34
+
35
+ async function main() {
36
+ const viewport = element("viewport"), graphics = new GraphicsEngine(), scene = new Scene();
37
+ viewport.appendChild(graphics.viewport.el);
38
+ const dataset = new EntityComponentDataset(), entities = new EntityManager();
39
+ const water_system = new WaterSystem(graphics, scene);
40
+ entities.addSystem(new ShadedGeometrySystem(graphics, scene));
41
+ entities.addSystem(new LightSystem(graphics, scene));
42
+ entities.addSystem(water_system);
43
+ entities.attachDataset(dataset);
44
+ await new Promise((resolve, reject) => entities.startup(resolve, reject));
45
+ const world = await build_world(dataset);
46
+ load_default_environment(scene);
47
+
48
+ const sun = new Light(); sun.intensity.set(2.4);
49
+ const sun_pose = new Transform64(), rotation = new Quaternion();
50
+ // low and ahead of the views, so its glitter path shows the slopes
51
+ rotation.fromUnitVectors(Vector3.forward, new Vector3(-0.15, -0.3, -0.94).normalize());
52
+ sun_pose.setRotation(rotation.x, rotation.y, rotation.z, rotation.w); sun_pose.updateMatrix();
53
+ new Entity().add(sun).add(sun_pose).build(dataset);
54
+
55
+ const camera = graphics.camera.camera, controller = new OrbitalCameraController(camera, viewport);
56
+ camera.fov = Math.PI / 3;
57
+ let stop = STOPS.cup;
58
+ function go(name) {
59
+ stop = STOPS[name];
60
+ camera.near = stop.near; camera.far = stop.far;
61
+ controller.look(new Vector3(...stop.eye), new Vector3(...stop.target));
62
+ for (const button of document.querySelectorAll("button.stop")) { button.style.borderColor = button.dataset.stop === name ? "#8dd3db" : ""; }
63
+ }
64
+ function configure() {
65
+ const lines = [];
66
+ for (const [name, body] of Object.entries(world.bodies)) {
67
+ body.waves.windSpeed.set(body.base_wind * number("wind"));
68
+ body.waves.windDirection.set(number("direction") * Math.PI / 180);
69
+ lines.push(`${name.padEnd(7)} ${(body.base_wind * number("wind")).toFixed(1)} m/s${body.waves.upwindFetch.getValue() > 0 ? `, ${body.waves.upwindFetch.getValue() / 1000} km of sea upwind` : ''}`);
70
+ }
71
+ element("winds").textContent = lines.join("\n");
72
+ }
73
+ const report = message => { element("status").textContent = message; };
74
+ for (const id of ["wind", "direction"]) { element(id).addEventListener("input", configure); }
75
+ for (const button of document.querySelectorAll("button.stop")) { button.onclick = () => go(button.dataset.stop); }
76
+ configure(); go("cup");
77
+
78
+ // a click splashes where its ray meets the stop's body at rest
79
+ const inverse = new Float64Array(16);
80
+ function splash_at(u, v, radius) {
81
+ const body = world.bodies[stop.body];
82
+ if (!m4_invert(inverse, camera.view_projection_matrix)) { return; }
83
+ const unproject = z => {
84
+ const x = 2 * u - 1, y = 1 - 2 * v;
85
+ const w = inverse[3] * x + inverse[7] * y + inverse[11] * z + inverse[15];
86
+ return [0, 1, 2].map(i => (inverse[i] * x + inverse[4 + i] * y + inverse[8 + i] * z + inverse[12 + i]) / w);
87
+ };
88
+ const near = unproject(1), far = unproject(0.5);
89
+ const direction = far.map((value, i) => value - near[i]);
90
+ if (Math.abs(direction[1]) < 1e-9) { return; }
91
+ const t = (body.level - near[1]) / direction[1];
92
+ if (!(t > 0)) { return; }
93
+ water_system.splash(body.entity, near.map((value, i) => value + direction[i] * t), radius, number("kick"));
94
+ }
95
+ viewport.addEventListener("click", event => {
96
+ const rect = viewport.getBoundingClientRect();
97
+ splash_at((event.clientX - rect.left) / rect.width, (event.clientY - rect.top) / rect.height, stop.splash);
98
+ });
99
+
100
+ let paused = false, ready = false, rain_debt = 0;
101
+ element("pause").onclick = () => { paused = !paused; element("pause").textContent = paused ? "Resume" : "Pause"; };
102
+ graphics.on.contextFailed.add(error => report(error.message));
103
+ graphics.on.contextLost.add(error => { ready = false; report(`GPU device lost · ${error.message}`); });
104
+ await graphics.start();
105
+ const renderer = graphics.renderer;
106
+ renderer.graphics.device.addEventListener("uncapturederror", event => { ready = false; report(event.error.message); console.error(event.error.message); });
107
+ const profile = install_profile_hotkey({ renderer, name: "water_surface", status: element("status"), target: viewport,
108
+ settings: () => [stop.body, `wind × ${number("wind")}`, element("rain").checked ? `rain ${number("rate")}/s` : 'no rain'] });
109
+ element("profile").onclick = () => profile.toggle().catch(error => report(error.message));
110
+
111
+ element("measure").onclick = async () => {
112
+ element("report").textContent = "recording…";
113
+ const session = new GPUProfileSession({ level: GPUProfileLevel.WORKLOAD, note: 'water_surface measure' });
114
+ renderer.profile_session = session; session.start();
115
+ await new Promise(resolve => setTimeout(resolve, 2500));
116
+ renderer.profile_session = null;
117
+ const bytes = await session.stop();
118
+ const capture = sgpt_read_capture(bytes instanceof ArrayBuffer ? bytes : bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
119
+ const sums = new Map();
120
+ let frames = 0, total = 0;
121
+ for (const frame of capture.frames) {
122
+ if (!frame.spans || frame.spans.length === 0) { continue; }
123
+ frames++;
124
+ for (const span of frame.spans) {
125
+ total += span.duration_ns;
126
+ if (!/^Water \/ (spectrum|waves|particles|classify)/.test(span.label)) { continue; }
127
+ sums.set(span.label, (sums.get(span.label) ?? 0) + span.duration_ns);
128
+ }
129
+ }
130
+ const rows = [...sums.entries()].sort((a, b) => b[1] - a[1]);
131
+ const surface = rows.reduce((sum, [, ns]) => sum + ns, 0);
132
+ element("report").textContent = [`${frames} frames · every pass ${(total / frames / 1000).toFixed(0)} µs · surface ${(surface / frames / 1000).toFixed(1)} µs`,
133
+ ...rows.map(([label, ns]) => `${(ns / frames / 1000).toFixed(1).padStart(7)} ${label.replace('Water / ', '')}`)].join("\n");
134
+ };
135
+
136
+ ready = true; report("Ready · click the water to splash");
137
+ Object.assign(globalThis, { graphics, scene, dataset, entities, world, water_system, camera, controller,
138
+ water_surface_playground: { go, splash_at, get ready() { return ready; } } });
139
+
140
+ create_frame_loop(raw_dt => {
141
+ if (!ready) { return; }
142
+ const dt = paused ? 0 : Math.min(raw_dt, 0.05);
143
+ if (element("rain").checked && dt > 0) {
144
+ rain_debt += number("rate") * dt;
145
+ for (; rain_debt >= 1; rain_debt--) { splash_at(Math.random(), 0.3 + 0.7 * Math.random(), stop.drop); }
146
+ }
147
+ graphics.viewport.size.set(Math.max(1, viewport.clientWidth), Math.max(1, viewport.clientHeight));
148
+ controller.update();
149
+ entities.update(dt);
150
+ graphics.render(dt);
151
+ }, 60);
152
+ }
153
+
154
+ main().catch(error => { console.error(error); element("status").textContent = error.message; });
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Four bodies of water, from a cup to an ocean, each a `Water` + `WaterWaves` entity whose mesh authors
3
+ * only its outline: the surface's detail comes from the waves, at any scale.
4
+ */
5
+ export function build_world(dataset: any): Promise<{
6
+ bodies: {
7
+ cup: {
8
+ entity: any;
9
+ water: Water;
10
+ waves: WaterWaves;
11
+ transform: Transform64;
12
+ level: any;
13
+ base_wind: any;
14
+ };
15
+ puddle: {
16
+ entity: any;
17
+ water: Water;
18
+ waves: WaterWaves;
19
+ transform: Transform64;
20
+ level: any;
21
+ base_wind: any;
22
+ };
23
+ lake: {
24
+ entity: any;
25
+ water: Water;
26
+ waves: WaterWaves;
27
+ transform: Transform64;
28
+ level: any;
29
+ base_wind: any;
30
+ };
31
+ ocean: {
32
+ entity: any;
33
+ water: Water;
34
+ waves: WaterWaves;
35
+ transform: Transform64;
36
+ level: any;
37
+ base_wind: any;
38
+ };
39
+ };
40
+ }>;
41
+ import Water from "../../../engine/graphics/ecs/water/Water.js";
42
+ import WaterWaves from "../../../engine/graphics/ecs/water/WaterWaves.js";
43
+ import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
44
+ //# sourceMappingURL=world.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/water_surface/world.js"],"names":[],"mappings":"AAsGA;;;GAGG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDC;kBA3JiB,6CAA6C;uBACxC,kDAAkD;4BAH7C,8CAA8C"}
@@ -0,0 +1,160 @@
1
+ import { Color } from "../../../core/color/Color.js";
2
+ import { Entity } from "../../../engine/ecs/Entity.js";
3
+ import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
4
+ import { ShadedGeometry } from "../../../engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
5
+ import Water from "../../../engine/graphics/ecs/water/Water.js";
6
+ import WaterWaves from "../../../engine/graphics/ecs/water/WaterWaves.js";
7
+ import { Attribute } from "../../renderer/geometry/Attribute.js";
8
+ import { Geometry } from "../../renderer/geometry/Geometry.js";
9
+ import { MeshoptClusterizer } from "../../renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.js";
10
+ import { meshlet_geometry_build_from_geometry } from "../../renderer/geometry/meshlet_geometry_build_from_geometry.js";
11
+ import { MeshletGeometry } from "../../renderer/geometry/MeshletGeometry.js";
12
+ import { make_box_geometry } from "../../renderer/geometry/primitives/make_box_geometry.js";
13
+ import { make_cylinder_geometry } from "../../renderer/geometry/primitives/make_cylinder_geometry.js";
14
+ import { StandardAttributes } from "../../renderer/geometry/StandardAttributes.js";
15
+ import { ShadeDrawSide } from "../../renderer/material/ShadeDrawSide.js";
16
+ import { StandardShadeMaterial } from "../../renderer/material/StandardShadeMaterial.js";
17
+ import { water_medium_preset } from "../../renderer/medium/water/water_presets.js";
18
+ import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
19
+ import { ColorSpace } from "../../renderer/texture/ColorSpace.js";
20
+ import { ShadeTexture } from "../../renderer/texture/ShadeTexture.js";
21
+ import { ShadeImage } from "../../renderer/texture/source/ShadeImage.js";
22
+
23
+ function pose(x, y, z) {
24
+ const transform = new Transform64();
25
+ transform.setTranslation(x, y, z);
26
+ transform.updateMatrix();
27
+ return transform;
28
+ }
29
+
30
+ let checker_texture = null;
31
+ /** Sharp light and dark squares, one per UV unit: what refraction bends shows the slopes without a sky. */
32
+ function checker() {
33
+ if (checker_texture !== null) { return checker_texture; }
34
+ const size = 512, data = Sampler2D.uint8(4, size, size);
35
+ for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {
36
+ const bright = ((x >> 8) + (y >> 8)) % 2 === 0;
37
+ data.data.set(bright ? [215, 220, 200, 255] : [42, 66, 84, 255], (y * size + x) * 4);
38
+ }
39
+ const image = ShadeImage.fromSampler2D(data); image.color_space = ColorSpace.SRGB;
40
+ return checker_texture = ShadeTexture.from(image);
41
+ }
42
+
43
+ function material(rgb, roughness = 0.8, textured = false) {
44
+ const m = new StandardShadeMaterial();
45
+ m.diffuse_color.copy(new Color(...rgb, 1));
46
+ m.metallic_factor = 0; m.roughness_factor = roughness; m.draw_side = ShadeDrawSide.Double;
47
+ if (textured) { m.texture_albedo = checker(); }
48
+ return m;
49
+ }
50
+
51
+ function meshlets(geometry) {
52
+ const result = new MeshletGeometry();
53
+ meshlet_geometry_build_from_geometry(geometry, result);
54
+ return result;
55
+ }
56
+
57
+ /**
58
+ * A polar mesh in local xz, wound to face +y: rings of `segments` vertices at radii `radius(theta, t)` for
59
+ * t from 0 to 1, at heights `height(theta, t)`. A disk has a centre vertex for t = 0; with `hole`, t = 0 is a
60
+ * ring, and the mesh an annulus. Texture coordinates are local xz over `texel` metres: two checker squares.
61
+ */
62
+ function polar_geometry({ segments, rings, radius, height = () => 0, hole = false, texel = 1 }) {
63
+ const positions = [], normals = [], uvs = [], index = [];
64
+ const centre = !hole;
65
+ if (centre) { positions.push(0, height(0, 0), 0); normals.push(0, 1, 0); uvs.push(0, 0); }
66
+ const first = centre ? 1 : 0;
67
+ const ring_count = centre ? rings : rings + 1;
68
+ for (let r = 0; r < ring_count; r++) {
69
+ const t = centre ? (r + 1) / rings : r / rings;
70
+ for (let s = 0; s < segments; s++) {
71
+ const theta = 2 * Math.PI * s / segments;
72
+ const rho = radius(theta, t);
73
+ positions.push(Math.cos(theta) * rho, height(theta, t), Math.sin(theta) * rho);
74
+ normals.push(0, 1, 0);
75
+ uvs.push(Math.cos(theta) * rho / texel, Math.sin(theta) * rho / texel);
76
+ }
77
+ }
78
+ const vertex = (r, s) => first + r * segments + (s % segments);
79
+ const triangle = (a, b, c) => {
80
+ const p = i => [positions[3 * i], positions[3 * i + 1], positions[3 * i + 2]];
81
+ const [pa, pb, pc] = [p(a), p(b), p(c)];
82
+ const ny = (pb[2] - pa[2]) * (pc[0] - pa[0]) - (pb[0] - pa[0]) * (pc[2] - pa[2]);
83
+ if (ny >= 0) { index.push(a, b, c); } else { index.push(a, c, b); }
84
+ };
85
+ if (centre) { for (let s = 0; s < segments; s++) { triangle(0, vertex(0, s), vertex(0, s + 1)); } }
86
+ for (let r = 0; r + 1 < ring_count; r++) {
87
+ for (let s = 0; s < segments; s++) {
88
+ triangle(vertex(r, s), vertex(r + 1, s), vertex(r + 1, s + 1));
89
+ triangle(vertex(r, s), vertex(r + 1, s + 1), vertex(r, s + 1));
90
+ }
91
+ }
92
+ const geometry = new Geometry();
93
+ geometry.index = Attribute.from(new Uint32Array(index), 1, 'index');
94
+ geometry.addAttribute(Attribute.from(new Float32Array(positions), 3, StandardAttributes.Position));
95
+ geometry.addAttribute(Attribute.from(new Float32Array(normals), 3, StandardAttributes.Normal));
96
+ geometry.addAttribute(Attribute.from(new Float32Array(uvs), 2, StandardAttributes.TextureCoordinates0));
97
+ return geometry;
98
+ }
99
+
100
+ /** A wobbly outline of mean radius one, the same for the water and the ground around it. */
101
+ const wobble = (seed, amount) => theta => 1 + amount * (0.6 * Math.sin(3 * theta + seed) + 0.4 * Math.sin(5 * theta + 2 * seed));
102
+
103
+ /**
104
+ * Four bodies of water, from a cup to an ocean, each a `Water` + `WaterWaves` entity whose mesh authors
105
+ * only its outline: the surface's detail comes from the waves, at any scale.
106
+ */
107
+ export async function build_world(dataset) {
108
+ await MeshoptClusterizer.ready;
109
+ const build = builder => { builder.build(dataset); return builder.id; };
110
+ const solid = (geometry, m, x, y, z) => {
111
+ const shaded = new ShadedGeometry(); shaded.geometry = meshlets(geometry); shaded.material = m;
112
+ return build(new Entity().add(pose(x, y, z)).add(shaded));
113
+ };
114
+ const water_body = ({ geometry, x, y, z, preset, wind, upwind = 0, reflection = 0.5, roughness = 0.02 }) => {
115
+ const water = new Water();
116
+ water.medium = water_medium_preset({ preset });
117
+ water.roughness.set(roughness);
118
+ const waves = new WaterWaves();
119
+ waves.windSpeed.set(wind); waves.upwindFetch.set(upwind); waves.shoreReflection.set(reflection);
120
+ const transform = pose(x, y, z);
121
+ const entity = build(new Entity().add(water).add(waves).add(meshlets(geometry)).add(transform));
122
+ return { entity, water, waves, transform, level: y, base_wind: wind };
123
+ };
124
+
125
+ // a floor for the cup's table and the puddle
126
+ solid(polar_geometry({ segments: 48, rings: 6, radius: (theta, t) => 40 * t, texel: 0.5 }), material([1, 1, 1], 0.8, true), 0, 0, 0);
127
+
128
+ // a cup of tea on a table: 4 cm across, 7 cm deep
129
+ solid(make_box_geometry(1.2, 0.75, 0.8), material([0.45, 0.28, 0.16], 0.5), 0, 0.375, 0);
130
+ solid(make_cylinder_geometry(0.045, 0.04, 0.095, 32, 1, true), material([0.92, 0.92, 0.9], 0.3), 0, 0.75 + 0.0475, 0);
131
+ solid(polar_geometry({ segments: 32, rings: 1, radius: (theta, t) => 0.04 * t, texel: 0.02 }), material([1, 1, 1], 0.3, true), 0, 0.751, 0);
132
+ const cup = water_body({ geometry: polar_geometry({ segments: 32, rings: 2, radius: (theta, t) => 0.0435 * t }),
133
+ x: 0, y: 0.83, z: 0, preset: 'swimming_pool', wind: 2, reflection: 0.9 });
134
+
135
+ // a puddle on the floor: a centimetre deep, two metres across
136
+ const puddle_outline = wobble(1.3, 0.25);
137
+ const puddle = water_body({ geometry: polar_geometry({ segments: 64, rings: 3, radius: (theta, t) => 1.0 * t * puddle_outline(theta) }),
138
+ x: 4, y: 0.01, z: 1, preset: 'swimming_pool', wind: 4, reflection: 0.2 });
139
+
140
+ // a mountain lake, 120 × 60 m, in a basin whose shore is its outline
141
+ const lake_outline = wobble(0.4, 0.15);
142
+ const lake_radius = (theta, t) => t * lake_outline(theta) * (60 - 30 * Math.sin(theta) ** 2);
143
+ const lake = water_body({ geometry: polar_geometry({ segments: 96, rings: 6, radius: lake_radius }),
144
+ x: 0, y: 0, z: 160, preset: 'tropical_lagoon', wind: 6, reflection: 0.3 });
145
+ solid(polar_geometry({ segments: 96, rings: 24, radius: (theta, t) => lake_radius(theta, 3 * t),
146
+ height: (theta, t) => { const f = 3 * t; return f < 1 ? -4 * (1 - f * f) : 18 * ((f - 1) / 2) ** 2; }, texel: 4 }),
147
+ material([0.75, 0.85, 0.65], 0.8, true), 0, 0, 160);
148
+
149
+ // an open ocean disk, 5 km across, around an island the mesh leaves a hole for; the sea runs on for 200 km upwind
150
+ const ocean_x = 0, ocean_z = 5000;
151
+ const island = wobble(2.1, 0.12);
152
+ const ocean = water_body({ geometry: polar_geometry({ segments: 128, rings: 24, hole: true,
153
+ radius: (theta, t) => { const rim = 130 * island(theta); return rim * (2500 / rim) ** t; } }),
154
+ x: ocean_x, y: 0, z: ocean_z, preset: 'clear_ocean', wind: 10, upwind: 200000, reflection: 0.6 });
155
+ solid(polar_geometry({ segments: 128, rings: 48, radius: (theta, t) => 2600 * t * t,
156
+ height: (theta, t) => { const r = 2600 * t * t / (220 * island(theta)); return r < 1 ? 60 - 100 * r ** 1.2 : -40; }, texel: 16 }),
157
+ material([0.95, 0.9, 0.75], 0.8, true), ocean_x, 0, ocean_z);
158
+
159
+ return { bodies: { cup, puddle, lake, ocean } };
160
+ }
@@ -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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"}
@@ -2514,11 +2514,12 @@ export class Renderer {
2514
2514
  resolution: view_ctx.resolution,
2515
2515
  });
2516
2516
 
2517
- // Build the view's volumetric fog LUTs (participating media -> per-froxel lighting ->
2518
- // ray-marched integration). Needs the light clusters and shadow atlas. Built every frame so
2519
- // the transparency (OIT) pass always has a valid LUT to sample — an empty scene integrates
2520
- // to a no-op (transmittance 1, in-scatter 0). The opaque composite below is still skipped
2521
- // when the scene has no fog.
2517
+ // The view's volumetrics: the fog every surface is seen through (participating media ->
2518
+ // per-froxel lighting -> ray-marched integration), and the froxel irradiance lit particles
2519
+ // are lit by. Both need the light clusters and shadow atlas. A scene with no volumes records
2520
+ // no fog and hands the transparency pass a constant LUT that reads as none (transmittance 1,
2521
+ // in-scatter 0); the irradiance is built only when something reads it. The opaque composite
2522
+ // below is skipped on the same fact.
2522
2523
  const has_volumetrics = view_ctx.scene.volumetrics.source.volumes.length > 0;
2523
2524
 
2524
2525
  const volumetrics = view_ctx.volumetrics.graph_update({
@@ -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;;;;;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"}
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,CA+NnB;IAmXD;;;;;;;OAOG;IACH,gBA+BC;;CACJ;qCA/xCY,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"}
@@ -711,6 +711,11 @@ export class GPUMeshSkinningContext {
711
711
  */
712
712
  update(cmd_ctx) {
713
713
  if (this.#bindings.length === 0) {
714
+ if (this.#bindings_dirty) {
715
+ this.#refresh_bindings_from_records();
716
+ this.#upload_prev_position_offsets();
717
+ this.#bindings_dirty = false;
718
+ }
714
719
  return false;
715
720
  }
716
721
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
3
+ */
1
4
  export class GPUSky {
2
5
  /**
3
6
  *
@@ -14,6 +17,14 @@ export class GPUSky {
14
17
  * @returns {GPUTextureContext}
15
18
  */
16
19
  get lut_multiple_scattering(): GPUTextureContext;
20
+ /**
21
+ * Whether the LUTs still hold nothing a reader could use: true until the first {@link update}.
22
+ * What reads {@link lut_transmittance} or {@link lut_multiple_scattering} has to see this false,
23
+ * as a texture nobody wrote reads as zero rather than failing.
24
+ *
25
+ * @returns {boolean}
26
+ */
27
+ get needs_update(): boolean;
17
28
  destroy(): void;
18
29
  debug(): void;
19
30
  /**
@@ -22,5 +33,6 @@ export class GPUSky {
22
33
  update(): void;
23
34
  #private;
24
35
  }
36
+ export type GraphicsContext = import("../GraphicsContext.js").GraphicsContext;
25
37
  import { GPUTextureContext } from "../texture/GPUTextureContext.js";
26
38
  //# sourceMappingURL=GPUSky.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GPUSky.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/atmosphere/GPUSky.js"],"names":[],"mappings":"AAUA;IAuCI;;;OAGG;IACH,uCAmBC;IAlDD;;;OAGG;IACH,2CAEC;IAOD;;;OAGG;IACH,iDAEC;IAiCD,gBAGC;IAED,cAYC;IAED;;OAEG;IACH,eAiDC;;CAEJ;kCA7IiC,iCAAiC"}
1
+ {"version":3,"file":"GPUSky.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/atmosphere/GPUSky.js"],"names":[],"mappings":"AAUA;;GAEG;AAEH;IAkDI;;;OAGG;IACH,sBAFW,eAAe,EAqBzB;IA7DD;;;OAGG;IACH,2CAEC;IAOD;;;OAGG;IACH,iDAEC;IAQD;;;;;;OAMG;IACH,4BAEC;IA2BD,gBAGC;IAED,cAYC;IAED;;OAEG;IACH,eAiDC;;CAEJ;8BAvJY,OAAO,uBAAuB,EAAE,eAAe;kCAL1B,iCAAiC"}