@woosh/meep-engine 3.64.1 → 3.67.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/format/lut/cube/CubeLut.d.ts +38 -0
- package/src/format/lut/cube/CubeLut.d.ts.map +1 -0
- package/src/format/lut/cube/CubeLut.js +23 -0
- package/src/format/lut/cube/cube_read.d.ts +23 -0
- package/src/format/lut/cube/cube_read.d.ts.map +1 -0
- package/src/format/lut/cube/cube_read.js +199 -0
- package/src/format/lut/cube/cube_write.d.ts +15 -0
- package/src/format/lut/cube/cube_write.d.ts.map +1 -0
- package/src/format/lut/cube/cube_write.js +90 -0
- 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/README.md +1 -0
- package/src/shade/playground/probe_clipmap/index.html +5 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +7 -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 +59 -55
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +73 -4
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/ColorGrade.js +113 -7
- package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts +12 -0
- package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.js +12 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +15 -1
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/ToneMapper.js +31 -3
- package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts +25 -0
- package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.js +51 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +2 -2
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js +6 -3
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +3 -2
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js +7 -3
- 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/eye/GPUCameraExposureManager.d.ts +35 -9
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +81 -11
- package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +4 -1
- 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/color/conversion/chunk_CRM_REC709_AP1.d.ts +6 -0
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +7 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +4 -4
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +86 -5
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts +65 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.js +136 -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
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts +0 -11
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.js +0 -56
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { CAMERA_RESOURCE } from "../../camera/CAMERA_RESOURCE.js";
|
|
2
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
3
|
+
import { COLLECTION_U32_STRUCT_WRITE } from "../../gpu_primitive/COLLECTION_U32_STRUCT_WRITE.js";
|
|
4
|
+
import { chunk_slot_stack } from "../../gpu_primitive/slot_stack/chunk_slot_stack.js";
|
|
5
|
+
import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
|
|
6
|
+
import { SCENE_DATABASE_RESOURCE } from "../../scene/SCENE_DATABASE_RESOURCE.js";
|
|
7
|
+
import { chunk_aabb3_from_transformed_corners } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js";
|
|
8
|
+
import { chunk_aabb3_intersects_frustum } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_intersects_frustum.js";
|
|
9
|
+
import { chunk_folded_workgroup_index } from "../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
10
|
+
import { chunk_lower_bound_branchless } from "../../shader/chunk/math/chunk_lower_bound_branchless.js";
|
|
11
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
12
|
+
import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
|
|
13
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
14
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
15
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
16
|
+
import { chunk_grass_directory } from "./chunk_grass_directory.js";
|
|
17
|
+
import { chunk_grass_surface_frame } from "./chunk_grass_surface_frame.js";
|
|
18
|
+
import { chunk_grass_surface_window } from "./chunk_grass_surface_window.js";
|
|
19
|
+
import {
|
|
20
|
+
GRASS_COLUMN_CROSSINGS,
|
|
21
|
+
GRASS_POOL_FREE_COUNT,
|
|
22
|
+
GRASS_POOL_STARVED,
|
|
23
|
+
GRASS_SLOT_HEIGHT_MAX,
|
|
24
|
+
GRASS_SLOT_HEIGHT_MIN,
|
|
25
|
+
GRASS_SLOT_LAYER_COUNT,
|
|
26
|
+
GRASS_SLOT_LEVEL_LAYER,
|
|
27
|
+
GRASS_SLOT_NORMAL_SPREAD,
|
|
28
|
+
GRASS_SLOT_STATE,
|
|
29
|
+
GRASS_SLOT_STATE_BAKED,
|
|
30
|
+
GRASS_SLOT_STATE_ORPHAN,
|
|
31
|
+
GRASS_SLOT_STATE_PENDING,
|
|
32
|
+
GRASS_SLOT_STATE_STALE,
|
|
33
|
+
GRASS_SLOT_SURFACE,
|
|
34
|
+
GRASS_SLOT_SURFEL_COUNT,
|
|
35
|
+
GRASS_SLOT_TILE_X,
|
|
36
|
+
GRASS_SLOT_TILE_Z,
|
|
37
|
+
GRASS_SLOT_WANTED_FRAME
|
|
38
|
+
} from "./GRASS_SURFACE.js";
|
|
39
|
+
import {
|
|
40
|
+
GRASS_DIRECTORY_RESOURCE,
|
|
41
|
+
GRASS_POOL_RESOURCE,
|
|
42
|
+
GRASS_SURFACE_VIEW_SETTINGS,
|
|
43
|
+
GRASS_SURFACES_RESOURCE
|
|
44
|
+
} from "./GRASS_SURFACE_VIEW.js";
|
|
45
|
+
|
|
46
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
47
|
+
|
|
48
|
+
resources.setImmediate("settings", GRASS_SURFACE_VIEW_SETTINGS);
|
|
49
|
+
|
|
50
|
+
resources.createGroup()
|
|
51
|
+
.add(CAMERA_RESOURCE)
|
|
52
|
+
.add(SCENE_DATABASE_RESOURCE)
|
|
53
|
+
.add(GRASS_SURFACES_RESOURCE)
|
|
54
|
+
.addStorageBuffer("prefix_sums", COLLECTION_U32_STRUCT_READ)
|
|
55
|
+
.add(GRASS_POOL_RESOURCE)
|
|
56
|
+
.add(GRASS_DIRECTORY_RESOURCE)
|
|
57
|
+
.addStorageBuffer("grass_free", WebGPUArray.u32, true)
|
|
58
|
+
.addStorageBuffer("grass_jobs", COLLECTION_U32_STRUCT_WRITE, true);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Asks for the tiles of the grass surfaces a view wants, a thread a tile of a window
|
|
62
|
+
* ({@link shader_grass_surface_window_count}, whose counts, summed, are `prefix_sums`).
|
|
63
|
+
*
|
|
64
|
+
* A thread finds its level of its surface from the sums and its tile from its place among that window's
|
|
65
|
+
* threads. A tile outside its level's ring (`grass_tile_wanted`) or outside the view's frustum is not
|
|
66
|
+
* wanted, and the thread ends.
|
|
67
|
+
*
|
|
68
|
+
* **A wanted tile's layers.** Layer 0 always; and once layer 0 is baked, the layers past it that its record
|
|
69
|
+
* counts. For each:
|
|
70
|
+
*
|
|
71
|
+
* - held by a slot (`grass_directory_find`): the slot's record is stamped with the frame. A stale slot also
|
|
72
|
+
* takes a place in the frame's bake list, with what a bake gathers into its record reset, and keeps its
|
|
73
|
+
* state: it reads as it was until the bake has run;
|
|
74
|
+
* - not held: the thread takes a place in the frame's bake list (`grass_jobs`, at most `job_capacity`
|
|
75
|
+
* places, a count that keeps rising past them) and a slot off the free stack, writes the slot's record
|
|
76
|
+
* for the layer, pending, and lists it in the directory. With the bake list full the layer waits for a
|
|
77
|
+
* later frame. With no slot free the place holds `GRASS_SLOT_NONE` and the pool's starved count rises.
|
|
78
|
+
* A slot the directory has no room for is marked an orphan and its place holds `GRASS_SLOT_NONE`.
|
|
79
|
+
*
|
|
80
|
+
* Every thread's layers are its own, so no two threads of a dispatch ask for the same one; two views ask
|
|
81
|
+
* in two dispatches, and the second finds what the first took.
|
|
82
|
+
*
|
|
83
|
+
* Dispatched through `shader_prefix_sum_to_command`'s folded command.
|
|
84
|
+
*
|
|
85
|
+
* @type {ComputeShader}
|
|
86
|
+
*/
|
|
87
|
+
export const shader_grass_surface_want = ComputeShader.from({
|
|
88
|
+
label: "Grass Surface Want",
|
|
89
|
+
resources,
|
|
90
|
+
body: CodeChunk.from(
|
|
91
|
+
//language=WGSL
|
|
92
|
+
`
|
|
93
|
+
// what a bake counts and gathers into a slot's record, as a bake is to find it
|
|
94
|
+
fn grass_slot_reset_bake(record: u32) {
|
|
95
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_LAYER_COUNT}u], 0u);
|
|
96
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_SURFEL_COUNT}u], 0u);
|
|
97
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_HEIGHT_MIN}u], 0xFFFFFFFFu);
|
|
98
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_HEIGHT_MAX}u], 0u);
|
|
99
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_NORMAL_SPREAD}u], 0u);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// stamp the layer's slot as wanted, or take a slot and a place in the bake for it; the slot that holds it, or none yet
|
|
103
|
+
fn grass_want_layer(surface: u32, level: u32, layer: u32, tile: vec2<i32>) -> u32 {
|
|
104
|
+
let level_layer = level | (layer << 8u);
|
|
105
|
+
|
|
106
|
+
let held = grass_directory_find(surface, level_layer, tile);
|
|
107
|
+
|
|
108
|
+
if (held != GRASS_SLOT_NONE) {
|
|
109
|
+
let record = grass_slot_record(held);
|
|
110
|
+
|
|
111
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_WANTED_FRAME}u], settings.frame);
|
|
112
|
+
|
|
113
|
+
if (atomicLoad(&grass_pool[record + ${GRASS_SLOT_STATE}u]) == ${GRASS_SLOT_STATE_STALE}u) {
|
|
114
|
+
// baked again where it is, once the frame's bake has a place for it; until then it reads as it was
|
|
115
|
+
let place = atomicAdd(&grass_jobs.count, 1u);
|
|
116
|
+
|
|
117
|
+
if (place < settings.job_capacity) {
|
|
118
|
+
grass_slot_reset_bake(record);
|
|
119
|
+
|
|
120
|
+
grass_jobs.elements[place] = held;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return held;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let place = atomicAdd(&grass_jobs.count, 1u);
|
|
128
|
+
|
|
129
|
+
if (place >= settings.job_capacity) {
|
|
130
|
+
return GRASS_SLOT_NONE;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let slot = slot_stack_pop(&grass_pool[${GRASS_POOL_FREE_COUNT}u], &grass_free, settings.slot_capacity);
|
|
134
|
+
|
|
135
|
+
grass_jobs.elements[place] = slot;
|
|
136
|
+
|
|
137
|
+
if (slot == SLOT_STACK_NONE) {
|
|
138
|
+
atomicAdd(&grass_pool[${GRASS_POOL_STARVED}u], 1u);
|
|
139
|
+
|
|
140
|
+
return GRASS_SLOT_NONE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let record = grass_slot_record(slot);
|
|
144
|
+
|
|
145
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_SURFACE}u], surface);
|
|
146
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_LEVEL_LAYER}u], level_layer);
|
|
147
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_TILE_X}u], bitcast<u32>(tile.x));
|
|
148
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_TILE_Z}u], bitcast<u32>(tile.y));
|
|
149
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_STATE}u], ${GRASS_SLOT_STATE_PENDING}u);
|
|
150
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_WANTED_FRAME}u], settings.frame);
|
|
151
|
+
|
|
152
|
+
grass_slot_reset_bake(record);
|
|
153
|
+
|
|
154
|
+
if (!grass_directory_insert(surface, level_layer, tile, slot)) {
|
|
155
|
+
atomicStore(&grass_pool[record + ${GRASS_SLOT_STATE}u], ${GRASS_SLOT_STATE_ORPHAN}u);
|
|
156
|
+
|
|
157
|
+
grass_jobs.elements[place] = GRASS_SLOT_NONE;
|
|
158
|
+
|
|
159
|
+
return GRASS_SLOT_NONE;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return slot;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@compute @workgroup_size(${COMPUTE_SHADER_DEFAULT_GROUP_SIZE})
|
|
166
|
+
fn main(
|
|
167
|
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
|
168
|
+
@builtin(local_invocation_index) lane: u32,
|
|
169
|
+
) {
|
|
170
|
+
let thread = folded_workgroup_index(workgroup_id) * ${COMPUTE_SHADER_DEFAULT_GROUP_SIZE}u + lane;
|
|
171
|
+
|
|
172
|
+
// the sums are inclusive: a thread belongs to the first window whose sum is past it
|
|
173
|
+
let windows = prefix_sums.count;
|
|
174
|
+
let index = lower_bound_branchless(&prefix_sums.elements, thread + 1u, windows);
|
|
175
|
+
|
|
176
|
+
if (index >= windows) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
var place = thread;
|
|
181
|
+
|
|
182
|
+
if (index > 0u) {
|
|
183
|
+
place -= prefix_sums.elements[index - 1u];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let surface = grass_surfaces[index / settings.level_count];
|
|
187
|
+
let level = index % settings.level_count;
|
|
188
|
+
|
|
189
|
+
let frame = grass_surface_frame(${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, surface.node));
|
|
190
|
+
let eye = grass_world_to_frame(frame, camera.transform[3].xyz);
|
|
191
|
+
|
|
192
|
+
let window = grass_surface_window(settings, surface, level, eye);
|
|
193
|
+
|
|
194
|
+
let tile = window.corner + vec2<i32>(i32(place % window.size.x), i32(place / window.size.x));
|
|
195
|
+
|
|
196
|
+
let tile_box = grass_tile_box(settings, surface, level, tile);
|
|
197
|
+
|
|
198
|
+
if (!grass_tile_wanted(settings, surface, level, tile_box, eye)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// where the tile's grass can be, against the view's frustum
|
|
203
|
+
let low = tile_box.low;
|
|
204
|
+
let high = tile_box.high;
|
|
205
|
+
|
|
206
|
+
let box = aabb3_from_transformed_corners(array<vec3<f32>, 8>(
|
|
207
|
+
vec3<f32>(low.x, low.y, low.z),
|
|
208
|
+
vec3<f32>(high.x, low.y, low.z),
|
|
209
|
+
vec3<f32>(low.x, high.y, low.z),
|
|
210
|
+
vec3<f32>(high.x, high.y, low.z),
|
|
211
|
+
vec3<f32>(low.x, low.y, high.z),
|
|
212
|
+
vec3<f32>(high.x, low.y, high.z),
|
|
213
|
+
vec3<f32>(low.x, high.y, high.z),
|
|
214
|
+
vec3<f32>(high.x, high.y, high.z),
|
|
215
|
+
), frame);
|
|
216
|
+
|
|
217
|
+
if (!aabb3_intersects_frustum(box, camera.frustum)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
let top = grass_want_layer(surface.node, level, 0u, tile);
|
|
222
|
+
|
|
223
|
+
if (top == GRASS_SLOT_NONE) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let record = grass_slot_record(top);
|
|
228
|
+
|
|
229
|
+
if (atomicLoad(&grass_pool[record + ${GRASS_SLOT_STATE}u]) != ${GRASS_SLOT_STATE_BAKED}u) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// a tile has no more layers than a column's walk has crossings
|
|
234
|
+
let layers = min(atomicLoad(&grass_pool[record + ${GRASS_SLOT_LAYER_COUNT}u]), ${GRASS_COLUMN_CROSSINGS}u);
|
|
235
|
+
|
|
236
|
+
for (var layer = 1u; layer < layers; layer++) {
|
|
237
|
+
grass_want_layer(surface.node, level, layer, tile);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
`, [
|
|
241
|
+
chunk_folded_workgroup_index,
|
|
242
|
+
chunk_lower_bound_branchless,
|
|
243
|
+
chunk_slot_stack,
|
|
244
|
+
chunk_aabb3_from_transformed_corners,
|
|
245
|
+
chunk_aabb3_intersects_frustum,
|
|
246
|
+
chunk_grass_surface_frame,
|
|
247
|
+
chunk_grass_surface_window,
|
|
248
|
+
chunk_grass_directory,
|
|
249
|
+
TRANSFORMS_TABLE.chunk_read_field('global'),
|
|
250
|
+
]),
|
|
251
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threads in a workgroup of {@link shader_grass_surface_window_count}.
|
|
3
|
+
*
|
|
4
|
+
* @type {number}
|
|
5
|
+
*/
|
|
6
|
+
export const GRASS_SURFACE_WINDOW_COUNT_WORKGROUP_SIZE: number;
|
|
7
|
+
/**
|
|
8
|
+
* Counts the tiles a view may want of each level of each grass surface, a thread a level of a surface.
|
|
9
|
+
*
|
|
10
|
+
* Thread `s * level_count + l` writes how many tiles the window of level `l` of surface `s` has
|
|
11
|
+
* (`grass_surface_window`) to `grass_window_counts.elements` at its own index, and thread 0 writes how many
|
|
12
|
+
* counts there are to `grass_window_counts.count`. Threads past `surface_count * level_count` write nothing,
|
|
13
|
+
* so the dispatch covers that many threads and need not be exact.
|
|
14
|
+
*
|
|
15
|
+
* The counts are what a prefix scan turns into a thread a tile for {@link shader_grass_surface_want}.
|
|
16
|
+
*
|
|
17
|
+
* @type {ComputeShader}
|
|
18
|
+
*/
|
|
19
|
+
export const shader_grass_surface_window_count: ComputeShader;
|
|
20
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
21
|
+
//# sourceMappingURL=shader_grass_surface_window_count.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_grass_surface_window_count.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/surface/shader_grass_surface_window_count.js"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wDAFU,MAAM,CAE4C;AAY5D;;;;;;;;;;;GAWG;AACH,gDAFU,aAAa,CAoCpB;8BArE2B,+BAA+B"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CAMERA_RESOURCE } from "../../camera/CAMERA_RESOURCE.js";
|
|
2
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
3
|
+
import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
|
|
4
|
+
import { SCENE_DATABASE_RESOURCE } from "../../scene/SCENE_DATABASE_RESOURCE.js";
|
|
5
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
6
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
7
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
|
+
import { chunk_grass_surface_frame } from "./chunk_grass_surface_frame.js";
|
|
9
|
+
import { chunk_grass_surface_window } from "./chunk_grass_surface_window.js";
|
|
10
|
+
import { GRASS_SURFACE_VIEW_SETTINGS, GRASS_SURFACES_RESOURCE } from "./GRASS_SURFACE_VIEW.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Threads in a workgroup of {@link shader_grass_surface_window_count}.
|
|
14
|
+
*
|
|
15
|
+
* @type {number}
|
|
16
|
+
*/
|
|
17
|
+
export const GRASS_SURFACE_WINDOW_COUNT_WORKGROUP_SIZE = 64;
|
|
18
|
+
|
|
19
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
20
|
+
|
|
21
|
+
resources.setImmediate("settings", GRASS_SURFACE_VIEW_SETTINGS);
|
|
22
|
+
|
|
23
|
+
resources.createGroup()
|
|
24
|
+
.add(CAMERA_RESOURCE)
|
|
25
|
+
.add(SCENE_DATABASE_RESOURCE)
|
|
26
|
+
.add(GRASS_SURFACES_RESOURCE)
|
|
27
|
+
.addStorageBuffer("grass_window_counts", COLLECTION_U32_STRUCT_READ, true);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Counts the tiles a view may want of each level of each grass surface, a thread a level of a surface.
|
|
31
|
+
*
|
|
32
|
+
* Thread `s * level_count + l` writes how many tiles the window of level `l` of surface `s` has
|
|
33
|
+
* (`grass_surface_window`) to `grass_window_counts.elements` at its own index, and thread 0 writes how many
|
|
34
|
+
* counts there are to `grass_window_counts.count`. Threads past `surface_count * level_count` write nothing,
|
|
35
|
+
* so the dispatch covers that many threads and need not be exact.
|
|
36
|
+
*
|
|
37
|
+
* The counts are what a prefix scan turns into a thread a tile for {@link shader_grass_surface_want}.
|
|
38
|
+
*
|
|
39
|
+
* @type {ComputeShader}
|
|
40
|
+
*/
|
|
41
|
+
export const shader_grass_surface_window_count = ComputeShader.from({
|
|
42
|
+
label: "Grass Surface Window Count",
|
|
43
|
+
resources,
|
|
44
|
+
body: CodeChunk.from(
|
|
45
|
+
//language=WGSL
|
|
46
|
+
`
|
|
47
|
+
@compute @workgroup_size(${GRASS_SURFACE_WINDOW_COUNT_WORKGROUP_SIZE})
|
|
48
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
49
|
+
let index = id.x;
|
|
50
|
+
let total = settings.surface_count * settings.level_count;
|
|
51
|
+
|
|
52
|
+
if (index == 0u) {
|
|
53
|
+
grass_window_counts.count = total;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (index >= total) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let surface = grass_surfaces[index / settings.level_count];
|
|
61
|
+
let level = index % settings.level_count;
|
|
62
|
+
|
|
63
|
+
let frame = grass_surface_frame(${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, surface.node));
|
|
64
|
+
let eye = grass_world_to_frame(frame, camera.transform[3].xyz);
|
|
65
|
+
|
|
66
|
+
let window = grass_surface_window(settings, surface, level, eye);
|
|
67
|
+
|
|
68
|
+
grass_window_counts.elements[index] = window.size.x * window.size.y;
|
|
69
|
+
}
|
|
70
|
+
`, [
|
|
71
|
+
chunk_grass_surface_frame,
|
|
72
|
+
chunk_grass_surface_window,
|
|
73
|
+
TRANSFORMS_TABLE.chunk_read_field('global'),
|
|
74
|
+
]),
|
|
75
|
+
});
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* The factor lives in one buffer for the manager's life, {@link multiplier}, which a frame's {@link update} or
|
|
6
6
|
* {@link unadapted} writes over. A pass recorded ahead of that write in the frame reads the factor the last frame was
|
|
7
7
|
* shown with: the exposure of the image on screen, Unreal Engine's `View.PreExposure`.
|
|
8
|
+
*
|
|
9
|
+
* Beside it, {@link adaptation}: the luminance the view is adapted to, cd/m², written by the same pass. Adapted, it is
|
|
10
|
+
* the luminance the eye has adapted to, without {@link exposure_compensation}; unadapted, it is the luminance the
|
|
11
|
+
* exposure shows at middle grey.
|
|
8
12
|
*/
|
|
9
13
|
export class GPUCameraExposureManager {
|
|
10
14
|
/**
|
|
@@ -44,9 +48,17 @@ export class GPUCameraExposureManager {
|
|
|
44
48
|
* imports it into its graph once, and hands the handle both to the passes that read it ahead of the exposure,
|
|
45
49
|
* which take the last frame's factor, and to {@link update} or {@link unadapted}, which write this frame's.
|
|
46
50
|
*
|
|
47
|
-
* @returns {GPUBuffer} usable as a uniform or read-only storage
|
|
51
|
+
* @returns {GPUBuffer} usable as a uniform or read-only storage, and as a copy source, to read it back
|
|
48
52
|
*/
|
|
49
53
|
get multiplier(): GPUBuffer;
|
|
54
|
+
/**
|
|
55
|
+
* The luminance the view is adapted to, cd/m², {@link F32_CONTAINER_STRUCT}, as the last {@link update} or
|
|
56
|
+
* {@link unadapted} wrote it. Imported into a frame's graph once and handed to {@link update} or {@link unadapted},
|
|
57
|
+
* like {@link multiplier}.
|
|
58
|
+
*
|
|
59
|
+
* @returns {GPUBuffer} usable as a uniform or read-only storage
|
|
60
|
+
*/
|
|
61
|
+
get adaptation(): GPUBuffer;
|
|
50
62
|
/**
|
|
51
63
|
* Offer the pipelines {@link update} meters and adapts with — see {@link PipelineEnquiry}.
|
|
52
64
|
* {@link unadapted} dispatches none.
|
|
@@ -55,34 +67,48 @@ export class GPUCameraExposureManager {
|
|
|
55
67
|
*/
|
|
56
68
|
enquirePipelines(enquiry: PipelineEnquiry): void;
|
|
57
69
|
/**
|
|
58
|
-
* This frame's factor from {@link exposure_compensation} alone: 2^compensation.
|
|
70
|
+
* This frame's factor from {@link exposure_compensation} alone: 2^compensation. Its adaptation is the luminance
|
|
71
|
+
* that factor shows at middle grey, 0.18 / 2^compensation cd/m².
|
|
59
72
|
*
|
|
60
73
|
* @param {Object} options
|
|
61
74
|
* @param {FrameGraph} options.graph
|
|
62
75
|
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
63
|
-
* @
|
|
76
|
+
* @param {number} options.adaptation the graph handle of {@link adaptation}, imported into `graph`
|
|
77
|
+
* @return {{multiplier: number, adaptation: number}} the handles of {@link multiplier} and {@link adaptation}
|
|
78
|
+
* with this frame's written; the object is reused by the next call
|
|
64
79
|
*/
|
|
65
|
-
unadapted({ graph, multiplier, }: {
|
|
80
|
+
unadapted({ graph, multiplier, adaptation, }: {
|
|
66
81
|
graph: FrameGraph;
|
|
67
82
|
multiplier: number;
|
|
68
|
-
|
|
83
|
+
adaptation: number;
|
|
84
|
+
}): {
|
|
85
|
+
multiplier: number;
|
|
86
|
+
adaptation: number;
|
|
87
|
+
};
|
|
69
88
|
/**
|
|
70
89
|
* This frame's factor metered from `input_color`: the luminance adapted toward the frame's, from the last
|
|
71
|
-
* frame's, by the adaptation speeds; its factor is middle grey over it, times 2^{@link exposure_compensation}.
|
|
90
|
+
* frame's, by the adaptation speeds; its factor is middle grey over it, times 2^{@link exposure_compensation}. Its
|
|
91
|
+
* adaptation is that adapted luminance, without the compensation.
|
|
72
92
|
*
|
|
73
93
|
* @param {Object} options
|
|
74
94
|
* @param {FrameGraph} options.graph
|
|
75
95
|
* @param {number} options.input_color
|
|
76
96
|
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
97
|
+
* @param {number} options.adaptation the graph handle of {@link adaptation}, imported into `graph`
|
|
77
98
|
* @param {number} [options.time_delta_seconds]
|
|
78
|
-
* @return {number} the
|
|
99
|
+
* @return {{multiplier: number, adaptation: number}} the handles of {@link multiplier} and {@link adaptation}
|
|
100
|
+
* with this frame's written; the object is reused by the next call
|
|
79
101
|
*/
|
|
80
|
-
update({ input_color, graph, multiplier, time_delta_seconds, }: {
|
|
102
|
+
update({ input_color, graph, multiplier, adaptation, time_delta_seconds, }: {
|
|
81
103
|
graph: FrameGraph;
|
|
82
104
|
input_color: number;
|
|
83
105
|
multiplier: number;
|
|
106
|
+
adaptation: number;
|
|
84
107
|
time_delta_seconds?: number;
|
|
85
|
-
}):
|
|
108
|
+
}): {
|
|
109
|
+
multiplier: number;
|
|
110
|
+
adaptation: number;
|
|
111
|
+
};
|
|
86
112
|
#private;
|
|
87
113
|
}
|
|
88
114
|
export type PipelineEnquiry = import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUCameraExposureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUCameraExposureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js"],"names":[],"mappings":"AA6BA;;;;;;;;;;;GAWG;AACH;IAuEI;;;OAGG;IACH,+BAoCC;IAlFD;;;;OAIG;IACH,qBAFU,MAAM,CAEU;IAE1B;;;;OAIG;IACH,uBAFU,MAAM,CAEY;IAE5B;;;;;OAKG;IACH,yBAFU,MAAM,CAEc;IAE9B;;;;;OAKG;IACH,uBAFU,MAAM,CAEY;IAwD5B,gBAOC;IAED;;;;;;OAMG;IACH,4BAEC;IAED;;;;;;OAMG;IACH,4BAEC;IAED;;;;;OAKG;IACH,0BAFW,eAAe,QAMzB;IAED;;;;;;;;;;OAUG;IACH;QAN+B,KAAK;QACT,UAAU,EAA1B,MAAM;QACU,UAAU,EAA1B,MAAM;QACL;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,CAwBnD;IAsBD;;;;;;;;;;;;;OAaG;IACH;QAR+B,KAAK;QACT,WAAW,EAA3B,MAAM;QACU,UAAU,EAA1B,MAAM;QACU,UAAU,EAA1B,MAAM;QACW,kBAAkB,GAAnC,MAAM;QACL;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,CA4DnD;;CA4EJ;8BAnYY,OAAO,6CAA6C,EAAE,eAAe"}
|
|
@@ -17,6 +17,11 @@ const HISTOGRAM_DESCRIPTOR = BufferResourceDescriptor.empty(
|
|
|
17
17
|
GPUBufferUsage.STORAGE,
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The luminance an exposure of one shows at middle grey, cd/m²: the scene value the adaptation maps to 0.18.
|
|
22
|
+
*/
|
|
23
|
+
const MIDDLE_GREY = 0.18;
|
|
24
|
+
|
|
20
25
|
const TARGET_LUMINANCE_DESCRIPTOR = BufferResourceDescriptor.from(
|
|
21
26
|
F32_CONTAINER_STRUCT.size,
|
|
22
27
|
GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM,
|
|
@@ -29,6 +34,10 @@ const TARGET_LUMINANCE_DESCRIPTOR = BufferResourceDescriptor.from(
|
|
|
29
34
|
* The factor lives in one buffer for the manager's life, {@link multiplier}, which a frame's {@link update} or
|
|
30
35
|
* {@link unadapted} writes over. A pass recorded ahead of that write in the frame reads the factor the last frame was
|
|
31
36
|
* shown with: the exposure of the image on screen, Unreal Engine's `View.PreExposure`.
|
|
37
|
+
*
|
|
38
|
+
* Beside it, {@link adaptation}: the luminance the view is adapted to, cd/m², written by the same pass. Adapted, it is
|
|
39
|
+
* the luminance the eye has adapted to, without {@link exposure_compensation}; unadapted, it is the luminance the
|
|
40
|
+
* exposure shows at middle grey.
|
|
32
41
|
*/
|
|
33
42
|
export class GPUCameraExposureManager {
|
|
34
43
|
/**
|
|
@@ -47,6 +56,18 @@ export class GPUCameraExposureManager {
|
|
|
47
56
|
*/
|
|
48
57
|
#multiplier;
|
|
49
58
|
|
|
59
|
+
/**
|
|
60
|
+
* {@link F32_CONTAINER_STRUCT}: the adaptation the last {@link update} or {@link unadapted} wrote, cd/m².
|
|
61
|
+
* @type {GPUTypedBuffer}
|
|
62
|
+
*/
|
|
63
|
+
#adaptation;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The handles {@link update} and {@link unadapted} return, kept across frames.
|
|
67
|
+
* @type {{multiplier: number, adaptation: number}}
|
|
68
|
+
*/
|
|
69
|
+
#written = { multiplier: -1, adaptation: -1 };
|
|
70
|
+
|
|
50
71
|
/**
|
|
51
72
|
* How fast do we adapt to brighter environments?
|
|
52
73
|
* in f-stops per second.
|
|
@@ -78,15 +99,16 @@ export class GPUCameraExposureManager {
|
|
|
78
99
|
exposure_compensation = 0.0;
|
|
79
100
|
|
|
80
101
|
// what each pass's execution reads, kept across frames: a frame records them and runs them before the next does
|
|
81
|
-
#unadapted_data = { output: -1 };
|
|
102
|
+
#unadapted_data = { output: -1, adaptation: -1 };
|
|
82
103
|
#unadapted_value = { value: 1.0 };
|
|
104
|
+
#unadapted_adaptation = { value: MIDDLE_GREY };
|
|
83
105
|
#build_data = { input_color: -1, output: -1 };
|
|
84
106
|
#parse_data = { input_histogram: -1, output: -1 };
|
|
85
|
-
#adapt_data = { goal: -1, previous: -1, adapted: -1, out_multiplier: -1 };
|
|
107
|
+
#adapt_data = { goal: -1, previous: -1, adapted: -1, out_multiplier: -1, out_adaptation: -1 };
|
|
86
108
|
#adapt_settings = { speed_up: 0, speed_down: 0, time_delta: 0, exp_transition_distance: 0, compensation: 0 };
|
|
87
109
|
#build_bindings = { tInput: null, histogram: null };
|
|
88
110
|
#parse_bindings = { histogram: null, output: null };
|
|
89
|
-
#adapt_bindings = { goal: null, previous: null, settings: this.#adapt_settings, adapted: null, out_multiplier: null };
|
|
111
|
+
#adapt_bindings = { goal: null, previous: null, settings: this.#adapt_settings, adapted: null, out_multiplier: null, out_adaptation: null };
|
|
90
112
|
|
|
91
113
|
/**
|
|
92
114
|
*
|
|
@@ -110,13 +132,24 @@ export class GPUCameraExposureManager {
|
|
|
110
132
|
this.#multiplier = GPUTypedBuffer.create({
|
|
111
133
|
label: 'exposure multiplier',
|
|
112
134
|
device,
|
|
113
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
135
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
|
|
114
136
|
type: F32_CONTAINER_STRUCT,
|
|
115
137
|
initial_value: {
|
|
116
138
|
value: 1.0
|
|
117
139
|
}
|
|
118
140
|
});
|
|
119
141
|
|
|
142
|
+
// what a factor of one shows at middle grey, until the first frame writes its own
|
|
143
|
+
this.#adaptation = GPUTypedBuffer.create({
|
|
144
|
+
label: 'exposure adaptation',
|
|
145
|
+
device,
|
|
146
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
147
|
+
type: F32_CONTAINER_STRUCT,
|
|
148
|
+
initial_value: {
|
|
149
|
+
value: MIDDLE_GREY
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
120
153
|
}
|
|
121
154
|
|
|
122
155
|
destroy() {
|
|
@@ -125,6 +158,7 @@ export class GPUCameraExposureManager {
|
|
|
125
158
|
}
|
|
126
159
|
|
|
127
160
|
this.#multiplier.destroy();
|
|
161
|
+
this.#adaptation.destroy();
|
|
128
162
|
}
|
|
129
163
|
|
|
130
164
|
/**
|
|
@@ -132,12 +166,23 @@ export class GPUCameraExposureManager {
|
|
|
132
166
|
* imports it into its graph once, and hands the handle both to the passes that read it ahead of the exposure,
|
|
133
167
|
* which take the last frame's factor, and to {@link update} or {@link unadapted}, which write this frame's.
|
|
134
168
|
*
|
|
135
|
-
* @returns {GPUBuffer} usable as a uniform or read-only storage
|
|
169
|
+
* @returns {GPUBuffer} usable as a uniform or read-only storage, and as a copy source, to read it back
|
|
136
170
|
*/
|
|
137
171
|
get multiplier() {
|
|
138
172
|
return this.#multiplier.buffer;
|
|
139
173
|
}
|
|
140
174
|
|
|
175
|
+
/**
|
|
176
|
+
* The luminance the view is adapted to, cd/m², {@link F32_CONTAINER_STRUCT}, as the last {@link update} or
|
|
177
|
+
* {@link unadapted} wrote it. Imported into a frame's graph once and handed to {@link update} or {@link unadapted},
|
|
178
|
+
* like {@link multiplier}.
|
|
179
|
+
*
|
|
180
|
+
* @returns {GPUBuffer} usable as a uniform or read-only storage
|
|
181
|
+
*/
|
|
182
|
+
get adaptation() {
|
|
183
|
+
return this.#adaptation.buffer;
|
|
184
|
+
}
|
|
185
|
+
|
|
141
186
|
/**
|
|
142
187
|
* Offer the pipelines {@link update} meters and adapts with — see {@link PipelineEnquiry}.
|
|
143
188
|
* {@link unadapted} dispatches none.
|
|
@@ -151,26 +196,37 @@ export class GPUCameraExposureManager {
|
|
|
151
196
|
}
|
|
152
197
|
|
|
153
198
|
/**
|
|
154
|
-
* This frame's factor from {@link exposure_compensation} alone: 2^compensation.
|
|
199
|
+
* This frame's factor from {@link exposure_compensation} alone: 2^compensation. Its adaptation is the luminance
|
|
200
|
+
* that factor shows at middle grey, 0.18 / 2^compensation cd/m².
|
|
155
201
|
*
|
|
156
202
|
* @param {Object} options
|
|
157
203
|
* @param {FrameGraph} options.graph
|
|
158
204
|
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
159
|
-
* @
|
|
205
|
+
* @param {number} options.adaptation the graph handle of {@link adaptation}, imported into `graph`
|
|
206
|
+
* @return {{multiplier: number, adaptation: number}} the handles of {@link multiplier} and {@link adaptation}
|
|
207
|
+
* with this frame's written; the object is reused by the next call
|
|
160
208
|
*/
|
|
161
209
|
unadapted({
|
|
162
210
|
graph,
|
|
163
211
|
multiplier,
|
|
212
|
+
adaptation,
|
|
164
213
|
}) {
|
|
165
214
|
assert.defined(graph, 'graph');
|
|
166
215
|
assert.isNonNegativeInteger(multiplier, 'multiplier');
|
|
216
|
+
assert.isNonNegativeInteger(adaptation, 'adaptation');
|
|
167
217
|
|
|
168
218
|
const data = this.#unadapted_data;
|
|
169
219
|
const pass = graph.add("unadapted", data, this.#execute_unadapted);
|
|
170
220
|
|
|
171
221
|
data.output = pass.write(multiplier);
|
|
222
|
+
data.adaptation = pass.write(adaptation);
|
|
223
|
+
|
|
224
|
+
const written = this.#written;
|
|
172
225
|
|
|
173
|
-
|
|
226
|
+
written.multiplier = data.output;
|
|
227
|
+
written.adaptation = data.adaptation;
|
|
228
|
+
|
|
229
|
+
return written;
|
|
174
230
|
}
|
|
175
231
|
|
|
176
232
|
/**
|
|
@@ -186,26 +242,32 @@ export class GPUCameraExposureManager {
|
|
|
186
242
|
|
|
187
243
|
// compensation is in f-stops: each stop doubles/halves brightness
|
|
188
244
|
this.#unadapted_value.value = Math.pow(2, this.exposure_compensation);
|
|
245
|
+
this.#unadapted_adaptation.value = MIDDLE_GREY / this.#unadapted_value.value;
|
|
189
246
|
|
|
190
247
|
// in the command stream, so a pass recorded ahead of this one still reads the last frame's factor
|
|
191
248
|
encoder.writeValueBuffer(resources.get(data.output), 0, F32_CONTAINER_STRUCT, this.#unadapted_value);
|
|
249
|
+
encoder.writeValueBuffer(resources.get(data.adaptation), 0, F32_CONTAINER_STRUCT, this.#unadapted_adaptation);
|
|
192
250
|
}
|
|
193
251
|
|
|
194
252
|
/**
|
|
195
253
|
* This frame's factor metered from `input_color`: the luminance adapted toward the frame's, from the last
|
|
196
|
-
* frame's, by the adaptation speeds; its factor is middle grey over it, times 2^{@link exposure_compensation}.
|
|
254
|
+
* frame's, by the adaptation speeds; its factor is middle grey over it, times 2^{@link exposure_compensation}. Its
|
|
255
|
+
* adaptation is that adapted luminance, without the compensation.
|
|
197
256
|
*
|
|
198
257
|
* @param {Object} options
|
|
199
258
|
* @param {FrameGraph} options.graph
|
|
200
259
|
* @param {number} options.input_color
|
|
201
260
|
* @param {number} options.multiplier the graph handle of {@link multiplier}, imported into `graph`
|
|
261
|
+
* @param {number} options.adaptation the graph handle of {@link adaptation}, imported into `graph`
|
|
202
262
|
* @param {number} [options.time_delta_seconds]
|
|
203
|
-
* @return {number} the
|
|
263
|
+
* @return {{multiplier: number, adaptation: number}} the handles of {@link multiplier} and {@link adaptation}
|
|
264
|
+
* with this frame's written; the object is reused by the next call
|
|
204
265
|
*/
|
|
205
266
|
update({
|
|
206
267
|
input_color,
|
|
207
268
|
graph,
|
|
208
269
|
multiplier,
|
|
270
|
+
adaptation,
|
|
209
271
|
time_delta_seconds = 0.01666,
|
|
210
272
|
}) {
|
|
211
273
|
|
|
@@ -219,6 +281,7 @@ export class GPUCameraExposureManager {
|
|
|
219
281
|
|
|
220
282
|
assert.defined(graph, 'graph');
|
|
221
283
|
assert.isNonNegativeInteger(multiplier, 'multiplier');
|
|
284
|
+
assert.isNonNegativeInteger(adaptation, 'adaptation');
|
|
222
285
|
assert.isNumber(time_delta_seconds, 'time_delta_seconds');
|
|
223
286
|
assert.greaterThanOrEqual(time_delta_seconds, 0, 'time_delta_seconds');
|
|
224
287
|
|
|
@@ -249,8 +312,14 @@ export class GPUCameraExposureManager {
|
|
|
249
312
|
adapt_data.previous = adapt_pass.read(graph_import_buffer(graph, exposure_buffer_previous.buffer, "previous adapted luminance"));
|
|
250
313
|
adapt_data.adapted = adapt_pass.write(graph_import_buffer(graph, exposure_buffer_current.buffer, "adapted luminance"));
|
|
251
314
|
adapt_data.out_multiplier = adapt_pass.write(multiplier);
|
|
315
|
+
adapt_data.out_adaptation = adapt_pass.write(adaptation);
|
|
316
|
+
|
|
317
|
+
const written = this.#written;
|
|
318
|
+
|
|
319
|
+
written.multiplier = adapt_data.out_multiplier;
|
|
320
|
+
written.adaptation = adapt_data.out_adaptation;
|
|
252
321
|
|
|
253
|
-
return
|
|
322
|
+
return written;
|
|
254
323
|
}
|
|
255
324
|
|
|
256
325
|
/**
|
|
@@ -319,6 +388,7 @@ export class GPUCameraExposureManager {
|
|
|
319
388
|
bindings.previous = resources.get(data.previous);
|
|
320
389
|
bindings.adapted = resources.get(data.adapted);
|
|
321
390
|
bindings.out_multiplier = resources.get(data.out_multiplier);
|
|
391
|
+
bindings.out_adaptation = resources.get(data.out_adaptation);
|
|
322
392
|
|
|
323
393
|
shader_autoexposure_adapt.dispatch({
|
|
324
394
|
encoder: context.encoder,
|