@woosh/meep-engine 3.60.3 → 3.60.5
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 +2602 -0
- package/CONTRIBUTING.md +7 -0
- package/MIGRATION_2_TO_3.md +136 -0
- package/SECURITY.md +4 -0
- package/editor/EditorCameraNavigation.d.ts +2 -1
- package/editor/EditorCameraNavigation.d.ts.map +1 -1
- package/editor/EditorCameraNavigation.js +51 -57
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +3 -0
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +6 -0
- package/package.json +6 -2
- package/src/engine/EngineHarness.d.ts +3 -9
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +6 -8
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
- package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +1 -2
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts +14 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts.map +1 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.js +22 -0
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +19 -3
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +31 -4
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +1 -1
- package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +8 -0
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +5 -5
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +1 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +6 -6
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +731 -734
- package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
- package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
- package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +10 -0
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +1 -1
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -1
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
- package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +2 -2
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- 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 +16 -2
- package/src/shade/playground/vgeo_scene/README.md +1 -1
- package/src/shade/playground/water_refraction/README.md +5 -6
- package/src/shade/playground/water_refraction/index.html +1 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +7 -5
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +4 -6
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +34 -36
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +162 -163
- package/src/shade/renderer/atmosphere/compute_mie_absorption.d.ts +1 -1
- package/src/shade/renderer/atmosphere/compute_mie_absorption.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_EARTH.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_PARAMETERS_STRUCT.js +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +164 -164
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +4 -4
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +4 -4
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +2 -2
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.js +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts +4 -5
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +6 -7
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +2 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +22 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +4 -4
- 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 +50 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +6 -0
- 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 +7 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.js +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -0
- 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 +20 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts +18 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.js +42 -0
- 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 +5 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +13 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts +52 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.js +250 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
- package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
- package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
- package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts +39 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.js +119 -0
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +15 -7
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/execute_filter_environment_map.js +66 -83
- package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/graph_filter_environment_map.js +15 -6
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.js +111 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.js +128 -0
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +0 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -3
- package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.js +1 -3
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts +5 -6
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js +9 -10
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +48 -49
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +12 -16
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +246 -246
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +1 -2
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +34 -35
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.js +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_compute_extinction.js +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.js +1 -1
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +3 -3
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +3 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +4 -4
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +5 -5
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +1 -2
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +1 -2
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts +14 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +19 -6
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts +10 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +14 -6
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.js +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts +2 -3
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.js +7 -8
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.d.ts +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.js +12 -12
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +2 -2
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/VSMPageManager.js +3 -4
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +22 -13
- package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water_avboit.js +7 -7
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +0 -19
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +2 -52
- package/editor/REWORK_PLAN_2026_08.md +0 -692
- package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
- package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
- package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
- package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
- package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
- package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
- package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
- package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
- package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
- package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
- package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
- package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
- package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
- package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
- package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
- package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
- package/src/REVIEW_2026_08_06/adv-core.md +0 -511
- package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
- package/src/REVIEW_2026_08_06/adv-view.md +0 -446
- package/src/REVIEW_2026_08_06/api-core.md +0 -296
- package/src/REVIEW_2026_08_06/api-engine.md +0 -195
- package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
- package/src/REVIEW_2026_08_06/core-binary.md +0 -348
- package/src/REVIEW_2026_08_06/core-collection.md +0 -376
- package/src/REVIEW_2026_08_06/core-math.md +0 -221
- package/src/REVIEW_2026_08_06/core-process.md +0 -266
- package/src/REVIEW_2026_08_06/core-science.md +0 -223
- package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
- package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
- package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
- package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
- package/src/REVIEW_2026_08_06/engine-input.md +0 -197
- package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
- package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
- package/src/REVIEW_2026_08_06/generation.md +0 -176
- package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
- package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
- package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
- package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
- package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
- package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
- package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
- package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
- package/src/REVIEW_2026_08_06/view.md +0 -667
- package/src/REVIEW_2026_08_06.md +0 -610
- package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
- package/src/core/bvh2/bvh3/NOTES.md +0 -2
- package/src/core/bvh8/NOTES.md +0 -63
- package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
- package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
- package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
- package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
- package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
- package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
- package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
- package/src/core/geom/3d/gjk/NOTES.md +0 -8
- package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
- package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
- package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
- package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
- package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
- package/src/engine/REVIEW_2026_07_03.md +0 -211
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
- package/src/engine/control/first-person/DESIGN.md +0 -658
- package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
- package/src/engine/control/first-person/TODO.md +0 -160
- package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
- package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
- package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
- package/src/engine/ecs/ik/PLAN.md +0 -179
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
- package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
- package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
- package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
- package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
- package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
- package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
- package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
- package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
- package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
- package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
- package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
- package/src/engine/network/CONGESTION_CONTROL.md +0 -87
- package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
- package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
- package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
- package/src/engine/physics/cloth/PLAN.md +0 -3056
- package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
- package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
- package/src/engine/physics/fluid/solver/NOTES.md +0 -46
- package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
- package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
- package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
- package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
- package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
- package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
- package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
- package/src/format/image/avif/DECISIONS.md +0 -545
- package/src/format/image/jpeg/NOTES.md +0 -3
- package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
- package/src/generation/COORDINATES.md +0 -54
- package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
- package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
- package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
- package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
- package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
- package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
- package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
- package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
- package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
- package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
- package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
- package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
- package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
- package/src/shade/RENDERER_CONTRACT.md +0 -697
- package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
- package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
- package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
- package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
- package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
- package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
- package/src/shade/renderer/NOTES.md +0 -78
- package/src/shade/renderer/PLAN.md +0 -8
- package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
- package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
- package/src/shade/renderer/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
- package/src/shade/renderer/camera/orbital/README.md +0 -81
- package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
- package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/index.js +0 -9
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
- package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
- package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
- package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -483
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
- package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
- package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -536
- package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4225
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
- package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
- package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
- package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
- package/src/shade/renderer/hiz/NOTES.md +0 -3
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
- package/src/shade/renderer/light/cluster/NOTES.md +0 -11
- package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
- package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts +0 -13
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +0 -1
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.js +0 -198
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
- package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
- package/src/shade/renderer/particles/DESIGN.md +0 -1011
- package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -283
- package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
- package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
- package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
- package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/nss/NOTES.md +0 -339
- package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
- package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
- package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
- package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
- package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
- package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
- package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
- package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
- package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -394
- package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -160
- package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
- package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
- package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
- package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
- package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
- package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -932
- package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
- package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
- package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
- package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
- package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
- package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
- package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
- package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
- package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
- package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -4
- package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
- package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
- package/src/shade/wgsl/NOTES.md +0 -4
- package/src/view/elements/progress/segmented/segment_frame_transform.d.ts +0 -15
- package/src/view/elements/progress/segmented/segment_frame_transform.d.ts.map +0 -1
- package/src/view/elements/progress/segmented/segment_frame_transform.js +0 -69
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
# Double-Rate `f16` Shading (`shader-f16` / `enable f16;`) — Performance & Precision Proposal
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-10-24 (Updated 2026-10-26)
|
|
4
|
-
**Status:** In Progress — `INFRA-1`, `INFRA-3`, `INFRA-4`, `INFRA-5`, `INFRA-6` (`a7e88413f`..`b637acaef`) and `BUG-1`..`BUG-5` (`eecb70112`..`a86cf8617`) landed on `master`; `INFRA-2` (device floor policy) and shader conversions (§4–§7) pending
|
|
5
|
-
**Scope:** `packages/meep-engine/src/shade/` (`device/`, `wgsl/`, `renderer/`)
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 0. Executive Summary
|
|
10
|
-
|
|
11
|
-
Every WGSL shader in Shade currently executes its arithmetic and declares its `var<workgroup>` shared memory in 32-bit precision (`f32`, `i32`, `u32`). Where 16-bit floats appear inside shaders today — in Depth of Field shared memory (`shader_dof_raymarch_compute.js`), SSR prefilter shared memory (`chunk_ffx_dnsr_group_shared_memory.js`), Brick4 v1 probes, SHARC voxels (`chunk_sharc_voxel_encode.js`), and LPV depth borders (`shader_lpv_atlas_border_read.js`) — they are packed and unpacked manually into `u32` words via `pack2x16float` / `unpack2x16float` or software bit-manipulation (`chunk_encode_f16.js` / `chunk_decode_f16.js`). Meanwhile, the majority of the renderer's color, lighting, volumetric, GI, velocity, and Hi-Z textures are already backed by 16-bit float formats (`rgba16float`, `rg16float`, `r16float`).
|
|
12
|
-
|
|
13
|
-
Enabling the WebGPU `shader-f16` feature (`enable f16;` in WGSL) unlocks native 16-bit floating-point scalars (`f16`), vectors (`vec2<f16>` / `vec2h`, `vec3<f16>` / `vec3h`, `vec4<f16>` / `vec4h`), and matrices (`matNxM<f16>`) across registers, `var<workgroup>` shared memory, `var<storage>` buffers, varying interpolants, and subgroup operations.
|
|
14
|
-
|
|
15
|
-
### Key Findings of This Investigation
|
|
16
|
-
|
|
17
|
-
1. **Blocking Infrastructure Bugs Discovered & Status (§2):** Although `WebGPUExtensionType.ShaderF16` (`"shader-f16"`) and `WEBGPU_WGSL_PRIMITIVE_TYPES` (`f16`, `vec2h`–`vec4h`, `mat2x2h`–`mat4x4h`) already existed in the codebase, six prerequisite defects prevented shaders from compiling, validating, or emulating `ShaderF16` accurately. **Five of the six (`INFRA-1`, `INFRA-3`, `INFRA-4`, `INFRA-5`, `INFRA-6`) are now fixed on `master` (`a7e88413f`..`b637acaef`)**:
|
|
18
|
-
- ✅ **Fixed (`INFRA-1`, `INFRA-5`):** `ShaderDescriptor.compile()` (`ShaderDescriptor.js`) previously interpolated the WebGPU feature name verbatim as `enable shader-f16;` (a WGSL syntax error); it now maps `WebGPUExtensionType.ShaderF16` (`"shader-f16"`) to `enable f16;` via `wgsl_enable_extension()`, auto-attaches `ShaderF16` when structs/buffers transitively contain `f16` (`type_has_f16.js`), and `validate_wgsl_source.js` enforces an `unenabled-f16` rule.
|
|
19
|
-
- ⏳ **Pending (`INFRA-2`):** `Renderer.initialize()` (`Renderer.js:1575-1600`), `SHADE_DEVICE_FLOOR`, and `SoftwareGPUDevice` do not yet request/expose `"shader-f16"` on the device.
|
|
20
|
-
- ✅ **Fixed (`INFRA-3`, `INFRA-4`, `INFRA-6`):** The WGSL CPU emulator (`WGSLJavaScriptCompiler.js` / `WGSLLanguageCore.js`) previously ran scalar `f16` arithmetic in 64-bit JS floats (`f64`) and `dot`/`length` on `vecNh` in `f32`, hiding `f16` overflow (`> 65504`) and underflow (`< 6.10e-5`) from unit tests. It now emulates IEEE 754 `f16` rounding across scalar ops, vector reductions, `matCxRh` products, `pack2x16float`/`unpack2x16float`, packed `bitcast`, and compile-time `FLOAT16_MAX` (`65504`) range checks, and GPU buffer serde (`write_gpu_typed_buffer.js` / `read_gpu_typed_buffer.js`) now supports `f16`, `vecNh`, and `matCxRh`/`matCxRf`.
|
|
21
|
-
2. **Five Live `rgba16float` (`+Inf` → `NaN`) Bugs Found & Fixed in Existing `f32` Shaders (§3):** Because `f32` shaders write unbounded HDR values into `rgba16float` targets, any value in `(F16_MAX, F32_MAX]` saturates to `+Inf` on hardware store. We found and fixed (`eecb70112`..`a86cf8617`) five places where those `+Inf` texels or unguarded denominators entered `rgb / (1 + luma)` (`Inf / Inf = NaN`), Karis weighting `rgb * (1 / (1 + luma))` (`Inf * 0 = NaN`), or `rgb / (1 - luma)`, which previously poisoned temporal history and mip pyramids in **Volumetric TAA**, **NSS**, **Bloom**, **SSR**, and **TAA inverse tonemapping**.
|
|
22
|
-
3. **Where `shader-f16` Delivers the Largest Real-World Wins (§4–§5):**
|
|
23
|
-
- **Compute Convolution + Shared Memory Tile (`shader_nss_conv_layer.js`)**: Runs **18 dispatches per frame**. Using `vec4h` dot products plus an 800-byte `var<workgroup> shared_in: array<vec4<f16>, 100>` tile cache cuts 3D texture loads by **5.76×** (`144 → 25` loads/thread) and runs all `576` MACs/thread at double rate.
|
|
24
|
-
- **Eliminating Inner-Loop `unpack2x16float` Bottlenecks (`shader_dof_raymarch_compute.js`, `shader_dof_slice_compute.js`, `chunk_ffx_dnsr_group_shared_memory.js`)**: Replacing `var<workgroup> lds_coc: array<u32, 3872>` with `array<f16, 7744>` (same `15,488 B` footprint) removes up to **2,304 bit-shift + `unpack2x16float` + `select` sequences per pixel** in DoF raymarching (`DOF_CONFIG.js:158` noted the compute shader measured slower than fragment for this reason).
|
|
25
|
-
- **Halving `var<workgroup>` Shared Memory at the 16 KiB Limit (`shader_fluid_mac_curl.js`, `chunk_fft128x4_inverse_workgroup.js`, `shader_project_environment_sh.js`)**: `shader_fluid_mac_curl` currently uses `16,224 B / 16,384 B` of LDS (`99%` of the WebGPU limit, capping occupancy at 1 workgroup/SIMD). Moving its curl tiles to `f16` cuts LDS to `8,112 B`, doubling occupancy.
|
|
26
|
-
- **Cutting Live VGPRs by 30–50% in Register-Starved Shaders (`shader_brick4_indirect_lighting.js`, `shader_deferred_main.js`, `shader_volumetrics_build_lighting.js`, `chunk_forward_shade_standard_fragment.js`)**: Holding `SH3CoefficientsColor` (`array<vec3h, 9>`, saving 54 VGPRs across 4 probes in Brick4), `MaterialShadingInfo` (saving 14 VGPRs across 128-light loops), and volumetric media/multiscattering state in `f16` directly increases wave occupancy to hide ray-query and texture latency.
|
|
27
|
-
4. **Where `f16` Must Never Be Used (§4.5 & §6):**
|
|
28
|
-
- **GGX NDF (`chunk_D_GGX.js`)**: For any `roughness < 0.148` (`a2 < 4.88e-4`, 1 ULP below `1.0h`), `a2 - 1.0h` rounds to `-1.0h`, causing `denom = 0.0h` and **`0 / 0 = NaN` at the center of every specular highlight**, while peak $D_{\text{GGX}}$ overflows `65504` for `roughness < 0.047`.
|
|
29
|
-
- **MBOIT Moments, LPV/TAA/SSR Variance Second Moments (`m2 - m1 * m1`), ReSTIR Reservoir `weightSum`/`targetPdf`, Atmosphere Planetary Geometry (`R = 6,378,000 m`), Fluid Multigrid Pressure V-Cycles, Water CDLOD/Phase, and Shadow/Hi-Z Depth Comparisons** all suffer catastrophic cancellation, underflow, or overflow in `f16` and must remain `f32`.
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## 1. Hardware Mechanics of `shader-f16` & Device Policy
|
|
34
|
-
|
|
35
|
-
### 1.1 How GPUs Execute `f16` (and When "Double-Rate" Actually Happens)
|
|
36
|
-
|
|
37
|
-
IEEE 754 binary16 (`f16`) has **1 sign bit, 5 exponent bits, and 10 mantissa bits** (11 significand bits):
|
|
38
|
-
$$\text{Normal range} = [2^{-14}, (2 - 2^{-10})\times 2^{15}] \approx [6.1035 \times 10^{-5},\ 65504.0], \qquad \text{ULP}(1.0) = 2^{-10} \approx 9.7656 \times 10^{-4}$$
|
|
39
|
-
$$\text{Subnormal range} = [2^{-24}, 2^{-14}) \approx [5.9605 \times 10^{-8},\ 6.1035 \times 10^{-5})$$
|
|
40
|
-
|
|
41
|
-
Converting `f32` code to `f16` improves GPU performance through **four distinct hardware mechanisms**, each with specific architectural rules:
|
|
42
|
-
|
|
43
|
-
| Mechanism | Hardware Reality Across Architectures (RDNA2/3/4, Ada/Ampere, Intel Xe/Gen12, Apple M-Series) | Pitfall that Negates the Win |
|
|
44
|
-
|---|---|---|
|
|
45
|
-
| **1. Double-Rate Packed SIMD ALU (`2× ops/clk`)** | On AMD RDNA (`v_pk_fma_f16`, `v_pk_add_f16`, `v_pk_mul_f16`, `v_pk_max_f16`, `v_pk_min_f16`), NVIDIA Turing/Ampere/Ada (`HFMA2`, `HADD2`, `HMUL2`), Intel Xe, and Apple Silicon, **2-wide packed `f16` (`vec2h` / `vec4h`) executes at 2× the throughput of `f32`**. | **Transcendentals (`sin`, `cos`, `exp2`, `log2`, `sqrt`, `inverseSqrt`, `rcp`)** run on the Special Function Unit (SFU) at **1× quarter-rate** on RDNA/NVIDIA — they do *not* run at double rate. Unpaired scalar `f16` ops may also issue at 1× rate on RDNA2 if the compiler cannot pack two independent ops into `v_pk_*_f16`. |
|
|
46
|
-
| **2. VGPR Packing & Wave Occupancy (`2× f16 per 32-bit VGPR`)** | Two `f16` scalars or one `vec2h` occupy a single 32-bit VGPR (`vec3h` and `vec4h` occupy two 32-bit VGPRs instead of three/four). In shaders limited by register file capacity (`shader_deferred_main`, `shader_brick4_indirect_lighting`, `shader_volumetrics_build_lighting`), cutting VGPRs from e.g. 96 to 64 raises occupancy from 4 to 8 waves/SIMD on RDNA, hiding memory and ray-tracing latency. | **Ping-ponging `f32 ↔ f16` inside a loop** forces the compiler to keep both the `f32` and `f16` values live simultaneously and emits `v_cvt_f16_f32` / `v_cvt_f32_f16` instructions on every iteration, increasing instruction count *and* register pressure. |
|
|
47
|
-
| **3. `var<workgroup>` Shared Memory (LDS) Capacity & Native 16-bit Access** | WebGPU caps `maxComputeWorkgroupStorageSize` at **16,384 bytes (16 KiB)** on the device floor. Using `f16` / `vec2h` / `vec4h` in `var<workgroup>` either **halves LDS usage** (allowing more concurrent workgroups per CU/SM) or **eliminates manual `pack2x16float`/`unpack2x16float` + bit-shift ALU** via native `ds_read_u16` / `ds_read_b64` instructions. | Odd-stride scalar `f16` access across threads can cause 32-bit LDS bank conflicts if threads do not access contiguous pairs or `vec2h`/`vec4h` aligned elements. |
|
|
48
|
-
| **4. Bandwidth & Varying Interpolation** | Reading/writing `vec2h`/`vec4h` in storage buffers halves memory traffic; using `vec3h`/`vec4h` on vertex-to-fragment outputs halves parameter cache / varying interpolation footprint (`v_interp_p10_f16` / `v_interp_p2_f16`). | Unaligned `vec3h` in structs has alignment 8 and size 6 (`WEBGPU_WGSL_PRIMITIVE_TYPES.js:40`), wasting 2 bytes unless paired with a scalar `f16` into `vec4h`. |
|
|
49
|
-
|
|
50
|
-
### 1.2 Device Floor Policy: Required Floor vs. Optional Feature
|
|
51
|
-
|
|
52
|
-
Per [`RENDERER_CONTRACT.md` §2](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/RENDERER_CONTRACT.md#L45-L75):
|
|
53
|
-
> *"The renderer requires a WebGPU device that meets a fixed floor. There is no feature detection beyond it and no branch that produces a lesser frame."*
|
|
54
|
-
|
|
55
|
-
**Hardware support for `shader-f16`**:
|
|
56
|
-
- Supported on **100% of desktop and laptop GPUs capable of running Shade's existing floor** (`indirect-first-instance`, `float32-blendable`, `texture-formats-tier1`): AMD GCN 3+ / Vega / RDNA 1–4, NVIDIA Pascal (SM60+) / Turing / Ampere / Ada / Blackwell, Intel Gen9+ / Iris Xe / Arc, Apple M1–M4 / A14+, and Qualcomm Adreno 600+.
|
|
57
|
-
- The only environment where `shader-f16` may be absent is an older Dawn/wgpu software adapter or a stripped-down test mock (`SoftwareGPUDevice`).
|
|
58
|
-
|
|
59
|
-
**Recommendation on Device Policy:**
|
|
60
|
-
- **Option A (Recommended, matches `RENDERER_CONTRACT.md` §2):** Add `WebGPUExtensionType.ShaderF16` to [`SHADE_DEVICE_FLOOR.features`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/device/SHADE_DEVICE_FLOOR.js#L19-L26) and [`SoftwareGPUDevice.js` `SUPPORTED_OPTIONAL_FEATURES`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/device/mock/SoftwareGPUDevice.js#L206-L226). Every shader that benefits from `enable f16;` uses it unconditionally with zero permutation bloat.
|
|
61
|
-
- **Option B (Conservative transitional path, matches `subgroups`):** Add `WebGPUExtensionType.ShaderF16` to `optional_desired` in [`Renderer.js:1578`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/Renderer.js#L1578-L1593) and gate `f16` chunks behind a `ShaderSwitch.bool('shader f16')` ([`SHADER_SWITCH_PROPOSAL_2026_10_16.md`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md)). Because Option B doubles the chunk maintenance surface for every converted shader and no target GPU lacks `shader-f16`, **Option A is strongly preferred**.
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 2. P0 Prerequisite Infrastructure Defects to Fix First
|
|
66
|
-
|
|
67
|
-
Before any shader can use `enable f16;`, **six defects in the compiler, device initialization, emulator, validator, and buffer serializer** were identified. **Five (`INFRA-1`, `INFRA-3`, `INFRA-4`, `INFRA-5`, `INFRA-6`) are now resolved on `master`; only `INFRA-2` remains open:**
|
|
68
|
-
|
|
69
|
-
| ID | Status | File & Lines | Defect Found | Resolution / Required Fix |
|
|
70
|
-
|---|---|---|---|---|
|
|
71
|
-
| **INFRA-1** | **✅ Landed** (`a7e88413f`) | [`ShaderDescriptor.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/ShaderDescriptor.js), [`WebGPUExtensionType.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/descriptor/WebGPUExtensionType.js), [`type_has_f16.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/type_has_f16.js), [`WebGPUStruct.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/WebGPUStruct.js), [`ShaderResourceSetDescriptor.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js), [`WebGPUArray.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/WebGPUArray.js) | `WebGPUExtensionType.ShaderF16` is `"shader-f16"` (the WebGPU `GPUFeatureName`). `ShaderDescriptor.compile()` emitted `enable ${extension};` → **`enable shader-f16;`**, which is invalid WGSL! For `subgroups`, the `GPUFeatureName` (`"subgroups"`) and WGSL enable-extension (`subgroups`) happen to match; for `shader-f16`, the WGSL directive is **`enable f16;`** ([WGSL §1.4.1.1](https://www.w3.org/TR/WGSL/#extension-f16)). | Added `wgsl_enable_extension(extension)` in `WebGPUExtensionType.js` (`{ [ShaderF16]: "f16", [Subgroups]: "subgroups" }`); updated `ShaderDescriptor.compile()` to emit `enable ${wgsl_enable_extension(extension)};` while keeping `#features` as `GPUFeatureName[]` (with lazy compilation in `get features()` and `validate_gpu_features()`). Also added `type_has_f16()` so `WebGPUStruct` and `ShaderResourceSetDescriptor` automatically attach `ShaderF16` when a struct or buffer/immediate resource transitively contains `f16` types, plus `WebGPUArray.f16` / `vec2h` / `vec4h`. |
|
|
72
|
-
| **INFRA-2** | **⏳ Pending** | [`SHADE_DEVICE_FLOOR.js:19-26`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/device/SHADE_DEVICE_FLOOR.js#L19-L26), [`Renderer.js:1575-1600`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/Renderer.js#L1575-L1600), [`SoftwareGPUDevice.js:206-226`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/device/mock/SoftwareGPUDevice.js#L206-L226) | `WebGPUExtensionType.ShaderF16` is never requested in `Renderer.initialize()` and is rejected by `SoftwareGPUDevice`. | Add `WebGPUExtensionType.ShaderF16` to `SHADE_DEVICE_FLOOR.features` (or `optional_desired` in `Renderer.js`) and to `SUPPORTED_OPTIONAL_FEATURES` in `SoftwareGPUDevice.js`. |
|
|
73
|
-
| **INFRA-3** | **✅ Landed** (`87b60069f`, `b637acaef`) | [`WGSLJavaScriptCompiler.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js), [`WGSLLanguageCore.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/WGSLLanguageCore.js), [`FLOAT16_MAX.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/core/binary/FLOAT16_MAX.js) | 1. Scalar `f32` ops routed through `F32_SCALAR_OP` (`add_f32`, `sub_f32`, `mul_f32`, `div_f32`), but **scalar `f16` ops routed through raw `f64` JS numbers** (`16000.0h * 8.0h` → `128000` instead of `+Infinity`; `1e-3h * 1e-3h` → `1e-6` instead of underflowing).<br>2. `WGSLLanguageCore.dot()` and `length()` accumulated via `Math.fround` (`f32`) even when given `Float16Array` (`vec2h`/`vec3h`/`vec4h`), so `length(vec3h(300.0h, 0.0h, 0.0h))` returned `300` instead of overflowing `300^2 = 90000 > 65504` to `+Infinity`.<br>3. `convertAbstract(operand, 'f16')` omitted the `Math.abs(operand.value) <= 65504` compile-time range check that `f32` performed. | 1. Added `round_f16`, `add_f16`, `sub_f16`, `mul_f16`, `div_f16`, and `quantizeToF16` in `WGSLLanguageCore.js`; routed `isScalarF16` binary ops, compound assignments (`+=`, `-=`, `*=`, `/=`, `%=`), and scalar `f16` builtin returns through `f16` rounding.<br>2. Updated `dot()`, `length()`, `distance()`, `cross()`, `determinant()`, `reflect()`, `refract()`, and `faceForward()` to round products and partial sums in `f16` when operating on `Float16Array`.<br>3. Enforced `FLOAT16_MAX` (`65504`) range checks on `h` decimal & hex float literals (`parseWgslHexFloat`), folded abstract binary ops, and converted abstract operands across `let`/`var`/`const` declarations, assignments, `return`, `for`-loop updates, and function/struct/array call arguments. |
|
|
74
|
-
| **INFRA-4** | **✅ Landed** (`87b60069f`) | [`WGSLLanguageCore.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/WGSLLanguageCore.js) & [`WGSLJavaScriptCompiler.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js) | 1. Matrix-vector and matrix-matrix multiply helpers existed only for `f` (`m2x2f_multiply_v2f`, `m3x3f_multiply_v3f`, etc.); multiplying `mat3x3<f16> * vec3<f16>` threw `TypeError: wgsl.m3x3h_multiply_v3h is not a function`.<br>2. `pack2x16float` and `unpack2x16float` were missing from `WGSLLanguageCore.js`.<br>3. `WGSLLanguageCore.bitcast` did element-wise conversion on `vec2<f16>` ↔ `u32` and `vec4<f16>` ↔ `vec2<u32>` instead of reinterpreting the underlying 4 or 8 bytes. | 1. Added `m2x2h`/`m3x3h`/`m4x4h` matrix-vector, vector-matrix, and matrix-matrix multiply helpers backed by `Float16Array` with `f16` intermediate rounding, and fixed `defaultValueForType` on `matCxRh`.<br>2. Implemented `pack2x16float` and `unpack2x16float`.<br>3. Upgraded `WGSLLanguageCore.bitcast` to support width-changing packed reinterpretation (`vec2<f16>`/`vec2h` ↔ `u32`/`i32`/`f32`, `vec4<f16>`/`vec4h` ↔ `vec2<u32>`/`vec2<i32>`/`vec2<f32>`) over a shared 16-byte `BITCAST_BUFFER`. |
|
|
75
|
-
| **INFRA-5** | **✅ Landed** (`a7e88413f`, `b637acaef`) | [`validate_wgsl_source.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/validate_wgsl_source.js) & [`chunk_wgsl_validity.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/chunk_wgsl_validity.spec.js) | A shader or chunk test that used `f16`, `vec3h`, or `1.0h` without calling `chunk.addExtension(WebGPUExtensionType.ShaderF16)` passed `validate_wgsl_source` and the emulator, then failed `createShaderModule` on a device. | Added the `unenabled-f16` rule (`F16_ENABLE_DIRECTIVE_RE`, `F16_TOKEN_RE` covering `\bf16\b`, `\b(?:vec[234]|mat[234]x[234])h\b`, and decimal/hex `h`-suffixed float literals) to `validate_wgsl_source.js` and enabled it in `chunk_wgsl_validity.spec.js`. |
|
|
76
|
-
| **INFRA-6** | **✅ Landed** (`4d349075d`, `b637acaef`) | [`write_gpu_typed_buffer.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js) & [`read_gpu_typed_buffer.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js) | `WEBGPU_WGSL_PRIMITIVE_TYPES.js` exported `f16`, `vec2h`, `vec3h`, `vec4h`, `mat2x2h`..`mat4x4h`, but `write_wgsl_type_value` and `read_wgsl_type_value` threw `Unsupported type` if a `WebGPUStruct` contained them. | Added `f16`, `vec2h`, `vec3h`, `vec4h`, and all 9 `matCxRh` + 9 `matCxRf` types (respecting 8-byte/16-byte WGSL column stride padding on `matCx3h`/`matCx3f` and struct tail padding) to `write_gpu_typed_buffer.js` and `read_gpu_typed_buffer.js`. |
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 3. Five Pre-Existing `rgba16float` (`f16` Target) Bugs Uncovered
|
|
81
|
-
|
|
82
|
-
Even while shaders run in `f32`, writing an `f32` value $> 65504.0$ (`F16_MAX`) into an `rgba16float` texture saturates that channel to **`+Inf`**. Our audit and subsequent adversarial review uncovered **five live bugs** where missing `F16_MAX` clamps or missing finite guards turned `+Inf` into **`NaN`**, corrupting temporal histories and mip pyramids. **All five (`BUG-1`..`BUG-5`) are now resolved on `master` (`eecb70112`..`a86cf8617`) using imported `F16_MAX_DEFINITION` / `F32_MAX_DEFINITION` (`FLOAT16_MAX` in specs):**
|
|
83
|
-
|
|
84
|
-
| Bug ID | Status | File & Lines | Mechanism of Defect | Visual Artifact Produced | Resolution / Landed Fix |
|
|
85
|
-
|---|---|---|---|---|---|
|
|
86
|
-
| **BUG-1** | **✅ Landed** (`eecb70112`) | [`shader_volumetrics_build_lighting.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js) & [`shader_volumetrics_taa.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js) | `shader_volumetrics_build_lighting.js` and `shader_volumetrics_taa.js` guarded against `NaN`/`Inf` using `abs(...) <= vec4f(F32_MAX)`. Any finite `f32` radiance in `(F16_MAX, F32_MAX]` (or variance-box expansion `mean + gamma * std_dev > F16_MAX` in `shader_volumetrics_taa`) passed the `F32_MAX` check and was converted to **`+Inf` by hardware `textureStore` into `rgba16float`**. Next frame, `t_history` held `+Inf` and `mix` / `get_std_dev4` evaluated `Inf - Inf = NaN`. | Growing black/NaN volumetric blotches around bright local lights that persist across frames in volumetric TAA. | Imported `F16_MAX_DEFINITION` and `F32_MAX_DEFINITION`; clamped finite `lighting_raw` in `shader_volumetrics_build_lighting.js` and both `current_safe` and `final_safe` in `shader_volumetrics_taa.js` to `[vec4f(0.0), vec4f(F16_MAX)]` before `textureStore`. |
|
|
87
|
-
| **BUG-2** | **✅ Landed** (`a43cf4ed5`) | [`shader_nss_preprocess.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js), [`chunk_nss_luma_derivative.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.js), [`shader_nss_postprocess.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js) | `nss_tonemap_exposure(rgb)` in `shader_nss_preprocess.js` and `nss_luma_derivative(current_rgb, history_rgb)` in `chunk_nss_luma_derivative.js` computed `scaled / (1.0 + m)` and `lc / (1.0 + lc)` without sanitizing `+Inf`/`NaN` against `F16_MAX`, producing `Inf / Inf = NaN` in `tTensor` slices `z=1` and `z=2, .a`. | Permanent `NaN` corruption injected into the 18-layer U-Net tensor and `tFeedback` temporal history. | Imported `F16_MAX_DEFINITION` and sanitized inputs via `select(vec3<f32>(0.0), clamp(rgb, vec3<f32>(0.0), vec3<f32>(F16_MAX)), rgb == rgb)` in both `shader_nss_preprocess.js` and `chunk_nss_luma_derivative.js` (and replaced literal `65504f` in `shader_nss_postprocess.js`). |
|
|
88
|
-
| **BUG-3** | **✅ Landed** (`5651af2e2`) | [`bloom/chunk_karis_blur4x4_sample.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.js) & [`ssr/downsample_karis.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/downsample_karis.js) | Computed `w = 1.0 / (1.0 + luma)` and `t * w` on `rgba16float` samples without clamping `t` to `F16_MAX` (`+Inf` → `w = 0.0` → `Inf * 0.0 = NaN`). In `downsample_karis.js`, `result += texel * weight` also multiplied all 4 channels where background pixels (`depth_weight = 0.0`) forced `weight = 0.0`, and `select(result, result / weight_sum, ...)` evaluated `result / 0.0` eagerly. | Large rectangular `NaN` black boxes across the 5-mip Bloom pyramid, SSR prefiltered color pyramid, and DoF firefly pass (`shader_dof_firefly_cleanup.js`). | Imported `F16_MAX_DEFINITION`; sanitized `t00..t11` (`vec3f`) in `chunk_karis_blur4x4_sample.js` and `texel` (`vec4f`) in `downsample_karis.js` to `[0.0, F16_MAX]`, and guarded `result / max(weight_sum, 1e-7)`. |
|
|
89
|
-
| **BUG-4** | **✅ Landed** (`ca0faed94`) | [`ssr_resolve_shader.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js), [`ssr_spatial_denoise_shader.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js), [`chunk_ssr_temporal_accumulate.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js) | Both `ssr_resolve_shader.js` (`abs(m2 - m1 * m1)`) and `ssr_spatial_denoise_shader.js` (`bootstrap_variance * sum_squared_weights / (sum_weight * sum_weight)`) wrote `f32` variance into `rgba16float.a` without clamping to `F16_MAX`, overflowing to `+Inf` when HDR luma deltas exceeded `256`. | `+Inf` variance in `rgba16float.a` propagated into spatial/temporal SSR denoise (`std_dev = Inf`), disabling luma edge-stopping and smearing bright specular reflections across edges. | Imported `F16_MAX_DEFINITION` and clamped variance to `[0.0, F16_MAX]` in `ssr_resolve_shader.js` and `ssr_spatial_denoise_shader.js` (and replaced literal `65504.0` in `chunk_ssr_temporal_accumulate.js`). |
|
|
90
|
-
| **BUG-5** | **✅ Landed** (`a86cf8617`) | [`chunk_taa_tonemap_inv.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.js), [`chunk_taa_tonemap.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.js), [`shader_taa.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/shader_taa.js) | `taa_tonemap_inv` computed `rgb / (1.0 - luma)` without a denominator floor or output clamp: YCoCg AABB expansion (`mean + final_sigma * std_dev`) can push `luma >= 1.0` (dividing by zero to `+Inf` or inverting bright pixels negative), and even in `f32`, `65504.0 / 65505.0` rounds up to `65535 / 65536` so `1.0 - luma = 1 / 65536` round-tripped `F16_MAX` to `65535.0 > F16_MAX` (`+Inf` in `rgba16float`). Also `shader_taa.js` only clamped `color_current_raw` with `max(vec3(0.0), ...)`, leaving the `!hasValidHistory` path unguarded against `+Inf`/`NaN`. | Specular highlights and overbright HDR neighborhoods turned into `+Inf`, negative values, or `NaN` in TAA history and bloom input. | Imported `F16_MAX_DEFINITION`; guarded `taa_tonemap_inv` with `min(vec3<f32>(F16_MAX), safe_rgb / max(1.0 - luma, 1.0 / (F16_MAX + 1.0)))`, replaced `HALF_MAX` in `chunk_taa_tonemap.js`, and clamped `color_current_raw` to `[0.0, F16_MAX]` in `shader_taa.js`. |
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## 4. Master Classification Matrix of Proposed `shader-f16` Items
|
|
95
|
-
|
|
96
|
-
Every proposed item is classified below by **Value** (`Critical`, `High`, `Medium`, `Low`), **Risk** (`Low`, `Medium`, `High`, `Extreme`), **Mechanism** (`2× ALU`, `VGPR`, `LDS Size`, `LDS Unpack`, `Bandwidth`), and **Artifact/Defect Profile**.
|
|
97
|
-
|
|
98
|
-
### 4.1 Tier 1 — High-to-Critical Value, Low Risk (Immediate Recommended Targets)
|
|
99
|
-
|
|
100
|
-
| ID | Proposed Item & Files | Mechanism | Value | Risk | Potential Artifacts / Defects & Required Mitigation |
|
|
101
|
-
|---|---|---|---|---|---|
|
|
102
|
-
| **F16-01** | **NSS Int8 U-Net Convolution (`vec4h` MACs + `var<workgroup>` `vec4h` Tile Cache)**<br>[`shader_nss_conv_layer.js:107-177`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js#L107-L177) | `LDS Size` (`800 B`) + `Bandwidth` (`-82%` 3D loads) + `2× ALU` (`576` `vec4h` dots/thread × 18 passes) | **Critical** | **Low** | **Artifact if misused:** Accumulating all 144 `dot` products in `f16` overflows or loses small bias terms (`biases` are scaled by $1/127^2 \approx 6.2 \times 10^{-5}$, right at `f16` min normal $6.10 \times 10^{-5}$), causing color bias/banding in upscaled output.<br>**Mitigation:** Cast `tInput` (`rgba16float` in $[-1,1]$) and `unpack4x8snorm(weights)` ($[-1,1]$) to `vec4h` for the 10×10 `var<workgroup>` tile and `dot(v_h, w_h)`, but accumulate the outer sum `acc`, `biases`, and `rescales` in `vec4<f32>`. |
|
|
103
|
-
| **F16-02** | **DoF Raymarch & Slice Compute Native `f16` Shared Memory**<br>[`shader_dof_raymarch_compute.js:56, 88-97, 168-170`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js#L56) & [`shader_dof_slice_compute.js:69, 81-84, 105-114`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js#L69) | `LDS Unpack` (removes 576–2,304 `unpack2x16float` + shift + `select` ops/pixel) | **Critical** | **Low** | **Artifact if misused:** Zero visual difference for `lds_coc` (`tPrefilter.a` is already `rgba16float` in $[-48, 48]$). However, if bokeh color accumulator `acc` (`L212-215`) is also moved to `vec3h`, `samp * highlight_boost * luma(samp)` ($\propto \text{samp}^2$) overflows `65504` on HDR highlights $> 256$, producing black `NaN` bokeh discs.<br>**Mitigation:** Change `var<workgroup> lds_coc` to `array<f16, 7744>` (`15,488 B`) and `s_coc` / `cover` / `shape` to `f16`; keep `hl`, `w`, `acc`, and `wsum` in `f32`. |
|
|
104
|
-
| **F16-03** | **Fluid MAC Vorticity Confinement Curl Shared Memory (`16.2 KB → 8.1 KB`)**<br>[`shader_fluid_mac_curl.js:40-44, 108-173`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js#L40-L44) & [`shader_fluid_mac_gradient.js:37`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js#L37) | `LDS Size` (`16,224 B → 8,112 B` in curl; `2,400 B → 1,200 B` in solid tile) + `VGPR` | **High** | **Low** | **Artifact if misused:** `shader_fluid_mac_curl` currently consumes `99%` of the 16 KiB workgroup limit (`L191-193`), restricting occupancy to 1 workgroup/SIMD. Vorticity confinement is an explicit turbulence boost ($\varepsilon \cdot \Delta t \cdot (\mathbf{N} \times \boldsymbol{\omega})$) where `f16` (10-bit mantissa) is indistinguishable from `f32`. In `shader_fluid_mac_gradient`, `fluid_mac_tile_solid` only stores `0.0` or `1.0`.<br>**Mitigation:** Use `f16` for `fluid_curl_u/v/w`, `fluid_curl_magnitude`, and `fluid_mac_tile_solid`. Keep `fluid_mac_tile_pressure` in `f32`. |
|
|
105
|
-
| **F16-04** | **Brick4 GI Probe Decode & SH3 Evaluation in `vec3h`**<br>[`shader_brick4_indirect_lighting.js:109-189`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.js#L109-L189), [`chunk_brick4_sh3_color_decode.js:11-43`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.js#L11-L43), [`chunk_sh3_uncompress.js:12-53`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_uncompress.js#L12-L53), [`chunk_sh3_color_get_radiance_with_GGX.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_get_radiance_with_GGX.js) | `VGPR` (`-54` 32-bit registers in Brick4 draw: 4 probes × 27 floats) + `2× ALU` (9-band `vec3h` FMA chains) | **Critical** | **Low** | **Artifact if misused:** Brick4 v2 stores DC as `rgbe9995` (max $65408 < 65504$, 9-bit mantissa, 100% lossless in `f16`) and L1/L2 as 8-bit normalized values scaled by $\le \sqrt{5} \cdot \text{DC}$. If `DC > 29294`, $\sqrt{5} \cdot \text{DC}$ can exceed `65504`.<br>**Mitigation:** Clamp `max_val` in `sh3_uncompress` to `65504.0h` (or keep `max_val` multiply at the end of the 9-band dot product!). Keep world-space cascade trilinear coordinates in `f32`. |
|
|
106
|
-
| **F16-05** | **SSR DNSR Compute Prefilter Shared Memory**<br>[`chunk_ffx_dnsr_group_shared_memory.js:10-14`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/prefilter/chunk_ffx_dnsr_group_shared_memory.js#L10-L14), [`chunk_store_in_group_shared_memory.js:18-21`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/prefilter/chunk_store_in_group_shared_memory.js#L18-L21), [`chunk_load_from_group_shared_memory.js:15-20`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/prefilter/chunk_load_from_group_shared_memory.js#L15-L20) | `LDS Unpack` (removes 30 `unpack_float16_4` calls = 120 `f16` decodes/pixel) + `2× ALU` | **High** | **Low** | **Artifact if misused:** None — the shader already packs `radiance.xyz`, `variance`, and `normal.xyz` into `f16` via `pack2x16float` in `g_ffx_dnsr_shared_0..3`.<br>**Mitigation:** Replace `g_ffx_dnsr_shared_0..3` with `array<array<vec4<f16>, 16>, 16>` (`radiance_variance`) and `array<array<vec3<f16>, 16>, 16>` (`normal`); keep `g_ffx_dnsr_shared_depth` in `f32`. |
|
|
107
|
-
| **F16-06** | **Hi-Z Single-Pass Downsampler (SPD) Shared Memory & Quad Reduction**<br>[`shader_hzb_spd.js:38, 54-96, 116-142`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/hiz/shader_hzb_spd.js#L38-L96) | `LDS Size` (`512 B → 256 B`) + `2× ALU` (`vec2h` `min`/`max` + `quadSwapX`/`Y`) | **Medium** | **Low** | **Artifact if misused:** All HZB mips (`tOut1..tOut4`) are stored in `rg16float` (`HZB_TEXTURE_FORMAT`). For mip 0 (`depth32float`), casting to `f16` *before* the first 2×2 reduction could add a second RTE rounding step.<br>**Mitigation:** Reduce mip 0's initial 4 `depth32float` samples in `vec2f`, cast to `vec2h` when writing `tOut1` and `hzb_spd_lds`, and run mips 1–4 completely in `vec2h`. Keep `uv_min + 1e-6` in `shader_hzb_reduce_mip0_clip.js:50` in `f32`. |
|
|
108
|
-
| **F16-07** | **Environment SH2 & Atmosphere Multiscatter LUT Workgroup/Subgroup Reductions**<br>[`shader_project_environment_sh.js:49-52`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/light/environment/shader_project_environment_sh.js#L49-L52) & [`shader_multiscatter_lut.js:53-54, 99-124`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/atmosphere/shader_multiscatter_lut.js#L53-L54) | `LDS Size` (`4 KB → 2 KB` in Env SH; `512 B → 256 B` in Multiscatter) + `Subgroup vec3h` | **Medium** | **Low** | **Artifact if misused:** In `shader_project_environment_sh`, each sample is multiplied by `solid_angle` ($\approx 0.002$), so a 64-lane subgroup sum is at most $0.13 \times \text{F16\_MAX}$ — guaranteed never to overflow `f16`. In `shader_multiscatter_lut`, `lum` and `f_ms` are in $[0, 1]$ and write to `rgba16float`.<br>**Mitigation:** Use `array<vec3<f16>, 64>` for `wg_sh_0..3` and `array<vec3<f16>, 16>` for `wg_lum`/`wg_fms`. |
|
|
109
|
-
| **F16-08** | **LPV Depth Border Buffer & SHARC Voxel Pack/Unpack Cleanup**<br>[`shader_lpv_atlas_border_read.js:16, 63`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/probe/octahedral/border/shader_lpv_atlas_border_read.js#L63), [`shader_lpv_atlas_paint_borders_depth.js:17, 51`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/probe/octahedral/border/shader_lpv_atlas_paint_borders_depth.js#L51), [`chunk_sharc_voxel_decode.js:10-25`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/sharc/shader/chunk_sharc_voxel_decode.js#L10-L25) | `LDS/Buffer Unpack` (removes manual `pack2x16float` / `unpack2x16float`) | **Low-Med** | **Low** | **Artifact if misused:** Zero visual change — data is already stored as packed `f16` pairs in `u32` buffers.<br>**Mitigation:** Declare `borders` as `array<vec2<f16>>` and use `bitcast<vec2<f16>>` / `bitcast<u32>` in SHARC decode/encode. |
|
|
110
|
-
| **F16-09** | **Temporal Luma/Shadow Denoiser Shared Memory**<br>[`shader_temporal_reprojection_luma.js:64, 106-142`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.js#L64) | `LDS Size` (`768 B → 384 B`) + `2× ALU` | **Low-Med** | **Low** | **Artifact if misused:** `g_mean_accumulation` stores horizontal sums of 17 binary `(0/1)` shadow hits (integers in $[0, 17]$), and `sample_neighborhood` sums 17 rows (integers in $[0, 289]$). Since `f16` represents all integers up to `2048` **exactly**, switching `g_mean_accumulation` to `f16` is 100% bit-exact.<br>**Mitigation:** Keep final `m2 - m1 * m1` variance subtraction (`L232-235`) in `f32`. |
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
### 4.2 Tier 2 — High-to-Medium Value, Medium Risk (Requires Specific Precision Guards)
|
|
115
|
-
|
|
116
|
-
| ID | Proposed Item & Files | Mechanism | Value | Risk | Potential Artifacts / Defects & Required Mitigation |
|
|
117
|
-
|---|---|---|---|---|---|
|
|
118
|
-
| **F16-10** | **Deferred & Forward `MaterialShadingInfo`, Unit Normals, & Diffuse/Fresnel BRDFs**<br>[`shader_deferred_main.js:84-128`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/deferred/shader_deferred_main.js#L84-L128), [`chunk_shade_standard_material_direct.js:50-125`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/deferred/chunk_shade_standard_material_direct.js#L50-L125), [`chunk_forward_shade_standard_fragment.js:58-195`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.js#L58-L195), [`MATERIAL_SHADING_INFO_STRUCT.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js), [`chunk_F_Schlick.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js), [`EON.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/brdf/diffuse/EON.js) | `VGPR` (`-14` 32-bit VGPRs live across 64–128 light loops & ray queries) + `2× ALU` | **Critical** | **Medium** | **Artifacts if misused:**<br>1. `EON.js:58, 66-71` uses `1e-7` and `M_FLOAT_EPS = 1e-8` denominator guards, and `chunk_forward_shade_standard_fragment.js:94` uses `max(t_diffuse.a, 1e-7)`. In `f16`, `1e-7` and `1e-8` flush to `0.0h`, causing **`0 / 0 = NaN` black pixels on grazing diffuse surfaces or zero-alpha texels**.<br>2. [`white_furnace.spec.js:473-521`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/deferred/white_furnace.spec.js#L473-L521) asserts `1e-6` (`F32_ROUNDING`) on metalness linearity in `shader_resolve_indirect_lighting`.<br>**Mitigation:** Replace `1e-7`/`1e-8` in `EON.js` and alpha un-premultiply with `1e-4h`; keep `D_GGX`, `V_GGX_SmithCorrelated`, `get_bent_noh_squared`, and `position_ws` in `f32`; either keep the final metalness lerp in `f32` or relax `white_furnace.spec.js` metalness linearity tolerance to `1e-3` (1 `f16` ULP). |
|
|
119
|
-
| **F16-11** | **Volumetric Froxel Lighting & 6-Octave Multiscattering Loop**<br>[`shader_volumetrics_build_lighting.js:55-62, 205-409`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js#L55-L62) & [`chunk_calculate_multiscattering.js:16-85`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/chunk_calculate_multiscattering.js#L16-L85) | `VGPR` (relieves documented `@workgroup_size(8,8,1)` register limit at `L55-58`) + `2× ALU` | **High** | **Medium** | **Artifacts if misused:**<br>1. In `shader_volumetrics_build_lighting.js:137-138`, `z0 * z0 * z0` ($z^3$) overflows `f16` (`65504`) for any depth **$z > 40.31\text{ m}$**, breaking froxel depth placement.<br>2. For large water droplets ($d \in [5, 50]\ \mu\text{m}$, $g > 0.9$), `chunk_phase_draine` (`chunk_calculate_multiscattering.js:61`) overflows/cancels in `f16` near $\theta = 0^\circ$, creating **bright/NaN rings around the sun in fog**.<br>**Mitigation:** Keep $z^3$ depth math, `chunk_phase_draine`, and `inScatteringSum` in `f32`; use `f16`/`vec3h` for media properties (`rgba16float`), `shadow_term`, `transmittance_atmospheric`, `scattering_decay`, `extinction_factor`, `current_g`, and `phase_dual` (for $g \le 0.8$). |
|
|
120
|
-
| **F16-12** | **Water Spectrum Column IFFT (`var<workgroup>`) & `rows` Buffer**<br>[`chunk_fft128x4_inverse_workgroup.js:19-38`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.js#L19-L38) & [`shader_water_spectrum.js:46, 78-147`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.js#L46-L147) | `LDS Size` (`4 KiB → 2 KiB`) + `Bandwidth` (`32 B → 16 B`/cell in `rows`) + `2× ALU` | **High** | **Medium** | **Artifacts if misused:**<br>1. In `shader_water_spectrum_rows`, `water_band_mode_phase` computes `fract(turns * loop_fraction)` where `turns > 2048`. In `f16`, numbers $> 2048$ have **zero fractional bits**, freezing wave motion!<br>2. Unnormalized capillary mode amplitudes in Band 0 can be $\sim 10^{-5}$ before the row IFFT, losing precision in `f16` if the row pass is converted without rescaling.<br>**Mitigation:** Keep `shader_water_spectrum_rows` (mode generation + row IFFT) in `f32`, store `rows` as `vec4h` (after the 128-point row sum has boosted amplitude by $\sim 8\times$, or scaled by $2^6$), and run `shader_water_spectrum_columns` in `vec2h` writing `rgba16float`. |
|
|
121
|
-
| **F16-13** | **XeGTAO Horizon Integration & Bent-Normal Polynomial**<br>[`fragment_shader_gtao.js:171-331`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js#L171-L331), [`fragment_shader_gtao_with_irradiance.js:154-362`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js#L154-L362), [`chunk_integrate_bent_normal_fast.js:12-32`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/gtao/chunk_integrate_bent_normal_fast.js#L12-L32) | `2× ALU` + `VGPR` | **High** | **Medium** | **Artifacts if misused:**<br>1. `viewspaceZ *= 0.99999` (`L133`) shifts depth by $10^{-5}$; in `f16`, `0.99999h` rounds to `1.0h`, **destroying self-occlusion bias and causing false AO stippling/acne**.<br>2. `sampleDelta0 = samplePos0 - position_vs` (`L255`) in `f16` causes view-space quantization banding at distance (explicitly warned in the upstream XeGTAO comment at `L255`).<br>**Mitigation:** Keep `viewspaceZ`, `position_vs`, `uv + sampleOffset`, `sampleDelta0/1`, and `sampleDist0/1` in `f32`; convert `sampleHorizonVec0/1`, `weight0/1`, `shc0/1`, `horizonCos0/1`, `fast_acos`, `iarc0/1`, and `integrate_bent_normal_fast` to `f16`/`vec2h`/`vec3h`. |
|
|
122
|
-
| **F16-14** | **TAA Resolve YCoCg Neighborhood & Catmull-Rom Color Blend**<br>[`shader_taa.js:161-235`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/shader_taa.js#L161-L235), [`chunk_taa_history_color_bounding_box_YCoCg.js:43-72`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/chunk_taa_history_color_bounding_box_YCoCg.js#L43-L72), [`chunk_color_clip_to_aabb3.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/color/chunk_color_clip_to_aabb3.js) | `VGPR` + `2× ALU` | **Medium** | **Medium** | **Artifacts if misused:**<br>1. `taa_tonemap_inv` in `f16` rounds `luma` to `1.0h` for any raw HDR luminance $> 2047$, dividing by zero (`+Inf`).<br>2. `get_std_dev3` (`abs(m2 - m1 * m1)`) in `f16` suffers 1-ULP (`5e-4`) cancellation floor on flat surfaces (`sqrt(5e-4) = 0.022`), widening the YCoCg box and **increasing ghosting**.<br>3. Catmull-Rom UV tap math in `f16` loses sub-pixel phase `f` above 1024 px, causing blocky staircase edges.<br>**Mitigation:** Keep Catmull-Rom UVs, `taa_tonemap`, `taa_tonemap_inv`, `moment2`, and `get_std_dev3` in `f32`; use `vec3h` for tonemapped YCoCg samples (in $[-1, 1]$), `color_clip_to_aabb3`, and blend weights. |
|
|
123
|
-
| **F16-15** | **Volumetric 3D TAA (`@workgroup_size(8,8,4)` = 256 threads)**<br>[`shader_volumetrics_taa.js:30-145`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js#L30-L145) & [`chunk_volumetric_history_bounding_box.js:13-79`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/taa/chunk_volumetric_history_bounding_box.js#L13-L79) | `VGPR` (256-thread workgroup) + `2× ALU` | **Medium** | **Medium** | **Artifacts if misused:**<br>1. Squaring HDR volumetric samples in `moment2 += encoded_sample * encoded_sample` (`L52`) overflows `f16` when radiance $> 255.9$, producing `NaN` AABB bounds.<br>2. Reprojection coordinate `prev_w = prev_slice / f32(res.z)` in `f16` loses sub-froxel precision, causing **exponential Z-blurring drift** (`chunk_volumetrics_taa_reproject.js:137-141`).<br>**Mitigation:** Keep `volumetrics_taa_reproject`, `moment1`, `moment2`, and `get_std_dev4` in `f32`; use `vec4h` for the 27 fetched `rgba16float` samples, `RGB_to_YCoCg4`/`YCoCg_to_RGB4`, and `color_clip_to_aabb4`. |
|
|
124
|
-
| **F16-16** | **FidelityFX RCAS Sharpening (`FsrRcasH`)**<br>[`shader_ffx_rcas.js:49-100`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js#L49-L100) | `2× ALU` + `VGPR` | **Medium** | **Medium** | **Artifacts if misused:**<br>1. Lines 86–87 add `vec3f(1e-6)` to denominators `4.0 * maxRGB` and `4.0 * minRGB - 4.0`. In `f16`, `1e-6` is subnormal and absorbed by `-4.0h`, so when `minRGB == 1.0h` (white pixel), `(1.0h - 1.0h) / (4.0h - 4.0h) = 0 / 0 = NaN` **speckles white highlights with black NaN pixels**.<br>2. If called on linear HDR $> 1.0$, `1.0 - maxRGB` goes negative.<br>**Mitigation:** Replace denominator guards with `max(4.0h * maxRGB, vec3h(1e-4h))` and `min(4.0h * minRGB - vec3h(4.0h), vec3h(-1e-4h))`, and only invoke `f16` RCAS on `[0, 1]` display-referred / tonemapped images. |
|
|
125
|
-
| **F16-17** | **SSR Spatial Denoise, Resolve BRDF Weights, & Combine**<br>[`ssr_spatial_denoise_shader.js:79-133`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js#L79-L133), [`ssr_resolve_shader.js:230-268`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js#L230-L268), [`ssr_combine_shader.js:52-134`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/ssr_combine_shader.js#L52-L134) | `VGPR` + `2× ALU` | **Medium** | **Medium** | **Artifacts if misused:**<br>1. In `ssr_resolve_shader` (`L190, 291`) and `chunk_ssr_temporal_accumulate` (`L30-35, 80`), second-moment `luma * luma` and `previous.w * old_age` (up to $65504 \times 128 = 8.38 \times 10^6$) overflow `f16`.<br>2. In `reconstruct_pdf` (`chunk_reconstruct_pdf.js`), GGX NDF overflows/cancels at low roughness in `f16`.<br>**Mitigation:** Use `vec3h`/`f16` for view-space unit normals, `ffx_dnsr_reflections_get_edge_stopping_normal_weight`, `env_brdf_approx` (`DFGApprox`), and `compute_specular_occlusion`; keep second moments, variance, and GGX PDF in `f32`. |
|
|
126
|
-
| **F16-18** | **ReSTIR DI Spatial À-Trous Denoiser & Surface Material Struct**<br>[`shader_restir_di_denoise.js:58-125`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/restir/di/shader_restir_di_denoise.js#L58-L125) & [`chunk_restir_reconstruct_surface.js:26-62`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/restir/di/chunk_restir_reconstruct_surface.js#L26-L62) | `VGPR` + `2× ALU` | **Medium** | **Low-Med** | **Artifacts if misused:** In `shader_restir_di_denoise.js:114-115`, luma and depth floors are `1e-3` (well above `f16` min normal `6.10e-5`). However, `center_depth` and `sample_depth` are linear view depths where `abs(center_depth - sample_depth)` needs `f32` precision.<br>**Mitigation:** Keep `center_depth`, `sample_depth`, `d_depth`, and all `RTXDI_Reservoir` fields in `f32`; run `center_normal`, `sample_normal`, `w_normal`, `d_luma`, `w`, and `RestirSurface.material` in `f16`/`vec3h`. |
|
|
127
|
-
| **F16-19** | **Forward Transparency Vertex-to-Fragment Varying Interpolants**<br>[`FORWARD_VERTEX_SHADER_STRUCT.js:10-12`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/forward/FORWARD_VERTEX_SHADER_STRUCT.js#L10-L12) & [`vertex_shader_chunk.js:70-79`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js#L70-L79) | `Bandwidth` (parameter cache / varying interpolation across AVBOIT & MBOIT passes) + `VGPR` | **Medium** | **Low** | **Artifacts if misused:** Converting `position_ws: vec3f` or `uv: vec2f` (for tiled UVs $> 16$) in `FORWARD_VERTEX_SHADER_STRUCT` to `f16` causes texture swimming and world-space lighting quantization.<br>**Mitigation:** Convert only `normal: vec3<f16>`, `tangent: vec4<f16>` (unit vectors in $[-1, 1]$), and `color: vec3<f16>` (vertex color in $[0, 1]$), saving 10 half-floats (20 bytes/vertex) of varying interpolation while keeping `position_ws: vec3<f32>` and `uv: vec2<f32>`. |
|
|
128
|
-
| **F16-20** | **DoF & Motion Blur Tile-Max Compute Conversion (`var<workgroup>` `f16`)**<br>[`shader_dof_tile_max.js:35-47`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_max.js#L35-L47), [`shader_dof2_tile_max.js:37-48`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_max.js#L37-L48), [`shader_motion_blur_tile_max.js:34-61`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_tile_max.js#L34-L61) | `LDS Size` (`512 B` / `1 KB`) + `2× ALU` (replaces 256 serial `textureLoad`s/thread with 1 load/thread + `subgroupMax`) | **Medium** | **Medium** | **Artifacts if misused:** In `shader_motion_blur_tile_max.js:45` and `shader_motion_blur_neighbor_max.js:41`, velocity is in **pixels** and dominance compares `mag_sq = dot(v, v)`. When motion exceeds $\sqrt{65504} = 255.9\text{ px/frame}$, `dot(v, v)` in `f16` overflows to `+Inf`, breaking `mag_sq > best_mag_sq` (`Inf > Inf` is `false`) and picking the wrong dominant velocity vector.<br>**Mitigation:** Store `vec2h` velocity in `var<workgroup>`, but compute `mag_sq = dot(vec2f(v), vec2f(v))` (or `length(vec2f(v))`) in `f32`. |
|
|
129
|
-
| **F16-21** | **Froxel & World Light Cluster Culling (`ClusterCell` Normals & `ClusterLightProxy`)**<br>[`chunk_cluster_cell.js:27-30`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/light/cluster/chunk_cluster_cell.js#L27-L30), [`CLUSTER_LIGHT_PROXY.js:17`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/light/cluster/CLUSTER_LIGHT_PROXY.js#L17), [`shader_world_cluster_assign_lights.js:43`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js#L43) | `VGPR` (`-4` VGPRs/thread for `nl,nr,nb,nt`) + `LDS Size` (`4 KB → 3 KB` in `shared_proxies`) | **Medium** | **Medium** | **Artifacts if misused:** `CLUSTER_LIGHT_PROXY_UNBOUNDED_RADIUS = 1e30`, `FLT_MAX = 3.4e38`, and squared distances `d2 = lateral^2 + depth^2` in `cluster_sphere_tile_span` (`chunk_cluster_light_proxy.js:40`) overflow `f16` whenever distance $> 255.9\text{ m}$, causing **missing or false-positive light assignment beyond 256 m**.<br>**Mitigation:** Convert only the 2D unit plane normals `C.nl, C.nr, C.nb, C.nt` (`vec2h`, components in $[-1, 1]$) and `proxy.direction_cos` (`vec4h`, unit axis + `coneCos` in $[-1, 1]$); keep `bound`, `apex_height`, `depth`, and `sphere` in `f32`. |
|
|
130
|
-
| **F16-22** | **Water Surface Detail, Wave Particle Envelope, & Coherent Optics**<br>[`chunk_water_surface_sample.js:163-202`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/surface/chunk_water_surface_sample.js#L163-L202), [`chunk_water_particle.js:284-303`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/surface/particles/chunk_water_particle.js#L284-L303), [`shader_water.js:524-612`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/shader_water.js#L524-L612), [`chunk_water_optics.js:22-77`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/optics/chunk_water_optics.js#L22-L77) | `VGPR` + `2× ALU` | **Medium** | **Medium** | **Artifacts if misused:**<br>1. `water_segment_integral` (`chunk_water_optics.js:23`) uses Taylor expansion when `abs(y) < 1e-3`; in `f16`, `(exp(y) - 1.0h) / y` loses precision for `abs(y) < 1e-2h`, causing subtle banding in thin water layers.<br>2. Band UVs `(to_tile * p) / period` in `f16` step coarsely far from the origin.<br>**Mitigation:** Keep `uv` and particle radial distance `u` / `carrier` in `f32`; use `f16`/`vec2h`/`vec3h` for `water_band_derivatives` accumulation, particle cosine envelope, Fresnel, and `water_inscatter` (widening the Taylor threshold in `water_segment_integral` to `1e-2h`). |
|
|
131
|
-
| **F16-23** | **Bloom Standard Downsample, Tent Upsample, & Mix**<br>[`downsample_standard.js:57-98`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/bloom/downsample_standard.js#L57-L98), [`upsample_blur.js:41-104`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/bloom/upsample_blur.js#L41-L104), [`shader_bloom_mix.js:27-53`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/bloom/shader_bloom_mix.js#L27-L53) | `2× ALU` + `VGPR` | **Low-Med** | **Low-Med** | **Artifacts if misused:** In `upsample_blur.js:41-58`, the 9 tent weights `(1, 2, 1, 2, 4, 2, 1, 2, 1)` sum to `16.0` and divide by `16.0` at the end. In `vec3h`, any bloom texel $> 65504 / 16 = 4094$ overflows `result` to `+Inf` before the `1/16` multiply!<br>**Mitigation:** Pre-normalize the tent weights to `(0.0625h, 0.125h, 0.25h)` so the convex combination never exceeds the maximum input texel. Keep `uv + texel_size * offsets[i]` in `vec2f`. |
|
|
132
|
-
| **F16-24** | **Staged Ray-Tracing Octahedral Ray Direction Packing**<br>[`chunk_pack_ray.js:23-35`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/ray/staged/chunk_pack_ray.js#L23-L35) & [`chunk_unpack_ray.js:7-25`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/ray/staged/chunk_unpack_ray.js#L7-L25) | `Bandwidth` (implements author's `NOTE` at `chunk_pack_ray.js:25`: cuts ray payload from 32 B to 24 B or 16 B) | **Medium** | **Medium** | **Artifacts if misused:** Octahedral `f16×2` direction has angular resolution $\approx 0.05^\circ$ (10-bit mantissa). Over very long shadow rays ($> 500\text{ m}$), a $0.05^\circ$ direction shift moves the far endpoint by $\sim 0.4\text{ m}$, which can slightly shift hard distant shadow edges (soft shadows mask it). Never pack `ray.origin` into `f16` (causes severe self-intersection shadow acne).<br>**Mitigation:** Keep `ray.origin` (`vec3f`), `ray.tmin`, and `ray.tmax` in `f32` (or `vec2h(tmin, tmax)` for local shadow rays $< 65504\text{ m}$), and pack `ray.direction` as octahedral `vec2h`. |
|
|
133
|
-
| **F16-25** | **VRS Luminance Delta, SDF Soft Shadow Cone Math, & Contact Shadow Fade**<br>[`chunk_vrs.js:58-114`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/ray/chunk_vrs.js#L58-L114), [`shader_scene_sdf_soft_shadows.js:132-158`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_soft_shadows.js#L132-L158), [`shader_contact_shadow_wavefront.js:289-318`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.js#L289-L318) | `VGPR` + `2× ALU` | **Low-Med** | **Low** | **Artifacts if misused:** In `shader_contact_shadow_wavefront.js`, `depth_data` stores `NO_SHADOW_DEPTH = 1e20` (`L133`) and `start_depth` uses a `1.0 / 65535.0` offset (`L262`), so `depth_data` and `start_depth - samples * depth_scale` must stay `f32`.<br>**Mitigation:** Only convert VRS luminance deltas (`[0, 1]`), SDF cone `step_visibility`/`visibility` (`[0, 1]`), and post-comparison contact shadow `hard_shadow`/`fade_out` (`[0, 1]`) to `f16`. |
|
|
134
|
-
| **F16-26** | **Exponential SH (`p4q2`) Base Reflectance, Particle AVBOIT Lighting, & Skinning Normal/Tangent DQ Rotation**<br>[`chunk_sh_exp_p4q2_base_reflectance.js:32-50`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_p4q2_base_reflectance.js#L32-L50), [`shader_particle_avboit_draw.js:113-152`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js#L113-L152), [`shader_meshlet_apply_skinning.js:311-329`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js#L311-L329) | `VGPR` + `2× ALU` (34-band `vec3h` FMA chain in `sh_exp`; fragment VGPRs in particles; DQ normal rotation in skinning) | **Medium** | **Low** | **Artifacts if misused:** In `shader_meshlet_apply_skinning.js`, vertex positions (`p_skinned`, `p_prev_skinned`) and dual-quaternion translation part `dq_blend.dual` must remain `f32` or skinned meshes jitter in TAA.<br>**Mitigation:** Use `vec3h`/`vec4h` only for the rotation of unit normals/tangents (`dual_quat_transform_direction(vec4h(dq_blend.real), n_h)`), particle SH lighting (`rgba16float` clipmap), and `sh_exp_p4q2` polynomial evaluation. |
|
|
135
|
-
| **F16-27** | **G-Buffer Laydown Normal/Tangent/Color & Khronos PBR Neutral Tonemapper**<br>[`fragment_gbuffer.js:249-346`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/material/standard/fragment_gbuffer.js#L249-L346), [`chunk_tonemap_khronos_pbr.js:25-46`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js#L25-L46), [`shader_avboit_integrate.js:63-80`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js#L63-L80) | `VGPR` + `2× ALU` | **Low-Med** | **Low** | **Artifacts if misused:** In `fragment_gbuffer.js`, visibility-buffer `barycentric_full` (`L198`), `uv_info` derivatives (`L213`), and `anti_alias_roughness_kaplanyan` (`fwidth` squared down to $2.5 \times 10^{-7}$) must remain `f32`.<br>**Mitigation:** Use `vec3h` only for tangent-frame construction (`build_orthonormal_matrix_nt`), normal map decoding, 8-bit triangle dither, `shader_avboit_integrate` (`rgba8unorm`), and `tonemap_khronos_pbr` (after clamping exposed input to `65504.0`). |
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
### 4.3 Tier 3 — Explicit "Do-Not-Convert" (`f32`-Mandatory) Red Zones
|
|
140
|
-
|
|
141
|
-
The following 16 subsystems/calculations were audited and proven mathematically incompatible with `f16`. Converting any of them produces immediate, severe visual defects or fails existing unit test oracles:
|
|
142
|
-
|
|
143
|
-
| Red Zone ID | Subsystem & Files | Why `f16` Fails (Mathematical Mechanism) | Resulting Visual Defect / Failure |
|
|
144
|
-
|---|---|---|---|
|
|
145
|
-
| **NO-F16-01** | **GGX Normal Distribution (`D_GGX`) & Smith-Correlated Visibility (`V_GGX_SmithCorrelated`)**<br>[`chunk_D_GGX.js:26, 40-50`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/brdf/chunk_D_GGX.js#L26-L50), [`chunk_V_GGX_SmithCorrelated.js:19-25`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/brdf/chunk_V_GGX_SmithCorrelated.js#L19-L25) | 1. `BSDF_ROUGHNESS_MINIMUM = 0.02` gives $\alpha^2 = 1.6 \times 10^{-7}$ (deep in `f16` subnormals).<br>2. In `denom = NoH_squared * (a2 - 1.0) + 1.0`, for **any `roughness < 0.148`** ($\alpha^2 < 2^{-11} = 4.88 \times 10^{-4}$), `a2 - 1.0h` rounds to **exactly `-1.0h`**. At `NoH_squared == 1.0h`, `denom == 0.0h` and `a2 / (PI * denom * denom)` evaluates **`0 / 0 = NaN` or `+Inf`**!<br>3. Peak $D_{\text{GGX}} = \frac{1}{\pi \alpha^2}$ exceeds `65504` whenever `roughness < 0.047` (reaching $1.99 \times 10^6$ at `roughness = 0.02`). | **Black `NaN` holes or `+Inf` fireflies at the center of every smooth specular highlight** (`roughness < 0.15`), which then explode into screen-sized artifacts in TAA, SSR, and Bloom. |
|
|
146
|
-
| **NO-F16-02** | **Decima Area-Light Representative Point Solver**<br>[`chunk_get_bent_noh_squared.js:12-81`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/material/chunk_get_bent_noh_squared.js#L12-L81) | Evaluates the 3-vector Gram determinant `1 - NoL^2 - NoV^2 - VoL^2 + 2*NoL*NoV*VoL` (`L47`, which vanishes when `N, L, V` are coplanar) and a cubic Newton step guarded by `1e-8` (`L65`). In `f16`, `1e-8` flushes to `0.0h` and the Gram determinant suffers catastrophic cancellation. | **Single-pixel bright specular fireflies and `NaN` speckles along grazing silhouettes** (documented at `L26-38`). |
|
|
147
|
-
| **NO-F16-03** | **MBOIT Power & Trigonometric Moments & Cholesky/Hankel Solvers**<br>[`shader_oit_generate_moments.js:174-204`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js#L174-L204), [`chunk_compute_transmittance_from_4_power_moments.js:29-104`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/mboit/moments/power/chunk_compute_transmittance_from_4_power_moments.js#L29-L104), [`chunk_compute_transmittance_from_4_trigonometric_moments.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/mboit/moments/geometric/chunk_compute_transmittance_from_4_trigonometric_moments.js) | Uses `moment_bias = 6e-6` (10× smaller than `f16` min normal `6.1e-5`), `c2_safe = 1e-10`, and `d = 1e-20` in Hankel/Toeplitz Cholesky elimination (`d11 = b[1] - b[0]*b[0]`). In `f16`, `d11` and `d22` quantize to `<= 0`, breaking positive-definiteness. | **Camera-locked `NaN` stripes and missing/exploding transparency across all MBOIT surfaces** (documented at `L54-60`). |
|
|
148
|
-
| **NO-F16-04** | **AVBOIT Low-Extinction Taylor Renormalization**<br>[`chunk_avboit_renormalization.js:5-10`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/native/avboit/chunk_avboit_renormalization.js#L5-L10) & [`chunk_avboit_transmittance_to_extinction.js:15`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/native/avboit/chunk_avboit_transmittance_to_extinction.js#L15) | Divides `loss / max(norm, vec3f(1e-20))` for `x < 0.001`. In `f16`, `1e-20` flushes to `0.0h` and faint transparent surfaces (`coverage * T < 6.1e-5`) underflow `norm` to `0.0h`, producing `0 / 0 = NaN`. | **Faint smoke/glass/particles vanish or flicker** as `is_nan` drops the pixel in `shader_avboit_resolve.js:53`. |
|
|
149
|
-
| **NO-F16-05** | **ACES 2.0 Output Transform & UE Filmic Tonemappers**<br>[`chunk_aces2_output_transform.js:73, 226, 242`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.js#L73), [`chunk_tonemap_ue_filmic.js:47, 116`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_ue_filmic.js#L47) | 1. ACES 2.0 Hellwig CAM `pow(x, 1.0 / 0.42)` ($\approx x^{2.38}$) overflows `f16` when LMS $> 105$, and the inverse gamut compressor quadratic `b - sqrt(b^2 - 4ac)` near `J_max` amplifies rounding error by $5\times$ (`ACES_TONE_MAPPING_BRIEF_2026_10_17.md:101`).<br>2. `chunk_tonemap_ue_filmic` computes `log2(max(color, 1e-10))`, which in `f16` flushes `1e-10` to `0.0h` → `log2(0) = -Inf` → `NaN`. | **Visible highlight contouring/banding in ACES 2.0** (fails `shader_tonemap_aces.spec.js` `1e-4` tolerance) and **`NaN` black pixels in dark shadows in UE Filmic**. |
|
|
150
|
-
| **NO-F16-06** | **ReSTIR DI Reservoir State (`targetPdf`, `weightSum`, `M`)**<br>[`RTXDI_PackedReservoir.js:13-14`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/restir/reservoir/RTXDI_PackedReservoir.js#L13-L14), [`restir/reservoir/shader.js:46-81`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/restir/reservoir/shader.js#L46-L81) | `targetPdf` for distant/grazing lights falls below $6.1 \times 10^{-5}$ (underflowing to `0.0h`), while `weightSum = targetPdf * invSourcePdf * M` across many lights exceeds `65504` (overflowing to `+Inf`). | **Permanent temporal `NaN` / firefly feedback loops** across frames and failure of `white_furnace.spec.js:714` (`1e-6` parity). |
|
|
151
|
-
| **NO-F16-07** | **Second-Moment Variance Subtraction (`m2 - m1 * m1`) Across LPV, GTAO, SSR, TAA, Volumetrics**<br>[`chunk_lpv_get_visibility_mask.js:34-49`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.js#L34-L49), [`fragment_shader_denoise_ao.js:42, 50`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js#L42), [`chunk_get_std_dev3.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/math/statistics/chunk_get_std_dev3.js) | 1. For HDR signals $> 255.9$, `m2 = x * x` overflows `65504` to `+Inf`.<br>2. For smooth signals where $\sigma < 0.03$, $\sigma^2 = E[X^2] - (E[X])^2 < 10^{-3}$ is smaller than 1 `f16` ULP at $E[X] \approx 1.0$, cancelling to `0.0h` (or `-1 ULP`).<br>3. `MIN_VARIANCE = 1e-6` / `eps_variance = 1e-10` flushes to `0.0h`. | **Spatial denoisers freeze (stop filtering noise) when `std_dev` collapses to `0`**, or **LPV Chebyshev visibility divides `0 / 0 = NaN`**, causing light leaking and shadow acne. |
|
|
152
|
-
| **NO-F16-08** | **Atmosphere Planetary Geometry & Meter-Scale Extinction Coefficients**<br>[`PLANET_RADIUS_DECLARATION.js:5`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/atmosphere/PLANET_RADIUS_DECLARATION.js#L5), [`C_RAYLEIGH_DECLARATION.js:12`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/atmosphere/C_RAYLEIGH_DECLARATION.js#L12), [`C_OZONE_DECLARATION.js:8`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/atmosphere/C_OZONE_DECLARATION.js#L8), [`chunk_phase_draine.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_phase_draine.js) | `PLANET_RADIUS = 6,378,000 m` and `ATMOSPHERE_HEIGHT = 100,000 m` both exceed `65504` (`+Inf`). Even in km (`6378`), `r^2 = 4.07e7` overflows `f16` and `length(pos) - 6378` has a **4 km altitude ULP**! Meanwhile, Rayleigh (`5.8e-6`), Mie (`4e-6`), and Ozone (`8.5e-8`) $\text{m}^{-1}$ coefficients are deep in `f16` subnormals. | **Complete failure of sky/atmosphere rendering** (ray-sphere intersection returns `NaN`, altitude steps in 4 km bands, and ozone/Rayleigh extinction flushes to zero). |
|
|
153
|
-
| **NO-F16-09** | **Fluid Multigrid Pressure V-Cycle & Divergence Projection**<br>[`shader_fluid_mg_smooth.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js), [`shader_fluid_mg_residual_restrict.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js), [`shader_fluid_mg_coarsest.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/fluid/pressure/shader_fluid_mg_coarsest.js) | Multigrid residual `r = f - A*p` and coarse-grid error corrections decay by $10\times$–$100\times$ per V-cycle (`GPUFluidCascade.js:46-48`), and `params.h2` scales with $h^2$. In `f16`, relaxation stalls at the $10^{-3}$ ULP floor. | **Non-divergent wind projection fails**, leaving compressible artifacts and failing the `1.25×` CPU quality gate (`GPUFluidCascade.quality.slow.spec.js`). |
|
|
154
|
-
| **NO-F16-10** | **Water CDLOD Lattice, Canonical Cell Clipping, & Two-Pass `@invariant` Depth**<br>[`chunk_water_lod.js:12-109`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/surface/lod/chunk_water_lod.js#L12-L109), [`chunk_water_lod_cell.js:10-224`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.js#L10-L224), [`shader_water.js:110, 646`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/water/shader_water.js#L110) | Relies on exact `f32` agreement across LOD levels (`k == 1` morph boundary), canonical Sutherland-Hodgman edge clipping, and `@invariant @builtin(position)` for the `depthCompare: 'equal'` finalize pass. | **T-junction cracks between water LOD rings, watertight boundary holes, and dropped pixels in the `depthCompare: 'equal'` second pass**. |
|
|
155
|
-
| **NO-F16-11** | **Shadow Map / VSM Depth, Receiver-Plane Bias, PCF Texel Coords, & EVSM**<br>[`chunk_sample_shadowmap_atlas_for_light.js:67-102`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.js#L67-L102), [`chunk_shadowmap_sample_5.js:18-40`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_5.js#L18-L40), [`chunk_shadowmap_compute_receiver_plane_depth_bias.js:17-31`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/map/shader/chunk_shadowmap_compute_receiver_plane_depth_bias.js#L17-L31), [`chunk_evsm_warp_depth.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/evsm/chunk_evsm_warp_depth.js) | 1. Shadow atlas texel coordinates reach `2048–8192`, where `f16` ULP is **2 to 8 texels**, wiping out fractional PCF weights `fract(texel_position + 0.5)`.<br>2. Receiver-plane Jacobian determinant `r = ddx.x * ddy.y - ddx.y * ddy.x` ($\sim 10^{-6}$) flushes to `0.0h` (`1/0 = Inf`).<br>3. EVSM `exp(40.0 * depth)` reaches $2.35 \times 10^{17}$ (overflowing `f16` at $e^{11.09} \approx 65504$). | **Blocky 4–8 texel stair-stepped shadow edges, severe shadow acne / peter-panning, and total EVSM overflow**. |
|
|
156
|
-
| **NO-F16-12** | **Screen-Space HZB Raymarch (`SSR` & Contact Shadows)**<br>[`chunk_ffx_sssr_hierarchical_raymarch.js:20-109`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.js#L20-L109), [`shader_contact_shadow_wavefront.js:139-285`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.js#L139-L285) | `uv_offset = 0.005 / screen_size` ($\sim 2.6 \times 10^{-6}$ at 1080p) underflows in `f16`, and screen UV in $[0.5, 1.0]$ has `f16` step $2^{-11} = 1/2048$ (1–2 pixels at 1080p/4K). | **SSR rays get stuck in infinite loops on HZB cell boundaries and produce severe staircase reflections**. |
|
|
157
|
-
| **NO-F16-13** | **Visibility-Buffer Barycentrics & UV Derivatives**<br>[`fragment_gbuffer.js:190-248`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/material/standard/fragment_gbuffer.js#L190-L248) & [`chunk_barycentric_full.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/geometry/barycentric/chunk_barycentric_full.js) | Computes screen-space edge cross products and `1/w` perspective derivatives from clip-space vertices. | **Severe texture UV swimming, wrong mip-level selection, and cracks along triangle edges**. |
|
|
158
|
-
| **NO-F16-14** | **GPU BVH Morton Codes, Bottom-Up Refit, & Unbiased AABB Quantization**<br>[`chunk_bvh_morton_code.js:23-41`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.js#L23-L41), [`chunk_bvh_refit_climb.js:55-102`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_refit_climb.js#L55-L102), [`GPU_BVH_BUILD_PLAN.md:1330-1339`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md#L1330-L1339) | Rounding an `f32` AABB to `f16` with round-to-nearest-even (or a fixed additive `FLT_EPSILON_16 = 2^-10` that rounds away when $|x| > 1$) shrinks AABBs inward by up to 0.5 ULP (`0.5 m` at `1024 m`). | **Ray queries and frustum culling silently miss triangles near AABB boundaries**. |
|
|
159
|
-
| **NO-F16-15** | **Auto-Exposure Histogram Reduction & Adaptation (`@workgroup_size(1)`)**<br>[`shader_autoexposure_read_histogram.js:48, 86-96`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/eye/shader_autoexposure_read_histogram.js#L48) & [`shader_autoexposure_adapt.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js) | Single-thread (`@workgroup_size(1)`) shaders (zero GPU cost) where `total_pixels` and `weighted_log_sum` reach $\sim 2 \times 10^8$ at 1080p, overflowing `65504` by $3000\times$. | **Camera exposure locks to `NaN` (black screen)**. |
|
|
160
|
-
| **NO-F16-16** | **Animation Curve Time, Dual-Quaternion Translation, Foliage State, & Particle VM**<br>[`chunk_animation_curve_evaluate.js:50-72`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/animation/chunk_animation_curve_evaluate.js#L50-L72), [`chunk_foliage_wind_step.js:48-122`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.js#L48-L122), [`chunk_particle_vm.js:28-30`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/particles/vm/chunk_particle_vm.js#L28-L30) | Keyframe `time` at `60 s` has `f16` ULP `0.03125 s` (~2 frames at 60 Hz); foliage `theta_new += vel_new * dt` underflows small `dt` steps; `chunk_particle_vm` requires bit-exact `f32` parity with `ParticleVMReference.js`. | **Visible animation/camera stepping, foliage branches sticking in wind, and broken particle VM tests**. |
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## 5. Detailed Technical Analysis of Top Proposed Items
|
|
165
|
-
|
|
166
|
-
### 5.1 F16-01: Neural Super Sampling Int8 U-Net Convolution (`postprocess/nss/shader_nss_conv_layer.js`)
|
|
167
|
-
|
|
168
|
-
- **Current Implementation ([`shader_nss_conv_layer.js:107-225`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js#L107-L225))**:
|
|
169
|
-
- Dispatched **18 times per frame** (`@workgroup_size(8, 8, 1)`), covering the U-Net encoder, bottleneck, decoder, and 6 KPN output heads.
|
|
170
|
-
- Each invocation computes 4 output channels (`out_group = gid.z`) at pixel `(gid.x, gid.y)` by looping over `ig = 0 .. in_groups - 1` (up to 16 groups = 64 channels) and `ky, kx = -1 .. 1` (3×3 spatial kernel).
|
|
171
|
-
- Inside the loop (`L147-175`), every thread issues **9× `in_groups` (up to 144) 3D `textureLoad`s** from `tInput` (`rgba16float`) and executes **4× `9 × in_groups` (up to 576) `vec4<f32>` dot products** against `unpack4x8snorm(weights[...])`, using **0 bytes of `var<workgroup>` shared memory**.
|
|
172
|
-
- **Proposed `shader-f16` Change**:
|
|
173
|
-
1. Because `gid.z` (`out_group`) is uniform across the entire `8×8×1` workgroup, all 64 threads read the exact same `10×10` spatial patch (`8×8` interior + 1-pixel halo) of `tInput(..., ig, 0)` on each `ig` iteration!
|
|
174
|
-
2. Declare `var<workgroup> wg_input_tile: array<vec4<f16>, 100>;` (**800 bytes** of shared memory — only `4.9%` of the 16 KiB limit, preserving 100% occupancy).
|
|
175
|
-
3. At the start of each `ig` iteration, the 64 threads cooperatively load the 100 `rgba16float` texels into `wg_input_tile` (`1.5625` loads/thread instead of `9` loads/thread — a **5.76× reduction in 3D texture fetches** across all 18 dispatches!).
|
|
176
|
-
4. Unpack the `int8` weights into `vec4<f16>`:
|
|
177
|
-
```wgsl
|
|
178
|
-
let v = wg_input_tile[(lid.y + u32(ky + 1)) * 10u + (lid.x + u32(kx + 1))];
|
|
179
|
-
let w0 = vec4<f16>(unpack4x8snorm(weights[w_idx]));
|
|
180
|
-
let w1 = vec4<f16>(unpack4x8snorm(weights[w_idx + 1u]));
|
|
181
|
-
let w2 = vec4<f16>(unpack4x8snorm(weights[w_idx + 2u]));
|
|
182
|
-
let w3 = vec4<f16>(unpack4x8snorm(weights[w_idx + 3u]));
|
|
183
|
-
acc += vec4<f32>(dot(v, w0), dot(v, w1), dot(v, w2), dot(v, w3));
|
|
184
|
-
```
|
|
185
|
-
- **Precision Analysis**:
|
|
186
|
-
- `tInput` is already `rgba16float` with activations in $[-1, 1]$ (LeakyReLU LUT outputs `int8` dequantized to $[-1, 1]$), and `unpack4x8snorm` produces exact multiples of $1/127$ in $[-1, 1]$, which have $> 3\text{ bits}$ of spare mantissa in `f16`.
|
|
187
|
-
- A 4-element dot product `dot(v, w)` in `f16` is bounded in $[-4, 4]$ (`ULP` $\le 2^{-8} \approx 0.0039$, smaller than 1 `int8` step $1/127 \approx 0.00787$).
|
|
188
|
-
- Keeping the outer sum `acc` (across up to 144 taps) and the post-loop `acc + biases` (`biases` are pre-scaled by $1/127^2 \approx 6.2 \times 10^{-5}$) in `vec4<f32>` prevents both accumulation drift and subnormal bias underflow.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
### 5.2 F16-02: Depth of Field Raymarch & Slice Compute (`postprocess/dof/raymarch/`)
|
|
193
|
-
|
|
194
|
-
- **Current Implementation ([`shader_dof_raymarch_compute.js:30-97, 168-170`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js#L30-L97) & [`shader_dof_slice_compute.js:36-114`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js#L36-L114))**:
|
|
195
|
-
- Each `8×8` workgroup preloads an `88×88` (`REGION = 88`, `REGION_PIXELS = 7744`) neighbourhood of signed CoC values from `tPrefilter.a` (`rgba16float`).
|
|
196
|
-
- Because `7744 × 4 B = 30,976 B` would exceed the 16,384 B WebGPU workgroup memory limit, both shaders declare `var<workgroup> lds_coc: array<u32, 3872>;` (`15,488 B`) and manually pack pairs of horizontal pixels with `pack2x16float(vec2<f32>(c0, c1))`.
|
|
197
|
-
- Inside the innermost ray-march loop (executed up to $48 \times 48 = 2,304$ times per pixel in `shader_dof_raymarch_compute.js:168-170`, and up to $12 \times 2 \times 24 = 576$ times per pixel in `shader_dof_slice_compute.js:81-84`), every step executes:
|
|
198
|
-
```wgsl
|
|
199
|
-
let pair = unpack2x16float(lds_coc[rc.y * ROW_U32 + (rc.x >> 1)]);
|
|
200
|
-
let s_coc = select(pair.x, pair.y, (rc.x & 1) != 0);
|
|
201
|
-
```
|
|
202
|
-
- As documented in [`DOF_CONFIG.js:158-160`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/dof/DOF_CONFIG.js#L158-L160), this inner-loop address shift + unpack + mask + select overhead made `shader_dof_raymarch_compute` measure slower than the uncached fragment shader!
|
|
203
|
-
- **Proposed `shader-f16` Change**:
|
|
204
|
-
- Enable `f16` (`addExtension(WebGPUExtensionType.ShaderF16)`) and declare:
|
|
205
|
-
```wgsl
|
|
206
|
-
var<workgroup> lds_coc: array<f16, 7744>; // 7,744 × 2 B = 15,488 bytes (identical footprint!)
|
|
207
|
-
```
|
|
208
|
-
- During preload (`s = 0 .. 7743` step `64`):
|
|
209
|
-
```wgsl
|
|
210
|
-
lds_coc[s] = f16(textureLoad(tPrefilter, coord, 0).a);
|
|
211
|
-
```
|
|
212
|
-
- Inside the inner march loop:
|
|
213
|
-
```wgsl
|
|
214
|
-
let s_coc: f16 = lds_coc[rc.y * REGION + rc.x];
|
|
215
|
-
```
|
|
216
|
-
- **Precision Analysis**:
|
|
217
|
-
- **100% bit-identical** to the current shader (`tPrefilter.a` is already `rgba16float`, so `f16(textureLoad(...).a)` is an exact copy), while removing 4 ALU instructions per march step ($\sim 9,200$ ALU ops/pixel at cinematic quality).
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
### 5.3 F16-04 & F16-10: Brick4 GI (`shader_brick4_indirect_lighting.js`) & Deferred/Forward PBR (`shader_deferred_main.js`, `chunk_forward_shade_standard_fragment.js`)
|
|
222
|
-
|
|
223
|
-
- **Current Register Pressure Bottleneck**:
|
|
224
|
-
- In [`shader_brick4_indirect_lighting.js:109-189`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.js#L109-L189), trilinear interpolation + normal-weighted probe blending + cone directional visibility keeps **four `SH3CoefficientsColor` arrays** (`probe0`, `probe1`, `sample_probe_diff`, `sample_probe_spec`, each `array<vec3<f32>, 9>` = 27 floats) live in registers simultaneously (**108 scalar 32-bit registers** just for SH coefficients!).
|
|
225
|
-
- In [`shader_deferred_main.js:84-128`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/deferred/shader_deferred_main.js#L84-L128) and [`chunk_forward_shade_standard_fragment.js:58-195`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment.js#L58-L195), `MaterialShadingInfo` (18 floats) + `GeometricShadingInfo` (`position_ws`, `view_direction`, `shading_normal`, `geometric_normal`, 12 floats) stay live across shadow-map / ray-query calls and two 64-iteration (or 32-iteration) point and spot light loops.
|
|
226
|
-
- **Proposed `shader-f16` Change**:
|
|
227
|
-
1. **SH3 Coefficients (`SH3CoefficientsColor`)**:
|
|
228
|
-
- In [`chunk_sh3_uncompress.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_uncompress.js), `brick4_sh3_color_decode` unpacks an `rgbe9995` DC (`max_val`, 100% exact in `f16`) and 8-bit Wiederien L1/L2 coefficients in $[-1, 1]$.
|
|
229
|
-
- Decoding into `array<vec3<f16>, 9>` and running `sh3_basis_at`, `sh3_color_mix2`, `sh3_color_estimate_for_cone`, `sh3_color_get_irradiance_at`, and `sh3_color_get_radiance_with_GGX` in `vec3h` cuts the SH register footprint in `shader_brick4_indirect_lighting.js` from **108 VGPRs to 54 VGPRs** and executes the 9-band multiply-accumulate chains at double rate.
|
|
230
|
-
2. **Surface Material & Bounded BRDF Terms (`MaterialShadingInfo`)**:
|
|
231
|
-
- Store `diffuse`, `specularF0`, `specularF0_dielectric`, `specularF0_metal`, `specularF90` (`vec3h` in $[0, 1]$), `emissive` (`vec3h`, decoded from `rgbe9995`), `occlusion`, `roughness`, `opacity` (`f16` in $[0, 1]$), and unit vectors `shading_normal`, `geometric_normal`, `view_direction` (`vec3h` in $[-1, 1]$).
|
|
232
|
-
- Evaluate `F_Schlick` (`chunk_F_Schlick.js`), `oren_nayar_fujii_diffuse_dir_albedo_approx`, `EON` (with `1e-4h` epsilon guards), and `calculate_bent_normal_shadowing` in `f16`/`vec3h`.
|
|
233
|
-
- Keep `position_ws`, `light_to_frag`, `D_GGX`, `V_GGX_SmithCorrelated`, and `get_bent_noh_squared` in `f32`.
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
## 6. Mandatory WGSL Coding Rules for `shader-f16` in Shade
|
|
238
|
-
|
|
239
|
-
To prevent `f16` precision bugs from entering the codebase, any chunk or shader using `enable f16;` must follow these five engineering rules:
|
|
240
|
-
|
|
241
|
-
1. **Rule 1 — Never Use `EPSILON` (`1e-6`) in `f16` Denominators:**
|
|
242
|
-
- [`EPSILON_DECLARATION.js:5`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/chunk/math/EPSILON_DECLARATION.js#L5) defines `const EPSILON = 1e-6;`, which is **subnormal in `f16`** (min normal is $2^{-14} \approx 6.1035 \times 10^{-5}$) and flushes to `0.0h` when added to an $O(1)$ quantity (such as `4.0h * minRGB - 4.0h + 1e-6h` in `shader_ffx_rcas.js:87`).
|
|
243
|
-
- Add `EPSILON_F16_DECLARATION.js` (`const EPSILON_F16: f16 = 1e-4h;`, $\approx 1.64 \times 2^{-14}$) and use `max(denom, EPSILON_F16)` in all `f16` divisions.
|
|
244
|
-
2. **Rule 2 — Clamp Unbounded `f32` Quantities Before Casting to `f16` or Storing to `rgba16float`:**
|
|
245
|
-
- In WGSL, `f16(x)` for any `x > 65504.0` produces `+Inf`, which turns into `NaN` as soon as it meets `* 0.0` (attenuation/weights) or `Inf / Inf` (Reinhard/Karis tonemap).
|
|
246
|
-
- Always clamp unbounded HDR radiance or variance via `min(x, 65504.0)` (`F16_MAX`) before casting to `f16` or calling `textureStore` on an `rgba16float` target.
|
|
247
|
-
3. **Rule 3 — Never Subtract Nearly-Equal Quantities Near `1.0` or Compute Second-Moment Variance in `f16`:**
|
|
248
|
-
- Expressions of the form `1.0 - cos_theta` (for small angles $\theta < 5^\circ$), `1.0 - NoH_squared * (1.0 - a2)` (GGX NDF), `1.0 - luma` (`taa_tonemap_inv`), and `m2 - m1 * m1` (variance in LPV, GTAO, SSR, TAA, Volumetrics) lose all significant bits in a 10-bit mantissa and **must stay `f32`**.
|
|
249
|
-
4. **Rule 4 — Never Compute Squared Distances `dot(v, v)` in `f16` When `|v|` Can Exceed `255.9`:**
|
|
250
|
-
- Because $\sqrt{65504} \approx 255.937$, `dot(v, v)` or `length(v)` on a `vec2h`/`vec3h` overflows to `+Inf` whenever `|v| >= 256` (e.g., world distances $> 256\text{ m}$ in light culling, pixel velocities $> 256\text{ px}$ in motion blur, or HDR luma $> 256$ in variance).
|
|
251
|
-
5. **Rule 5 — Vectorize into `vec2h` / `vec4h` and Keep `f32 ↔ f16` Casts Outside Inner Loops:**
|
|
252
|
-
- Place `vec3h(...)` / `vec4h(...)` conversions at texture/buffer load boundaries or before a loop, and convert back to `vec3f` / `vec4f` only at the accumulator or output boundary.
|
|
253
|
-
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
## 7. Recommended Phased Rollout Plan
|
|
257
|
-
|
|
258
|
-
| Stage | Scope | Items Included | Verification Gate |
|
|
259
|
-
|---|---|---|---|
|
|
260
|
-
| **Stage 0: P0 Infrastructure & `rgba16float` Bug Fixes** | Fix `enable f16;` codegen, device feature negotiation, CPU emulator `f16` scalar/vector rounding, validator rule, buffer serde, and the 5 live `rgba16float` `+Inf → NaN` bugs | ✅ `INFRA-1`, ✅ `INFRA-3`, ✅ `INFRA-4`, ✅ `INFRA-5`, ✅ `INFRA-6` (landed in `a7e88413f`..`b637acaef`);<br>✅ `BUG-1`..`BUG-5` (landed in `eecb70112`..`a86cf8617`);<br>⏳ `INFRA-2` | ✅ Unit & regression specs landed for `ShaderDescriptor` (`enable f16;` & auto-extension propagation), `WGSLJavaScriptCompiler` / `WGSLLanguageCore` ([`f16_emulation.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/f16_emulation.spec.js), [`abstract_float_range.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/emulator/abstract_float_range.spec.js)), `validate_wgsl_source` (`unenabled-f16` in [`validate_wgsl_source.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/wgsl/validate_wgsl_source.spec.js)), `f16`/`vecNh`/`matCxRh` buffer serde ([`read_gpu_typed_buffer.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.spec.js)), and `BUG-1`..`BUG-5` ([`shader_volumetrics_taa.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.spec.js), [`shader_volumetrics_build_lighting_local_shadow.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting_local_shadow.spec.js), [`shader_nss_preprocess.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/nss/shader_nss_preprocess.spec.js), [`chunk_karis_blur4x4_sample.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.spec.js), [`downsample_karis.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/downsample_karis.spec.js), [`ssr_metadata.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/ssr/ssr_metadata.spec.js), [`chunk_taa_tonemap_inv.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.spec.js), [`shader_taa.spec.js`](file:///h:/git/CompanyNamed/meep/packages/meep-engine/src/shade/renderer/postprocess/taa/shader_taa.spec.js)).<br>⏳ Remaining: `INFRA-2` device floor. |
|
|
261
|
-
| **Stage 1: Tier-1 Shared Memory (`var<workgroup>`) & Compute Wins** | Zero-visual-risk compute passes where `f16` eliminates `unpack2x16float` loops, halves 16 KiB LDS pressure, or caches `rgba16float` tiles | `F16-01` (NSS conv), `F16-02` (DoF raymarch/slice compute), `F16-03` (Fluid MAC curl/gradient), `F16-05` (SSR prefilter), `F16-06` (Hi-Z SPD), `F16-07` (Env/Sky SH reductions), `F16-08` (LPV border & SHARC), `F16-09` (Luma denoiser) | Paired A/B GPU timestamp measurements on RTX 4090 and AMD RDNA2 iGPU + emulator bit-exact / 1-ULP equivalence tests. |
|
|
262
|
-
| **Stage 2: Tier-1/2 High-VGPR Shading & Post-Process Loops** | Reduce VGPR footprint and enable 2× SIMD ALU in register-heavy fragment and compute shaders | `F16-04` (Brick4 SH3 `vec3h`), `F16-10` (Deferred & Forward `MaterialShadingInfo` + `F_Schlick`/diffuse), `F16-11` (Volumetrics lighting), `F16-12` (Water column FFT), `F16-13` (GTAO), `F16-14` (TAA), `F16-15` (Volumetric TAA), `F16-16` (RCAS), `F16-17` (SSR denoise/combine), `F16-18` (ReSTIR denoise) | `white_furnace.spec.js`, `chunk_wgsl_validity.spec.js`, RDNA/NVIDIA register & occupancy dump inspection, and per-pass timestamp A/B. |
|
|
263
|
-
| **Stage 3: Tier-2 Bandwidth, Varyings, & Secondary Passes** | Varying interpolant packing, compute tile-max reductions, and staged ray packing | `F16-19` (`FORWARD_VERTEX_SHADER_STRUCT`), `F16-20` (DoF & Motion Blur compute tile-max), `F16-21` (Cluster culling), `F16-22`..`F16-27` | Visual & numerical diff across playgrounds (`avboit`, `water_surface`, `volumetrics_froxel`, `vsm`, `caldera`). |
|