@woosh/meep-engine 3.64.1 → 3.65.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.
- package/CHANGELOG.md +85 -0
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts +5 -0
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +39 -5
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GroundCoverSystem.js +58 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +372 -110
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +65 -9
- package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
- package/src/engine/network/state/PredictionHistory.js +6 -1
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
- package/src/engine/network/time/RenderPlayout.d.ts +23 -3
- package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
- package/src/engine/network/time/RenderPlayout.js +40 -4
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
- package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
- package/src/shade/playground/grass_surfaces/index.html +75 -0
- package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
- package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/main.js +593 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
- package/src/shade/playground/probe_clipmap_box/README.md +5 -1
- package/src/shade/playground/probe_clipmap_box/index.html +12 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/main.js +15 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +47 -43
- package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
- package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
- package/src/shade/renderer/extension/ViewTextures.js +19 -5
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
- package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
- package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
- package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
- package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
|
@@ -0,0 +1,676 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { TextureViewDescriptor } from "../../../descriptor/texture/TextureViewDescriptor.js";
|
|
3
|
+
import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
|
|
4
|
+
import { TextureResourceDescriptor } from "../../../device/graph/TextureResourceDescriptor.js";
|
|
5
|
+
import { graph_read_buffer } from "../../buffer/graph_read_buffer.js";
|
|
6
|
+
import { DEFAULT_DEPTH_TEXTURE_VIEW } from "../../depth/DEFAULT_DEPTH_TEXTURE_VIEW.js";
|
|
7
|
+
import { GBufferTextures } from "../../extension/GBufferTextures.js";
|
|
8
|
+
import { ViewTextures } from "../../extension/ViewTextures.js";
|
|
9
|
+
import { INDIRECT_COMPUTE_COMMAND_DESCRIPTOR } from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
|
|
10
|
+
import { view_velocity_matrices } from "../../postprocess/velocity/view_velocity_matrices.js";
|
|
11
|
+
import {
|
|
12
|
+
graph_prefix_scan_csdldf,
|
|
13
|
+
prefix_scan_csdldf_output_descriptor
|
|
14
|
+
} from "../../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
|
|
15
|
+
import { shader_prefix_sum_to_command } from "../../rasterize/expand/mesh/shader_prefix_sum_to_command.js";
|
|
16
|
+
import { graph_create_buffer } from "../../shader/graph/graph_create_buffer.js";
|
|
17
|
+
import { GPUGrassPress } from "../press/GPUGrassPress.js";
|
|
18
|
+
import { GRASS_BLADE_CLOCK_STRUCT } from "./chunk_grass_blade_wind.js";
|
|
19
|
+
import { grass_blade_compliance, grass_blade_frequency } from "./grass_blade_mechanics.js";
|
|
20
|
+
import {
|
|
21
|
+
GRASS_BLADE_CAPACITY_LIMIT,
|
|
22
|
+
GRASS_BLADE_ID_FORMAT,
|
|
23
|
+
GRASS_BLADE_ID_NONE,
|
|
24
|
+
GRASS_BLADE_LIST_COUNT,
|
|
25
|
+
GRASS_BLADE_LIST_HEADER_WORDS,
|
|
26
|
+
GRASS_BLADE_RECORD_WORDS,
|
|
27
|
+
GRASS_CELL_WORDS,
|
|
28
|
+
GRASS_SPECIES_WORDS
|
|
29
|
+
} from "./GRASS_BLADE.js";
|
|
30
|
+
import { GRASS_BLADE_ID_PIPELINE, GRASS_BLADE_ID_RESOURCES } from "./grass_blade_id_draw.js";
|
|
31
|
+
import { GRASS_BLADE_RESOLVE_PIPELINE, GRASS_BLADE_RESOLVE_RESOURCES } from "./grass_blade_resolve.js";
|
|
32
|
+
import { shader_grass_blade_draw_args } from "./shader_grass_blade_draw_args.js";
|
|
33
|
+
import { shader_grass_blade_expand } from "./shader_grass_blade_expand.js";
|
|
34
|
+
import { GRASS_CELL_COUNT_WORKGROUP_SIZE, shader_grass_cell_count } from "./shader_grass_cell_count.js";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
|
|
38
|
+
* @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
|
|
39
|
+
* @typedef {import("../../extension/FrameContext.js").FrameContext} FrameContext
|
|
40
|
+
* @typedef {import("../../fluid/forcing/GPUFluidForcing.js").GPUFluidForcing} GPUFluidForcing
|
|
41
|
+
* @typedef {import("../../GraphicsContext.js").GraphicsContext} GraphicsContext
|
|
42
|
+
* @typedef {import("../../view/GPUViewContext.js").GPUViewContext} GPUViewContext
|
|
43
|
+
* @typedef {import("../surface/GPUGrassSurfaces.js").GPUGrassSurfaces} GPUGrassSurfaces
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Bytes at the front of a `u32` collection: its count, padded to the elements' alignment.
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
const COLLECTION_HEADER_BYTES = 16;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Blades the frame's list is first made with room for.
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
const INITIAL_BLADE_CAPACITY = 2 ** 17;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Species the species list is made with room for.
|
|
60
|
+
* @type {number}
|
|
61
|
+
*/
|
|
62
|
+
const INITIAL_SPECIES_CAPACITY = 16;
|
|
63
|
+
|
|
64
|
+
const MIP_0 = TextureViewDescriptor.from({ mipLevelCount: 1, baseMipLevel: 0 });
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Bytes of a `u32` collection with room for `count` elements.
|
|
68
|
+
*
|
|
69
|
+
* @param {number} count
|
|
70
|
+
* @returns {number}
|
|
71
|
+
*/
|
|
72
|
+
function collection_size(count) {
|
|
73
|
+
return COLLECTION_HEADER_BYTES + Math.max(1, Math.ceil(count / 4)) * 16;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A view's blades for the frame being recorded: the handles its draw reads.
|
|
78
|
+
*/
|
|
79
|
+
class BladeProduct {
|
|
80
|
+
/** @type {number} the closed blade list */
|
|
81
|
+
blades = -1;
|
|
82
|
+
|
|
83
|
+
/** @type {number} the draw's indirect arguments */
|
|
84
|
+
draw_args = -1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Grass blades on the device: the species list, and the passes that make a view's blades each frame and
|
|
89
|
+
* draw them (`GRASS_BLADE.js`).
|
|
90
|
+
*
|
|
91
|
+
* Blades stand on the surfels {@link GPUGrassSurfaces} keeps; nothing of a blade outlives its frame.
|
|
92
|
+
*
|
|
93
|
+
* Each frame: {@link update} once; then for every view that draws grass {@link graph_generate}, after the
|
|
94
|
+
* surfaces' own passes for the view, after whatever publishes the scene's wind for the frame (the blades
|
|
95
|
+
* are bent by it), and before anything reads the scene's depth for the frame's image; and
|
|
96
|
+
* {@link graph_draw} at the frame phase where the G-buffer is written into.
|
|
97
|
+
*
|
|
98
|
+
* The blades are pushed over by the scene's fluid obstacles through {@link press}, a field this owns and
|
|
99
|
+
* stamps as part of making a view's blades.
|
|
100
|
+
*/
|
|
101
|
+
export class GPUGrassBlades {
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Offer the pipelines the blades' passes run — see {@link PipelineEnquiry}.
|
|
105
|
+
*
|
|
106
|
+
* @param {PipelineEnquiry} enquiry
|
|
107
|
+
*/
|
|
108
|
+
static enquirePipelines(enquiry) {
|
|
109
|
+
enquiry.compute.push(shader_grass_cell_count.pipeline);
|
|
110
|
+
enquiry.compute.push(shader_grass_blade_expand.pipeline);
|
|
111
|
+
enquiry.compute.push(shader_grass_blade_draw_args.pipeline);
|
|
112
|
+
enquiry.compute.push(shader_prefix_sum_to_command.pipeline);
|
|
113
|
+
enquiry.render.push(GRASS_BLADE_ID_PIPELINE);
|
|
114
|
+
enquiry.render.push(GRASS_BLADE_RESOLVE_PIPELINE);
|
|
115
|
+
|
|
116
|
+
GPUGrassPress.enquirePipelines(enquiry);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Where obstacles have pressed the grass down, and its settings.
|
|
121
|
+
*
|
|
122
|
+
* @readonly
|
|
123
|
+
* @type {GPUGrassPress}
|
|
124
|
+
*/
|
|
125
|
+
press;
|
|
126
|
+
|
|
127
|
+
/** @type {GPUDevice} */
|
|
128
|
+
#device;
|
|
129
|
+
|
|
130
|
+
/** @type {GPUGrassSurfaces} */
|
|
131
|
+
#surfaces;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The species list, a record a species, by the species' index.
|
|
135
|
+
* @type {Float32Array}
|
|
136
|
+
*/
|
|
137
|
+
#species = new Float32Array(INITIAL_SPECIES_CAPACITY * GRASS_SPECIES_WORDS);
|
|
138
|
+
|
|
139
|
+
/** @type {GPUBuffer|null} the device's copy of {@link #species} */
|
|
140
|
+
#species_buffer = null;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Whether the device's copy is behind.
|
|
144
|
+
* @type {boolean}
|
|
145
|
+
*/
|
|
146
|
+
#species_dirty = true;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The scene's clock as the blades' pass reads it (`GRASS_BLADE_CLOCK_STRUCT`): this frame's, then the
|
|
150
|
+
* frame before's.
|
|
151
|
+
* @type {ArrayBuffer}
|
|
152
|
+
*/
|
|
153
|
+
#clock = new ArrayBuffer(GRASS_BLADE_CLOCK_STRUCT.size);
|
|
154
|
+
#clock_u32 = new Uint32Array(this.#clock);
|
|
155
|
+
#clock_f32 = new Float32Array(this.#clock);
|
|
156
|
+
|
|
157
|
+
/** @type {GPUBuffer|null} the device's copy of {@link #clock} */
|
|
158
|
+
#clock_buffer = null;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Seconds of the scene's clock past its whole seconds, kept in f64.
|
|
162
|
+
* @type {number}
|
|
163
|
+
*/
|
|
164
|
+
#clock_fraction = 0;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Blades a frame's list has room for.
|
|
168
|
+
* @type {number}
|
|
169
|
+
*/
|
|
170
|
+
#blade_capacity = INITIAL_BLADE_CAPACITY;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The most blades any view's list was asked to hold, as last read off the device.
|
|
174
|
+
* @type {number}
|
|
175
|
+
*/
|
|
176
|
+
#blades_asked = 0;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Each view's blades for the frame being recorded, from its generation to its draw.
|
|
180
|
+
* @type {Map<GPUViewContext, BladeProduct>}
|
|
181
|
+
*/
|
|
182
|
+
#products = new Map();
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {GraphicsContext} graphics
|
|
186
|
+
* @param {GPUGrassSurfaces} surfaces whose surfels the blades stand on
|
|
187
|
+
*/
|
|
188
|
+
constructor(graphics, surfaces) {
|
|
189
|
+
assert.defined(graphics, 'graphics');
|
|
190
|
+
assert.equal(graphics.isGraphicsContext, true, 'graphics.isGraphicsContext !== true');
|
|
191
|
+
assert.defined(surfaces, 'surfaces');
|
|
192
|
+
|
|
193
|
+
this.#device = graphics.device;
|
|
194
|
+
this.#surfaces = surfaces;
|
|
195
|
+
|
|
196
|
+
this.press = new GPUGrassPress(graphics);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @returns {number} blades a frame's list has room for
|
|
201
|
+
*/
|
|
202
|
+
get blade_capacity() {
|
|
203
|
+
return this.#blade_capacity;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @returns {number} the most blades a view's list was asked to hold, as last read off the device
|
|
208
|
+
*/
|
|
209
|
+
get blades_asked() {
|
|
210
|
+
return this.#blades_asked;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The species list on the device. Null before the first {@link update}, and replaced when it grows.
|
|
215
|
+
*
|
|
216
|
+
* @returns {GPUBuffer|null}
|
|
217
|
+
*/
|
|
218
|
+
get species_buffer() {
|
|
219
|
+
return this.#species_buffer;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The blades' clock on the device (`GRASS_BLADE_CLOCK_STRUCT`). Null before the first {@link update}.
|
|
224
|
+
*
|
|
225
|
+
* @returns {GPUBuffer|null}
|
|
226
|
+
*/
|
|
227
|
+
get clock_buffer() {
|
|
228
|
+
return this.#clock_buffer;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Set a species' record.
|
|
233
|
+
*
|
|
234
|
+
* @param {number} index the species' place in the list, as `mesh_ground_covers` rows name it
|
|
235
|
+
* @param {object} species
|
|
236
|
+
* @param {number} species.blade_length metres
|
|
237
|
+
* @param {number} species.blade_width metres
|
|
238
|
+
* @param {number} species.density blades a square metre
|
|
239
|
+
* @param {number} species.roughness
|
|
240
|
+
* @param {number[]} species.color_root linear rgb
|
|
241
|
+
* @param {number[]} species.color_tip linear rgb
|
|
242
|
+
* @param {number} species.length_variation how much of its length a blade can lack, 0 to 1
|
|
243
|
+
* @param {number} species.lean the most a blade leans from upright at its root, radians
|
|
244
|
+
* @param {number} species.curl the most a blade's tip turns further than its root leans, radians
|
|
245
|
+
* @param {number} species.tint how far a blade's colour strays from its species', as a share of it
|
|
246
|
+
* @param {number} species.roundness how far a blade's normal turns towards its edges
|
|
247
|
+
* @param {number} species.elastic_modulus of the blade's tissue in bending, Pa
|
|
248
|
+
* @param {number} species.blade_depth depth of the blade's section in bending, metres
|
|
249
|
+
* @param {number} species.turbulence how unsteady the wind a blade feels is, as a share of its speed
|
|
250
|
+
*/
|
|
251
|
+
set_species(index, species) {
|
|
252
|
+
assert.isNonNegativeInteger(index, 'index');
|
|
253
|
+
|
|
254
|
+
if ((index + 1) * GRASS_SPECIES_WORDS > this.#species.length) {
|
|
255
|
+
const grown = new Float32Array(Math.max(this.#species.length * 2, (index + 1) * GRASS_SPECIES_WORDS));
|
|
256
|
+
|
|
257
|
+
grown.set(this.#species);
|
|
258
|
+
|
|
259
|
+
this.#species = grown;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const words = this.#species;
|
|
263
|
+
const at = index * GRASS_SPECIES_WORDS;
|
|
264
|
+
|
|
265
|
+
words[at] = species.blade_length;
|
|
266
|
+
words[at + 1] = species.blade_width;
|
|
267
|
+
words[at + 2] = species.density;
|
|
268
|
+
words[at + 3] = species.roughness;
|
|
269
|
+
|
|
270
|
+
words[at + 4] = species.color_root[0];
|
|
271
|
+
words[at + 5] = species.color_root[1];
|
|
272
|
+
words[at + 6] = species.color_root[2];
|
|
273
|
+
words[at + 7] = species.length_variation;
|
|
274
|
+
|
|
275
|
+
words[at + 8] = species.color_tip[0];
|
|
276
|
+
words[at + 9] = species.color_tip[1];
|
|
277
|
+
words[at + 10] = species.color_tip[2];
|
|
278
|
+
words[at + 11] = species.lean;
|
|
279
|
+
|
|
280
|
+
words[at + 12] = species.curl;
|
|
281
|
+
words[at + 13] = species.tint;
|
|
282
|
+
words[at + 14] = species.roundness;
|
|
283
|
+
words[at + 15] = 0;
|
|
284
|
+
|
|
285
|
+
words[at + 16] = grass_blade_compliance(species.elastic_modulus, species.blade_depth);
|
|
286
|
+
words[at + 17] = grass_blade_frequency(species.elastic_modulus, species.blade_depth);
|
|
287
|
+
words[at + 18] = species.turbulence;
|
|
288
|
+
words[at + 19] = species.recovery_time;
|
|
289
|
+
|
|
290
|
+
this.#species_dirty = true;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Begin a frame: move the blades' clock and the press's on, bring the device's species list up to
|
|
295
|
+
* date, and make room for the blades the last frames' lists were asked to hold. Call once a frame,
|
|
296
|
+
* before any view's {@link graph_generate}.
|
|
297
|
+
*
|
|
298
|
+
* @param {number} time_delta_seconds how far the scene's clock has moved since the last call
|
|
299
|
+
*/
|
|
300
|
+
update(time_delta_seconds) {
|
|
301
|
+
assert.isNumber(time_delta_seconds, 'time_delta_seconds');
|
|
302
|
+
assert.greaterThanOrEqual(time_delta_seconds, 0, 'time_delta_seconds');
|
|
303
|
+
|
|
304
|
+
const device = this.#device;
|
|
305
|
+
|
|
306
|
+
// what was this frame's time is the frame before's
|
|
307
|
+
this.#clock_u32[2] = this.#clock_u32[0];
|
|
308
|
+
this.#clock_f32[3] = this.#clock_f32[1];
|
|
309
|
+
|
|
310
|
+
const fraction = this.#clock_fraction + time_delta_seconds;
|
|
311
|
+
const whole = Math.floor(fraction);
|
|
312
|
+
|
|
313
|
+
this.#clock_fraction = fraction - whole;
|
|
314
|
+
|
|
315
|
+
// whole seconds wrap with the word that holds them, as the sway's integer product does
|
|
316
|
+
this.#clock_u32[0] = (this.#clock_u32[0] + whole) >>> 0;
|
|
317
|
+
this.#clock_f32[1] = this.#clock_fraction;
|
|
318
|
+
|
|
319
|
+
if (this.#clock_buffer === null) {
|
|
320
|
+
this.#clock_buffer = device.createBuffer({
|
|
321
|
+
label: "grass / blade clock",
|
|
322
|
+
size: GRASS_BLADE_CLOCK_STRUCT.size,
|
|
323
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
device.queue.writeBuffer(this.#clock_buffer, 0, this.#clock);
|
|
328
|
+
|
|
329
|
+
if (this.#species_buffer === null || this.#species_buffer.size < this.#species.byteLength) {
|
|
330
|
+
this.#species_buffer?.destroy();
|
|
331
|
+
|
|
332
|
+
this.#species_buffer = device.createBuffer({
|
|
333
|
+
label: "grass / species",
|
|
334
|
+
size: this.#species.byteLength,
|
|
335
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
this.#species_dirty = true;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (this.#species_dirty) {
|
|
342
|
+
this.#species_dirty = false;
|
|
343
|
+
|
|
344
|
+
device.queue.writeBuffer(this.#species_buffer, 0, this.#species);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// a list that was asked for more than it holds doubles until it holds what was asked
|
|
348
|
+
while (this.#blades_asked > this.#blade_capacity && this.#blade_capacity < GRASS_BLADE_CAPACITY_LIMIT) {
|
|
349
|
+
this.#blade_capacity = Math.min(this.#blade_capacity * 2, GRASS_BLADE_CAPACITY_LIMIT);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
this.press.update(time_delta_seconds);
|
|
353
|
+
|
|
354
|
+
this.#products.clear();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Record the passes that make a view's blades: stamp the press field, count the cells, sum, and make
|
|
359
|
+
* the blades the counts allow. Records nothing while nothing grows.
|
|
360
|
+
*
|
|
361
|
+
* @param {object} options
|
|
362
|
+
* @param {FrameGraph} options.graph
|
|
363
|
+
* @param {GPUViewContext} options.view the view; its scene is the surfaces' scene
|
|
364
|
+
* @param {GPUFluidForcing|null} [options.forcing] the scene's GPU fluid forcing, whose obstacles press
|
|
365
|
+
* the blades; none press without it
|
|
366
|
+
*/
|
|
367
|
+
graph_generate({ graph, view, forcing = null }) {
|
|
368
|
+
assert.defined(graph, 'graph');
|
|
369
|
+
assert.defined(view, 'view');
|
|
370
|
+
|
|
371
|
+
const surfaces = this.#surfaces;
|
|
372
|
+
const settings = surfaces.view_settings(view);
|
|
373
|
+
|
|
374
|
+
if (settings === null || this.#species_buffer === null) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const blade_capacity = this.#blade_capacity;
|
|
379
|
+
|
|
380
|
+
settings.blade_capacity = blade_capacity;
|
|
381
|
+
|
|
382
|
+
const slot_capacity = settings.slot_capacity;
|
|
383
|
+
const scene = view.scene;
|
|
384
|
+
const camera = view.camera;
|
|
385
|
+
|
|
386
|
+
const press_field = this.press.graph_stamp({ graph, view, forcing });
|
|
387
|
+
|
|
388
|
+
graph.push_scope("grass blades");
|
|
389
|
+
|
|
390
|
+
const cell_data = {};
|
|
391
|
+
|
|
392
|
+
const cell_pass = graph.add("count cells", cell_data, (data, resources, context) => {
|
|
393
|
+
shader_grass_cell_count.dispatch({
|
|
394
|
+
encoder: context.encoder,
|
|
395
|
+
group_count_x: Math.ceil(slot_capacity / GRASS_CELL_COUNT_WORKGROUP_SIZE),
|
|
396
|
+
bindings: {
|
|
397
|
+
settings,
|
|
398
|
+
camera: camera.gpu_buffer,
|
|
399
|
+
scene_database: scene.scene_database_buffer,
|
|
400
|
+
grass_pool: surfaces.pool_buffer,
|
|
401
|
+
grass_directory: surfaces.directory_buffer,
|
|
402
|
+
grass_cell_counts: resources.get(data.counts),
|
|
403
|
+
grass_cells: resources.get(data.cells),
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
cell_data.counts = cell_pass.create("cell counts", BufferResourceDescriptor.from(
|
|
409
|
+
collection_size(slot_capacity),
|
|
410
|
+
GPUBufferUsage.STORAGE,
|
|
411
|
+
// the count, which thread 0 writes
|
|
412
|
+
0, COLLECTION_HEADER_BYTES,
|
|
413
|
+
));
|
|
414
|
+
|
|
415
|
+
cell_data.cells = cell_pass.create("cells", BufferResourceDescriptor.from(
|
|
416
|
+
slot_capacity * GRASS_CELL_WORDS * 4,
|
|
417
|
+
GPUBufferUsage.STORAGE,
|
|
418
|
+
));
|
|
419
|
+
|
|
420
|
+
const sums = graph_prefix_scan_csdldf({
|
|
421
|
+
graph,
|
|
422
|
+
input: cell_data.counts,
|
|
423
|
+
output: graph_create_buffer(graph, "cell offsets", prefix_scan_csdldf_output_descriptor(slot_capacity)),
|
|
424
|
+
element_max_count: slot_capacity,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const command_data = {};
|
|
428
|
+
|
|
429
|
+
const command_pass = graph.add("make blade command", command_data, (data, resources, context) => {
|
|
430
|
+
shader_prefix_sum_to_command.dispatch({
|
|
431
|
+
encoder: context.encoder,
|
|
432
|
+
bindings: {
|
|
433
|
+
prefix_sums: resources.get(data.prefix_sums),
|
|
434
|
+
command: resources.get(data.command),
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
command_data.prefix_sums = command_pass.read(sums);
|
|
440
|
+
command_data.command = command_pass.create("blade command", INDIRECT_COMPUTE_COMMAND_DESCRIPTOR);
|
|
441
|
+
|
|
442
|
+
const expand_data = {};
|
|
443
|
+
|
|
444
|
+
const expand_pass = graph.add("make blades", expand_data, (data, resources, context) => {
|
|
445
|
+
const bindings = {
|
|
446
|
+
settings,
|
|
447
|
+
camera: camera.gpu_buffer,
|
|
448
|
+
scene_database: scene.scene_database_buffer,
|
|
449
|
+
prefix_sums: resources.get(data.prefix_sums),
|
|
450
|
+
grass_cells: resources.get(data.cells),
|
|
451
|
+
grass_species: this.#species_buffer,
|
|
452
|
+
grass_surfels: surfaces.atlas_view,
|
|
453
|
+
grass_blades: resources.get(data.blades),
|
|
454
|
+
grass_clock: this.#clock_buffer,
|
|
455
|
+
grass_press: resources.get(data.press),
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
this.press.bind(bindings);
|
|
459
|
+
|
|
460
|
+
// the wind as it is and as the frame before read it
|
|
461
|
+
scene.wind.bind_history(bindings);
|
|
462
|
+
|
|
463
|
+
shader_grass_blade_expand.dispatchIndirect({
|
|
464
|
+
encoder: context.encoder,
|
|
465
|
+
command: resources.get(data.command),
|
|
466
|
+
bindings,
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
expand_data.command = expand_pass.read(command_data.command);
|
|
471
|
+
expand_data.prefix_sums = expand_pass.read(sums);
|
|
472
|
+
expand_data.cells = expand_pass.read(cell_data.cells);
|
|
473
|
+
expand_data.press = expand_pass.read(press_field);
|
|
474
|
+
expand_data.blades = expand_pass.create("blade list", BufferResourceDescriptor.from(
|
|
475
|
+
(GRASS_BLADE_LIST_HEADER_WORDS + blade_capacity * GRASS_BLADE_RECORD_WORDS) * 4,
|
|
476
|
+
// read back for its count
|
|
477
|
+
GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
|
|
478
|
+
// the count, which the blades raise from zero
|
|
479
|
+
0, GRASS_BLADE_LIST_HEADER_WORDS * 4,
|
|
480
|
+
));
|
|
481
|
+
|
|
482
|
+
const args_data = {};
|
|
483
|
+
|
|
484
|
+
const args_pass = graph.add("make blade draw", args_data, (data, resources, context) => {
|
|
485
|
+
shader_grass_blade_draw_args.dispatch({
|
|
486
|
+
encoder: context.encoder,
|
|
487
|
+
bindings: {
|
|
488
|
+
settings,
|
|
489
|
+
grass_blades: resources.get(data.blades),
|
|
490
|
+
draw_args: resources.get(data.draw_args),
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
args_data.blades = args_pass.write(args_pass.read(expand_data.blades));
|
|
496
|
+
args_data.draw_args = args_pass.create("blade draw arguments", BufferResourceDescriptor.from(
|
|
497
|
+
16,
|
|
498
|
+
GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT,
|
|
499
|
+
));
|
|
500
|
+
|
|
501
|
+
graph.pop_scope();
|
|
502
|
+
|
|
503
|
+
const product = new BladeProduct();
|
|
504
|
+
|
|
505
|
+
product.blades = args_data.blades;
|
|
506
|
+
product.draw_args = args_data.draw_args;
|
|
507
|
+
|
|
508
|
+
this.#products.set(view, product);
|
|
509
|
+
|
|
510
|
+
// how many blades asked for a place: a list too small for them is made larger from the next frame
|
|
511
|
+
graph_read_buffer({ graph, buffer: args_data.blades, offset: GRASS_BLADE_LIST_COUNT * 4, size: 4 })
|
|
512
|
+
.then(reference => {
|
|
513
|
+
try {
|
|
514
|
+
this.#blades_asked = Math.max(this.#blades_asked, new Uint32Array(reference.getValue())[0]);
|
|
515
|
+
} finally {
|
|
516
|
+
reference.release();
|
|
517
|
+
}
|
|
518
|
+
})
|
|
519
|
+
.catch(() => {
|
|
520
|
+
// a reading lost to a timeout or a lost device: a later frame's carries it
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Record a view's blade draw: its blades into the blade id target under the scene's depth, then the
|
|
526
|
+
* G-buffer's surface, the visibility word and the velocity under every pixel a blade covers. Publishes
|
|
527
|
+
* the depth, the G-buffer targets, the visibility buffer and the velocity buffer it wrote. Records nothing for a view {@link graph_generate} made no blades for this frame.
|
|
528
|
+
*
|
|
529
|
+
* @param {FrameContext} frame at the phase where the G-buffer is written into
|
|
530
|
+
*/
|
|
531
|
+
graph_draw(frame) {
|
|
532
|
+
const view = frame.view;
|
|
533
|
+
const product = this.#products.get(view);
|
|
534
|
+
|
|
535
|
+
if (product === undefined) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
this.#products.delete(view);
|
|
540
|
+
|
|
541
|
+
const graph = frame.graph;
|
|
542
|
+
const scene = view.scene;
|
|
543
|
+
const camera = view.camera;
|
|
544
|
+
|
|
545
|
+
const view_textures = frame.get(ViewTextures);
|
|
546
|
+
const gbuffer = frame.get(GBufferTextures);
|
|
547
|
+
|
|
548
|
+
graph.push_scope("grass blades");
|
|
549
|
+
|
|
550
|
+
const id_data = {};
|
|
551
|
+
|
|
552
|
+
const id_pass = graph.add("draw blade ids", id_data, (data, resources, context) => {
|
|
553
|
+
const encoder = context.encoder;
|
|
554
|
+
|
|
555
|
+
const bindings = GRASS_BLADE_ID_RESOURCES.generateBindings({
|
|
556
|
+
camera: camera.gpu_buffer,
|
|
557
|
+
scene_database: scene.scene_database_buffer,
|
|
558
|
+
grass_blades: resources.get(data.blades),
|
|
559
|
+
}, encoder);
|
|
560
|
+
|
|
561
|
+
const pass = encoder.constructRenderPass({
|
|
562
|
+
label: "Grass Blade Ids",
|
|
563
|
+
pipeline: GRASS_BLADE_ID_PIPELINE,
|
|
564
|
+
bindings,
|
|
565
|
+
colorAttachments: [{
|
|
566
|
+
view: resources.get(data.ids).obtainView(MIP_0),
|
|
567
|
+
loadOp: "clear",
|
|
568
|
+
clearValue: [GRASS_BLADE_ID_NONE, 0, 0, 0],
|
|
569
|
+
storeOp: "store",
|
|
570
|
+
}],
|
|
571
|
+
depthStencilAttachment: {
|
|
572
|
+
view: resources.get(data.depth).obtainView(DEFAULT_DEPTH_TEXTURE_VIEW),
|
|
573
|
+
// the scene's depth is what blades are hidden by, and what they then hide
|
|
574
|
+
depthLoadOp: "load",
|
|
575
|
+
depthStoreOp: "store",
|
|
576
|
+
},
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
pass.drawIndirect(resources.get(data.draw_args), 0);
|
|
580
|
+
pass.end();
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
id_data.blades = id_pass.read(product.blades);
|
|
584
|
+
id_data.draw_args = id_pass.read(product.draw_args);
|
|
585
|
+
id_data.depth = id_pass.write(view_textures.depth);
|
|
586
|
+
id_data.ids = id_pass.create("blade ids", TextureResourceDescriptor.from({
|
|
587
|
+
format: GRASS_BLADE_ID_FORMAT,
|
|
588
|
+
resolution: frame.resolution,
|
|
589
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
590
|
+
}));
|
|
591
|
+
|
|
592
|
+
view_textures.depth = id_data.depth;
|
|
593
|
+
|
|
594
|
+
const resolve_data = {};
|
|
595
|
+
|
|
596
|
+
const inverse_view_projection = new Float32Array(16);
|
|
597
|
+
const view_projection_previous = new Float32Array(16);
|
|
598
|
+
|
|
599
|
+
view_velocity_matrices(view, inverse_view_projection, view_projection_previous);
|
|
600
|
+
|
|
601
|
+
const resolve_pass = graph.add("resolve blades", resolve_data, (data, resources, context) => {
|
|
602
|
+
const encoder = context.encoder;
|
|
603
|
+
|
|
604
|
+
const bindings = GRASS_BLADE_RESOLVE_RESOURCES.generateBindings({
|
|
605
|
+
camera: camera.gpu_buffer,
|
|
606
|
+
scene_database: scene.scene_database_buffer,
|
|
607
|
+
grass_blades: resources.get(data.blades),
|
|
608
|
+
grass_species: this.#species_buffer,
|
|
609
|
+
grass_ids: resources.get(data.ids).obtainView(MIP_0),
|
|
610
|
+
scene_depth: resources.get(data.depth).obtainView(DEFAULT_DEPTH_TEXTURE_VIEW),
|
|
611
|
+
inverse_view_projection: encoder.allocateTransientBufferAndLoad(inverse_view_projection.buffer, GPUBufferUsage.UNIFORM),
|
|
612
|
+
view_projection_previous: encoder.allocateTransientBufferAndLoad(view_projection_previous.buffer, GPUBufferUsage.UNIFORM),
|
|
613
|
+
}, encoder);
|
|
614
|
+
|
|
615
|
+
const attachment = handle => ({
|
|
616
|
+
view: resources.get(handle).obtainView(MIP_0),
|
|
617
|
+
// every pixel no blade covers keeps what the scene left there
|
|
618
|
+
loadOp: "load",
|
|
619
|
+
storeOp: "store",
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
const pass = encoder.constructRenderPass({
|
|
623
|
+
label: "Grass Blade Resolve",
|
|
624
|
+
pipeline: GRASS_BLADE_RESOLVE_PIPELINE,
|
|
625
|
+
bindings,
|
|
626
|
+
colorAttachments: [
|
|
627
|
+
attachment(data.pbr),
|
|
628
|
+
attachment(data.normal),
|
|
629
|
+
attachment(data.albedo),
|
|
630
|
+
attachment(data.emissive),
|
|
631
|
+
attachment(data.visibility),
|
|
632
|
+
attachment(data.velocity),
|
|
633
|
+
],
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
pass.draw(3);
|
|
637
|
+
pass.end();
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
resolve_data.blades = resolve_pass.read(product.blades);
|
|
641
|
+
resolve_data.ids = resolve_pass.read(id_data.ids);
|
|
642
|
+
resolve_data.depth = resolve_pass.read(id_data.depth);
|
|
643
|
+
|
|
644
|
+
// in place: the written handles are what the record hands on
|
|
645
|
+
resolve_data.pbr = resolve_pass.write(gbuffer.pbr);
|
|
646
|
+
resolve_data.normal = resolve_pass.write(gbuffer.normal);
|
|
647
|
+
resolve_data.albedo = resolve_pass.write(gbuffer.albedo);
|
|
648
|
+
resolve_data.emissive = resolve_pass.write(gbuffer.emissive);
|
|
649
|
+
|
|
650
|
+
gbuffer.pbr = resolve_data.pbr;
|
|
651
|
+
gbuffer.normal = resolve_data.normal;
|
|
652
|
+
gbuffer.albedo = resolve_data.albedo;
|
|
653
|
+
gbuffer.emissive = resolve_data.emissive;
|
|
654
|
+
|
|
655
|
+
resolve_data.visibility = resolve_pass.write(view_textures.visibility);
|
|
656
|
+
resolve_data.velocity = resolve_pass.write(view_textures.velocity);
|
|
657
|
+
|
|
658
|
+
view_textures.visibility = resolve_data.visibility;
|
|
659
|
+
view_textures.velocity = resolve_data.velocity;
|
|
660
|
+
|
|
661
|
+
graph.pop_scope();
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Let go of everything on the device. The species stay listed.
|
|
666
|
+
*/
|
|
667
|
+
destroy() {
|
|
668
|
+
this.#species_buffer?.destroy();
|
|
669
|
+
this.#species_buffer = null;
|
|
670
|
+
this.#species_dirty = true;
|
|
671
|
+
this.#clock_buffer?.destroy();
|
|
672
|
+
this.#clock_buffer = null;
|
|
673
|
+
this.press.destroy();
|
|
674
|
+
this.#products.clear();
|
|
675
|
+
}
|
|
676
|
+
}
|