@woosh/meep-engine 2.164.0 → 2.165.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BitImage2.d.ts +91 -0
- package/src/core/binary/BitImage2.d.ts.map +1 -0
- package/src/core/binary/BitImage2.js +242 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts +22 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts.map +1 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -0
- package/src/core/geom/2d/packing/skyline.d.ts +116 -0
- package/src/core/geom/2d/packing/skyline.d.ts.map +1 -0
- package/src/core/geom/2d/packing/skyline.js +258 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts +18 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts.map +1 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +86 -0
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -0
- package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -0
- package/src/core/geom/3d/atlas/Chart.d.ts +58 -0
- package/src/core/geom/3d/atlas/Chart.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/Chart.js +77 -0
- package/src/core/geom/3d/atlas/REVIEW_02.md +392 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts +73 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.d.ts +17 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts +25 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts +17 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -0
- package/src/core/geom/3d/atlas/atlas_generate.d.ts +39 -0
- package/src/core/geom/3d/atlas/atlas_generate.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_generate.js +43 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +84 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts +25 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts +22 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts +9 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts +9 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts +27 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts +22 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.js +57 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts +36 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts +62 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +551 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts +22 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.js +73 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts +37 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +270 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts +23 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +224 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts +14 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts +22 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts +20 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts +27 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts +31 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts +23 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts +24 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts +27 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +113 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts +44 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +275 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts +22 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +199 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts +32 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts.map +1 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts +20 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +66 -0
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +13 -11
- package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js +4 -3
- package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +4 -3
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.js +4 -3
- package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.js +10 -6
- package/src/core/geom/3d/topology/struct/TopoMesh.js +2 -2
- package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/TopoTriangle.js +2 -2
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +8 -27
- package/src/core/geom/vec3/v3_cotangent.d.ts +20 -0
- package/src/core/geom/vec3/v3_cotangent.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_cotangent.js +29 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.d.ts +19 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -0
- package/src/core/geom/vec3/v3_multiply.d.ts +16 -0
- package/src/core/geom/vec3/v3_multiply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_multiply.js +19 -0
- package/src/core/math/linalg/cg/cg_solve.d.ts +24 -0
- package/src/core/math/linalg/cg/cg_solve.d.ts.map +1 -0
- package/src/core/math/linalg/cg/cg_solve.js +106 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts +21 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts.map +1 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +19 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts +50 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -0
- package/src/core/math/linalg/sparse/spm_matvec.d.ts +9 -0
- package/src/core/math/linalg/sparse/spm_matvec.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/spm_matvec.js +22 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts +12 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -0
- package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.d.ts +39 -0
- package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.js +22 -1
- package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.d.ts.map +1 -1
- package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.js +32 -9
- package/src/core/math/physics/mie/compute_mie_phase.d.ts +2 -3
- package/src/core/math/physics/mie/compute_mie_phase.d.ts.map +1 -1
- package/src/core/math/physics/mie/compute_mie_phase.js +1 -3
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +0 -1
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
- package/src/core/math/physics/mie/lorenz_mie_coefs.js +0 -7
- package/src/engine/ecs/attachment/TransformAttachmentBinding.js +3 -3
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -2
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +4 -3
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +2 -2
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +9 -8
- package/src/engine/graphics/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics/GraphicsEngine.js +2 -1
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +2 -2
- package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +2 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +2 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +0 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +8 -7
- package/src/engine/graphics/geometry/MikkT/AvgTSpace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/AvgTSpace.js +11 -6
- package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +2 -3
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.js +3 -4
- package/src/engine/graphics/geometry/MikkT/DegenEpilogue.js +4 -4
- package/src/engine/graphics/geometry/MikkT/EvalTspace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/EvalTspace.js +11 -8
- package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +7 -8
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +8 -8
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.js +30 -25
- package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +7 -7
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts +0 -1
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.js +6 -4
- package/src/engine/graphics/geometry/MikkT/STSpace.d.ts +0 -2
- package/src/engine/graphics/geometry/MikkT/STSpace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/STSpace.js +3 -3
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts +0 -2
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.js +0 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts +0 -2
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.js +4 -3
- package/src/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +2 -2
- package/src/engine/graphics/impostors/octahedral/grid/UvEncoder.d.ts +17 -7
- package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.js +2 -2
- package/src/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +3 -3
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +4 -3
- package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
- package/src/engine/graphics/render/forward_plus/model/Decal.d.ts +0 -2
- package/src/engine/graphics/render/forward_plus/model/Decal.d.ts.map +1 -1
- package/src/engine/graphics/render/forward_plus/model/Decal.js +3 -3
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +4 -3
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +6 -4
- package/src/engine/graphics/sh3/lightmap/ARTIFACTS_PLAN.md +146 -0
- package/src/engine/graphics/sh3/lightmap/CODE_REVIEW.md +121 -0
- package/src/engine/graphics/sh3/lightmap/LIGHTMAPPER_REVIEW.md +183 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts +90 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.js +678 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts +32 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.js +155 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts +49 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.js +136 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts +19 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.js +89 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts +54 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.js +168 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts +30 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.js +145 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts +38 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.js +152 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts +2 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.js +186 -0
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.js +6 -4
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +3 -3
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +5 -4
- package/src/engine/graphics/sh3/sky/hosek/prototype_hosek.js +2 -2
- package/src/engine/input/devices/KeyboardDevice.d.ts +61 -14
- package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
- package/src/engine/input/devices/KeyboardDevice.js +41 -15
- package/src/engine/input/devices/isHTMLElementFocusable.d.ts.map +1 -1
- package/src/engine/input/devices/isHTMLElementFocusable.js +2 -9
- package/src/engine/sound/simulation/prototypeAcousticSolver.js +261 -143
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a renderable {@link BufferGeometry} from a mesh's packed lightmap charts.
|
|
3
|
+
*
|
|
4
|
+
* The charts are a re-indexed triangle soup: each chart owns its own local
|
|
5
|
+
* vertices (seam vertices are duplicated between charts, which is exactly what is
|
|
6
|
+
* needed so each side of a seam carries its own atlas UV). We concatenate every
|
|
7
|
+
* chart's vertices into one indexed geometry, writing:
|
|
8
|
+
* - `position` from {@link Chart#positions} (object-local 3D coordinates),
|
|
9
|
+
* - `uv2` from {@link Chart#uv} (atlas-space lightmap coordinates, post-pack),
|
|
10
|
+
* - `normal` carried per triangle from the SOURCE mesh's normals when available
|
|
11
|
+
* (continuous across chart seams), falling back to a geometric normal only for
|
|
12
|
+
* triangles that don't map back cleanly (see {@link accumulate_normals}).
|
|
13
|
+
*
|
|
14
|
+
* @param {Chart[]} charts the mesh's charts, already packed (atlas-space `uv`)
|
|
15
|
+
* @param {Float32Array|number[]} [source_normals] source per-vertex normals (flat xyz)
|
|
16
|
+
* @param {ArrayLike<number>} [source_indices] source triangle index buffer
|
|
17
|
+
* @returns {{
|
|
18
|
+
* geometry: BufferGeometry,
|
|
19
|
+
* positions: Float32Array,
|
|
20
|
+
* normals: Float32Array,
|
|
21
|
+
* chart_vertex_offset: Uint32Array
|
|
22
|
+
* }} the geometry plus the backing position/normal arrays and the per-chart
|
|
23
|
+
* starting vertex offset (for callers that still need to walk the charts)
|
|
24
|
+
*/
|
|
25
|
+
export function lightmap_build_geometry(charts: Chart[], source_normals?: Float32Array | number[], source_indices?: ArrayLike<number>): {
|
|
26
|
+
geometry: BufferGeometry;
|
|
27
|
+
positions: Float32Array;
|
|
28
|
+
normals: Float32Array;
|
|
29
|
+
chart_vertex_offset: Uint32Array;
|
|
30
|
+
};
|
|
31
|
+
import { BufferGeometry } from "three";
|
|
32
|
+
//# sourceMappingURL=lightmap_build_geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightmap_build_geometry.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_build_geometry.js"],"names":[],"mappings":"AAkEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,gDAXW,OAAO,mBACP,YAAY,GAAC,MAAM,EAAE,mBACrB,UAAU,MAAM,CAAC;cAEb,cAAc;eACb,YAAY;aACd,YAAY;yBACA,WAAW;EAoEpC;+BA1J+C,OAAO"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { BufferAttribute, BufferGeometry } from "three";
|
|
2
|
+
import { v3_add_array } from "../../../../core/geom/vec3/v3_add_array.js";
|
|
3
|
+
import { geometry_construct_triangle_normal } from "../../geometry/geometry_construct_triangle_normal.js";
|
|
4
|
+
import { v3_array_normalize_many } from "../../geometry/buffered/v3_array_normalize_many.js";
|
|
5
|
+
|
|
6
|
+
const _tri_normal = new Float64Array(3);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Accumulate per-vertex normals onto the concatenated chart vertices, then the
|
|
10
|
+
* caller normalizes. Each triangle carries the SOURCE mesh's per-corner normals
|
|
11
|
+
* (via its source face id) when it maps cleanly back — so a seam vertex gets the
|
|
12
|
+
* same normal on both sides of a chart boundary (continuous shading) while hard
|
|
13
|
+
* edges keep their per-face normals. A triangle that does NOT map cleanly (e.g. a
|
|
14
|
+
* weld T-junction split created a face beyond the source range) falls back to its
|
|
15
|
+
* own geometric normal — PER TRIANGLE, so one bad face never discards authored
|
|
16
|
+
* normals for the rest of the mesh. With no source normals at all, every triangle
|
|
17
|
+
* takes the geometric path (equivalent to recomputing vertex normals).
|
|
18
|
+
*
|
|
19
|
+
* @param {Chart[]} charts
|
|
20
|
+
* @param {Uint32Array} chart_vertex_offset
|
|
21
|
+
* @param {Float32Array} normals destination (zero-initialised), accumulated then normalized by caller
|
|
22
|
+
* @param {Float32Array|number[]|null} source_normals source per-vertex normals (flat xyz), or null
|
|
23
|
+
* @param {ArrayLike<number>|null} source_indices source triangle index buffer, or null
|
|
24
|
+
*/
|
|
25
|
+
function accumulate_normals(charts, chart_vertex_offset, normals, source_normals, source_indices) {
|
|
26
|
+
const have_source = source_normals != null && source_indices != null;
|
|
27
|
+
const index_count = have_source ? source_indices.length : 0;
|
|
28
|
+
const normal_count = have_source ? source_normals.length : 0;
|
|
29
|
+
|
|
30
|
+
for (let ci = 0; ci < charts.length; ci++) {
|
|
31
|
+
const chart = charts[ci];
|
|
32
|
+
const offset = chart_vertex_offset[ci];
|
|
33
|
+
const tri_local = chart.tri_local;
|
|
34
|
+
const tri_face = chart.tri_face;
|
|
35
|
+
const chart_positions = chart.positions;
|
|
36
|
+
const triangle_count = chart.triangle_count;
|
|
37
|
+
|
|
38
|
+
for (let t = 0; t < triangle_count; t++) {
|
|
39
|
+
const la = tri_local[t * 3];
|
|
40
|
+
const lb = tri_local[t * 3 + 1];
|
|
41
|
+
const lc = tri_local[t * 3 + 2];
|
|
42
|
+
|
|
43
|
+
let carried = false;
|
|
44
|
+
if (have_source) {
|
|
45
|
+
const fi = tri_face[t] * 3;
|
|
46
|
+
if (fi + 2 < index_count) {
|
|
47
|
+
const o0 = source_indices[fi], o1 = source_indices[fi + 1], o2 = source_indices[fi + 2];
|
|
48
|
+
if (o0 * 3 + 2 < normal_count && o1 * 3 + 2 < normal_count && o2 * 3 + 2 < normal_count) {
|
|
49
|
+
v3_add_array(normals, (offset + la) * 3, source_normals, o0 * 3);
|
|
50
|
+
v3_add_array(normals, (offset + lb) * 3, source_normals, o1 * 3);
|
|
51
|
+
v3_add_array(normals, (offset + lc) * 3, source_normals, o2 * 3);
|
|
52
|
+
carried = true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!carried) {
|
|
58
|
+
geometry_construct_triangle_normal(_tri_normal, 0, la, lb, lc, chart_positions);
|
|
59
|
+
v3_add_array(normals, (offset + la) * 3, _tri_normal, 0);
|
|
60
|
+
v3_add_array(normals, (offset + lb) * 3, _tri_normal, 0);
|
|
61
|
+
v3_add_array(normals, (offset + lc) * 3, _tri_normal, 0);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build a renderable {@link BufferGeometry} from a mesh's packed lightmap charts.
|
|
69
|
+
*
|
|
70
|
+
* The charts are a re-indexed triangle soup: each chart owns its own local
|
|
71
|
+
* vertices (seam vertices are duplicated between charts, which is exactly what is
|
|
72
|
+
* needed so each side of a seam carries its own atlas UV). We concatenate every
|
|
73
|
+
* chart's vertices into one indexed geometry, writing:
|
|
74
|
+
* - `position` from {@link Chart#positions} (object-local 3D coordinates),
|
|
75
|
+
* - `uv2` from {@link Chart#uv} (atlas-space lightmap coordinates, post-pack),
|
|
76
|
+
* - `normal` carried per triangle from the SOURCE mesh's normals when available
|
|
77
|
+
* (continuous across chart seams), falling back to a geometric normal only for
|
|
78
|
+
* triangles that don't map back cleanly (see {@link accumulate_normals}).
|
|
79
|
+
*
|
|
80
|
+
* @param {Chart[]} charts the mesh's charts, already packed (atlas-space `uv`)
|
|
81
|
+
* @param {Float32Array|number[]} [source_normals] source per-vertex normals (flat xyz)
|
|
82
|
+
* @param {ArrayLike<number>} [source_indices] source triangle index buffer
|
|
83
|
+
* @returns {{
|
|
84
|
+
* geometry: BufferGeometry,
|
|
85
|
+
* positions: Float32Array,
|
|
86
|
+
* normals: Float32Array,
|
|
87
|
+
* chart_vertex_offset: Uint32Array
|
|
88
|
+
* }} the geometry plus the backing position/normal arrays and the per-chart
|
|
89
|
+
* starting vertex offset (for callers that still need to walk the charts)
|
|
90
|
+
*/
|
|
91
|
+
export function lightmap_build_geometry(charts, source_normals, source_indices) {
|
|
92
|
+
let vertex_total = 0;
|
|
93
|
+
let triangle_total = 0;
|
|
94
|
+
|
|
95
|
+
const chart_count = charts.length;
|
|
96
|
+
const chart_vertex_offset = new Uint32Array(chart_count);
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < chart_count; i++) {
|
|
99
|
+
chart_vertex_offset[i] = vertex_total;
|
|
100
|
+
vertex_total += charts[i].vertex_count;
|
|
101
|
+
triangle_total += charts[i].triangle_count;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const positions = new Float32Array(vertex_total * 3);
|
|
105
|
+
const uv2 = new Float32Array(vertex_total * 2);
|
|
106
|
+
const normals = new Float32Array(vertex_total * 3);
|
|
107
|
+
const indices = new Uint32Array(triangle_total * 3);
|
|
108
|
+
|
|
109
|
+
let index_cursor = 0;
|
|
110
|
+
|
|
111
|
+
for (let i = 0; i < chart_count; i++) {
|
|
112
|
+
const chart = charts[i];
|
|
113
|
+
const vertex_offset = chart_vertex_offset[i];
|
|
114
|
+
|
|
115
|
+
const chart_positions = chart.positions;
|
|
116
|
+
const chart_uv = chart.uv;
|
|
117
|
+
const vertex_count = chart.vertex_count;
|
|
118
|
+
|
|
119
|
+
for (let v = 0; v < vertex_count; v++) {
|
|
120
|
+
const dst3 = (vertex_offset + v) * 3;
|
|
121
|
+
const src3 = v * 3;
|
|
122
|
+
positions[dst3] = chart_positions[src3];
|
|
123
|
+
positions[dst3 + 1] = chart_positions[src3 + 1];
|
|
124
|
+
positions[dst3 + 2] = chart_positions[src3 + 2];
|
|
125
|
+
|
|
126
|
+
const dst2 = (vertex_offset + v) * 2;
|
|
127
|
+
const src2 = v * 2;
|
|
128
|
+
uv2[dst2] = chart_uv[src2];
|
|
129
|
+
uv2[dst2 + 1] = chart_uv[src2 + 1];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const tri_local = chart.tri_local;
|
|
133
|
+
const corner_count = chart.triangle_count * 3;
|
|
134
|
+
for (let k = 0; k < corner_count; k++) {
|
|
135
|
+
indices[index_cursor++] = tri_local[k] + vertex_offset;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
accumulate_normals(charts, chart_vertex_offset, normals, source_normals, source_indices);
|
|
140
|
+
v3_array_normalize_many(normals);
|
|
141
|
+
|
|
142
|
+
const geometry = new BufferGeometry();
|
|
143
|
+
geometry.setAttribute('position', new BufferAttribute(positions, 3));
|
|
144
|
+
geometry.setAttribute('normal', new BufferAttribute(normals, 3));
|
|
145
|
+
geometry.setAttribute('uv2', new BufferAttribute(uv2, 2));
|
|
146
|
+
geometry.setIndex(new BufferAttribute(indices, 1));
|
|
147
|
+
|
|
148
|
+
// Compute the bounding box up front so the geometry is render-ready: consumers that cull / refit bounds
|
|
149
|
+
// (e.g. ShadedGeometry.update_bounds → aabb3_from_three_geometry) require boundingBox to be non-null. Without
|
|
150
|
+
// this, a baked mesh that later moves (its Transform changes) hits a null boundingBox on the bounds refit and
|
|
151
|
+
// its cull leaf goes stale — the object gets frustum-culled at its new pose.
|
|
152
|
+
geometry.computeBoundingBox();
|
|
153
|
+
|
|
154
|
+
return { geometry, positions, normals, chart_vertex_offset };
|
|
155
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variance-guided, normal-aware, edge-preserving denoise of a baked lightmap —
|
|
3
|
+
* NOT a blind blur.
|
|
4
|
+
*
|
|
5
|
+
* For each covered texel it forms a weighted average of its covered neighbours in
|
|
6
|
+
* a small window, where each neighbour's weight is the product of three terms:
|
|
7
|
+
* - **spatial** — a Gaussian in texel distance (closer counts more);
|
|
8
|
+
* - **range** — gated by the Monte-Carlo noise level: the luminance difference is
|
|
9
|
+
* measured against the combined per-texel noise stddev
|
|
10
|
+
* `sqrt(var_center + var_neighbour)`, so differences consistent with noise blend
|
|
11
|
+
* away while real lighting gradients are preserved;
|
|
12
|
+
* - **normal** — `pow(max(0, dot(n_center, n_neighbour)), normal_power)`, so the
|
|
13
|
+
* filter never blurs across an angular discontinuity. Atlas-adjacency does not
|
|
14
|
+
* imply surface-adjacency: a box's two faces, or two unrelated charts packed
|
|
15
|
+
* near each other across a thin gutter, must not bleed into one another. A 90°
|
|
16
|
+
* crease (`dot = 0`) is fully stopped; smooth curvature (`dot ≈ 1`) blends.
|
|
17
|
+
*
|
|
18
|
+
* **Boundary-aware:** a texel at a chart edge (or next to a crease) has a
|
|
19
|
+
* truncated, one-sided support, whose average is biased. The denoised value is
|
|
20
|
+
* blended back toward the texel's own value in proportion to how incomplete its
|
|
21
|
+
* support is (fraction of the window that actually contributed), so edges keep
|
|
22
|
+
* their unbiased — if noisier — value instead of being pulled toward the
|
|
23
|
+
* available (darker/brighter) side.
|
|
24
|
+
*
|
|
25
|
+
* Writes filtered values for covered texels into `out`; uncovered texels are left
|
|
26
|
+
* as-is in `out` (the caller dilates them afterwards). `out` must be a distinct
|
|
27
|
+
* buffer from `data`.
|
|
28
|
+
*
|
|
29
|
+
* @param {Float32Array} out destination, same layout as `data` (distinct buffer)
|
|
30
|
+
* @param {Float32Array} data source pixels, row-major, stride `channels`
|
|
31
|
+
* @param {Float32Array} variance per-texel luminance variance-of-mean, length width*height
|
|
32
|
+
* @param {Float32Array} normals per-texel world normal (3 per texel), length width*height*3
|
|
33
|
+
* @param {Uint8Array} coverage per-texel coverage (1 = valid), length width*height
|
|
34
|
+
* @param {number} width
|
|
35
|
+
* @param {number} height
|
|
36
|
+
* @param {number} channels values per texel (rgb[+a])
|
|
37
|
+
* @param {object} [options]
|
|
38
|
+
* @param {number} [options.radius] window half-size in texels (default 2)
|
|
39
|
+
* @param {number} [options.spatial_sigma] spatial Gaussian sigma in texels (default 1.5)
|
|
40
|
+
* @param {number} [options.beta] noise tolerance: how many stddevs count as "still noise" (default 3)
|
|
41
|
+
* @param {number} [options.normal_power] sharpness of the normal-similarity cutoff (default 8)
|
|
42
|
+
*/
|
|
43
|
+
export function lightmap_denoise(out: Float32Array, data: Float32Array, variance: Float32Array, normals: Float32Array, coverage: Uint8Array, width: number, height: number, channels: number, options?: {
|
|
44
|
+
radius?: number;
|
|
45
|
+
spatial_sigma?: number;
|
|
46
|
+
beta?: number;
|
|
47
|
+
normal_power?: number;
|
|
48
|
+
}): void;
|
|
49
|
+
//# sourceMappingURL=lightmap_denoise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightmap_denoise.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_denoise.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,sCAdW,YAAY,QACZ,YAAY,YACZ,YAAY,WACZ,YAAY,YACZ,UAAU,SACV,MAAM,UACN,MAAM,YACN,MAAM;IAEW,MAAM,GAAvB,MAAM;IACW,aAAa,GAA9B,MAAM;IACW,IAAI,GAArB,MAAM;IACW,YAAY,GAA7B,MAAM;SA6FhB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { rgb_to_luminance } from "../../../../core/color/rgb_to_luminance.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Variance-guided, normal-aware, edge-preserving denoise of a baked lightmap —
|
|
5
|
+
* NOT a blind blur.
|
|
6
|
+
*
|
|
7
|
+
* For each covered texel it forms a weighted average of its covered neighbours in
|
|
8
|
+
* a small window, where each neighbour's weight is the product of three terms:
|
|
9
|
+
* - **spatial** — a Gaussian in texel distance (closer counts more);
|
|
10
|
+
* - **range** — gated by the Monte-Carlo noise level: the luminance difference is
|
|
11
|
+
* measured against the combined per-texel noise stddev
|
|
12
|
+
* `sqrt(var_center + var_neighbour)`, so differences consistent with noise blend
|
|
13
|
+
* away while real lighting gradients are preserved;
|
|
14
|
+
* - **normal** — `pow(max(0, dot(n_center, n_neighbour)), normal_power)`, so the
|
|
15
|
+
* filter never blurs across an angular discontinuity. Atlas-adjacency does not
|
|
16
|
+
* imply surface-adjacency: a box's two faces, or two unrelated charts packed
|
|
17
|
+
* near each other across a thin gutter, must not bleed into one another. A 90°
|
|
18
|
+
* crease (`dot = 0`) is fully stopped; smooth curvature (`dot ≈ 1`) blends.
|
|
19
|
+
*
|
|
20
|
+
* **Boundary-aware:** a texel at a chart edge (or next to a crease) has a
|
|
21
|
+
* truncated, one-sided support, whose average is biased. The denoised value is
|
|
22
|
+
* blended back toward the texel's own value in proportion to how incomplete its
|
|
23
|
+
* support is (fraction of the window that actually contributed), so edges keep
|
|
24
|
+
* their unbiased — if noisier — value instead of being pulled toward the
|
|
25
|
+
* available (darker/brighter) side.
|
|
26
|
+
*
|
|
27
|
+
* Writes filtered values for covered texels into `out`; uncovered texels are left
|
|
28
|
+
* as-is in `out` (the caller dilates them afterwards). `out` must be a distinct
|
|
29
|
+
* buffer from `data`.
|
|
30
|
+
*
|
|
31
|
+
* @param {Float32Array} out destination, same layout as `data` (distinct buffer)
|
|
32
|
+
* @param {Float32Array} data source pixels, row-major, stride `channels`
|
|
33
|
+
* @param {Float32Array} variance per-texel luminance variance-of-mean, length width*height
|
|
34
|
+
* @param {Float32Array} normals per-texel world normal (3 per texel), length width*height*3
|
|
35
|
+
* @param {Uint8Array} coverage per-texel coverage (1 = valid), length width*height
|
|
36
|
+
* @param {number} width
|
|
37
|
+
* @param {number} height
|
|
38
|
+
* @param {number} channels values per texel (rgb[+a])
|
|
39
|
+
* @param {object} [options]
|
|
40
|
+
* @param {number} [options.radius] window half-size in texels (default 2)
|
|
41
|
+
* @param {number} [options.spatial_sigma] spatial Gaussian sigma in texels (default 1.5)
|
|
42
|
+
* @param {number} [options.beta] noise tolerance: how many stddevs count as "still noise" (default 3)
|
|
43
|
+
* @param {number} [options.normal_power] sharpness of the normal-similarity cutoff (default 8)
|
|
44
|
+
*/
|
|
45
|
+
export function lightmap_denoise(out, data, variance, normals, coverage, width, height, channels, options = {}) {
|
|
46
|
+
const radius = options.radius ?? 2;
|
|
47
|
+
const spatial_sigma = options.spatial_sigma ?? 1.5;
|
|
48
|
+
const beta = options.beta ?? 3;
|
|
49
|
+
const normal_power = options.normal_power ?? 8;
|
|
50
|
+
|
|
51
|
+
const inv_2_spatial = 1 / (2 * spatial_sigma * spatial_sigma);
|
|
52
|
+
|
|
53
|
+
// start as a copy so uncovered texels pass through untouched
|
|
54
|
+
out.set(data);
|
|
55
|
+
|
|
56
|
+
const acc = new Float64Array(channels);
|
|
57
|
+
|
|
58
|
+
for (let y = 0; y < height; y++) {
|
|
59
|
+
for (let x = 0; x < width; x++) {
|
|
60
|
+
const index = y * width + x;
|
|
61
|
+
|
|
62
|
+
if (coverage[index] === 0) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const center_base = index * channels;
|
|
67
|
+
const center_lum = rgb_to_luminance(data[center_base], data[center_base + 1], data[center_base + 2]);
|
|
68
|
+
const var_center = variance[index];
|
|
69
|
+
|
|
70
|
+
const n3 = index * 3;
|
|
71
|
+
const cnx = normals[n3];
|
|
72
|
+
const cny = normals[n3 + 1];
|
|
73
|
+
const cnz = normals[n3 + 2];
|
|
74
|
+
|
|
75
|
+
acc.fill(0);
|
|
76
|
+
let weight_sum = 0;
|
|
77
|
+
let contributing = 0; // neighbours that passed coverage + normal
|
|
78
|
+
let window = 0; // in-bounds window texels
|
|
79
|
+
|
|
80
|
+
const y0 = Math.max(0, y - radius);
|
|
81
|
+
const y1 = Math.min(height - 1, y + radius);
|
|
82
|
+
const x0 = Math.max(0, x - radius);
|
|
83
|
+
const x1 = Math.min(width - 1, x + radius);
|
|
84
|
+
|
|
85
|
+
for (let ny = y0; ny <= y1; ny++) {
|
|
86
|
+
for (let nx = x0; nx <= x1; nx++) {
|
|
87
|
+
window++;
|
|
88
|
+
const n_index = ny * width + nx;
|
|
89
|
+
if (coverage[n_index] === 0) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// normal similarity — never blend across an angular discontinuity
|
|
94
|
+
const nn3 = n_index * 3;
|
|
95
|
+
const dot = cnx * normals[nn3] + cny * normals[nn3 + 1] + cnz * normals[nn3 + 2];
|
|
96
|
+
if (dot <= 0) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const w_normal = Math.pow(dot, normal_power);
|
|
100
|
+
|
|
101
|
+
const dx = nx - x;
|
|
102
|
+
const dy = ny - y;
|
|
103
|
+
const w_spatial = Math.exp(-(dx * dx + dy * dy) * inv_2_spatial);
|
|
104
|
+
|
|
105
|
+
const n_base = n_index * channels;
|
|
106
|
+
const n_lum = rgb_to_luminance(data[n_base], data[n_base + 1], data[n_base + 2]);
|
|
107
|
+
const d_lum = n_lum - center_lum;
|
|
108
|
+
|
|
109
|
+
// noise stddev of the difference; the floor keeps an edge between
|
|
110
|
+
// two zero-variance texels sharp (any real difference -> weight ~0)
|
|
111
|
+
const sigma = Math.sqrt(var_center + variance[n_index]);
|
|
112
|
+
const tol = beta * sigma;
|
|
113
|
+
const w_range = Math.exp(-(d_lum * d_lum) / (2 * tol * tol + 1e-12));
|
|
114
|
+
|
|
115
|
+
const w = w_spatial * w_range * w_normal;
|
|
116
|
+
|
|
117
|
+
for (let c = 0; c < channels; c++) {
|
|
118
|
+
acc[c] += data[n_base + c] * w;
|
|
119
|
+
}
|
|
120
|
+
weight_sum += w;
|
|
121
|
+
contributing++;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// boundary-aware: a truncated/one-sided window (chart edge, or a crease
|
|
126
|
+
// that rejected half its neighbours) gives a biased average, so trust the
|
|
127
|
+
// texel's own value in proportion to how incomplete its support is.
|
|
128
|
+
const inv = weight_sum > 0 ? 1 / weight_sum : 0;
|
|
129
|
+
const alpha = window > 0 ? contributing / window : 0;
|
|
130
|
+
for (let c = 0; c < channels; c++) {
|
|
131
|
+
const denoised = acc[c] * inv;
|
|
132
|
+
out[center_base + c] = data[center_base + c] * (1 - alpha) + denoised * alpha;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grow ("dilate") covered texels outward into their uncovered neighbours, so that
|
|
3
|
+
* bilinear sampling across a chart boundary blends with valid lighting instead of
|
|
4
|
+
* the black background. This is the standard lightmap gutter/seam fix.
|
|
5
|
+
*
|
|
6
|
+
* Each iteration fills every uncovered texel that has at least one covered
|
|
7
|
+
* 4-neighbour with the average of those covered neighbours, then marks it covered
|
|
8
|
+
* for the next iteration. Operates in place on a flat, row-major, `channels`-wide
|
|
9
|
+
* pixel buffer.
|
|
10
|
+
*
|
|
11
|
+
* @param {Float32Array|number[]} data flat row-major pixel data, length width*height*channels
|
|
12
|
+
* @param {Uint8Array} coverage flat row-major coverage mask (1 = has valid lighting), mutated
|
|
13
|
+
* @param {number} width
|
|
14
|
+
* @param {number} height
|
|
15
|
+
* @param {number} channels values per texel
|
|
16
|
+
* @param {number} iterations how many texels of border to grow (≈ the atlas padding)
|
|
17
|
+
*/
|
|
18
|
+
export function lightmap_dilate(data: Float32Array | number[], coverage: Uint8Array, width: number, height: number, channels: number, iterations: number): void;
|
|
19
|
+
//# sourceMappingURL=lightmap_dilate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightmap_dilate.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_dilate.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,sCAPW,YAAY,GAAC,MAAM,EAAE,YACrB,UAAU,SACV,MAAM,UACN,MAAM,YACN,MAAM,cACN,MAAM,QA6DhB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grow ("dilate") covered texels outward into their uncovered neighbours, so that
|
|
3
|
+
* bilinear sampling across a chart boundary blends with valid lighting instead of
|
|
4
|
+
* the black background. This is the standard lightmap gutter/seam fix.
|
|
5
|
+
*
|
|
6
|
+
* Each iteration fills every uncovered texel that has at least one covered
|
|
7
|
+
* 4-neighbour with the average of those covered neighbours, then marks it covered
|
|
8
|
+
* for the next iteration. Operates in place on a flat, row-major, `channels`-wide
|
|
9
|
+
* pixel buffer.
|
|
10
|
+
*
|
|
11
|
+
* @param {Float32Array|number[]} data flat row-major pixel data, length width*height*channels
|
|
12
|
+
* @param {Uint8Array} coverage flat row-major coverage mask (1 = has valid lighting), mutated
|
|
13
|
+
* @param {number} width
|
|
14
|
+
* @param {number} height
|
|
15
|
+
* @param {number} channels values per texel
|
|
16
|
+
* @param {number} iterations how many texels of border to grow (≈ the atlas padding)
|
|
17
|
+
*/
|
|
18
|
+
export function lightmap_dilate(data, coverage, width, height, channels, iterations) {
|
|
19
|
+
const acc = new Float64Array(channels);
|
|
20
|
+
|
|
21
|
+
for (let iter = 0; iter < iterations; iter++) {
|
|
22
|
+
// texels that become covered this round; deferred so a single pass does not
|
|
23
|
+
// chain-fill along a row from a texel filled earlier in the same iteration
|
|
24
|
+
const newly = [];
|
|
25
|
+
|
|
26
|
+
for (let y = 0; y < height; y++) {
|
|
27
|
+
for (let x = 0; x < width; x++) {
|
|
28
|
+
const index = y * width + x;
|
|
29
|
+
|
|
30
|
+
if (coverage[index] !== 0) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
acc.fill(0);
|
|
35
|
+
let n = 0;
|
|
36
|
+
|
|
37
|
+
if (x > 0 && coverage[index - 1] !== 0) {
|
|
38
|
+
accumulate(acc, data, (index - 1) * channels, channels);
|
|
39
|
+
n++;
|
|
40
|
+
}
|
|
41
|
+
if (x < width - 1 && coverage[index + 1] !== 0) {
|
|
42
|
+
accumulate(acc, data, (index + 1) * channels, channels);
|
|
43
|
+
n++;
|
|
44
|
+
}
|
|
45
|
+
if (y > 0 && coverage[index - width] !== 0) {
|
|
46
|
+
accumulate(acc, data, (index - width) * channels, channels);
|
|
47
|
+
n++;
|
|
48
|
+
}
|
|
49
|
+
if (y < height - 1 && coverage[index + width] !== 0) {
|
|
50
|
+
accumulate(acc, data, (index + width) * channels, channels);
|
|
51
|
+
n++;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (n === 0) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const base = index * channels;
|
|
59
|
+
const inv = 1 / n;
|
|
60
|
+
for (let c = 0; c < channels; c++) {
|
|
61
|
+
data[base + c] = acc[c] * inv;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
newly.push(index);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (newly.length === 0) {
|
|
69
|
+
// fully grown, nothing left to reach
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (let i = 0; i < newly.length; i++) {
|
|
74
|
+
coverage[newly[i]] = 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {Float64Array} acc
|
|
81
|
+
* @param {Float32Array|number[]} data
|
|
82
|
+
* @param {number} offset
|
|
83
|
+
* @param {number} channels
|
|
84
|
+
*/
|
|
85
|
+
function accumulate(acc, data, offset, channels) {
|
|
86
|
+
for (let c = 0; c < channels; c++) {
|
|
87
|
+
acc[c] += data[offset + c];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estimate the lightmap value at a single surface point in **mixed mode**: the
|
|
3
|
+
* cosine-weighted average incoming radiance — indirect bounces + sky only (direct
|
|
4
|
+
* light is supplied at render time by the realtime lights, not baked).
|
|
5
|
+
*
|
|
6
|
+
* Reuses {@link PathTracer#path_trace} along cosine-weighted hemisphere directions
|
|
7
|
+
* ({@link getBiasedNormalSample}, power 1) — bounced light, emissive surfaces, and
|
|
8
|
+
* the environment. Each texel draws its own independent random directions (no fixed
|
|
9
|
+
* sample set is shared between texels, which would otherwise show as structured
|
|
10
|
+
* bias on flat surfaces).
|
|
11
|
+
*
|
|
12
|
+
* **Supersampling:** each sample's ray ORIGIN is jittered within the texel's world
|
|
13
|
+
* footprint (in the surface tangent plane, magnitude `cfg.supersample × texel`), so
|
|
14
|
+
* a texel straddling a shadow boundary or silhouette averages lit/occluded
|
|
15
|
+
* sub-positions into a soft gradient instead of a hard one-texel line.
|
|
16
|
+
*
|
|
17
|
+
* Also produces two auxiliary signals used by the baker:
|
|
18
|
+
* - the **variance of the mean** (luminance), written to `out[3]`, which drives
|
|
19
|
+
* the variance-guided denoiser;
|
|
20
|
+
* - a **confidence** in [0,1] (the return value): `1 - (fraction of short probes
|
|
21
|
+
* that hit a BACK face)`. Flags only buried/wrong-side points; an enclosed-room
|
|
22
|
+
* floor (front faces all around) stays confident. `cfg.confidence_probes === 0`
|
|
23
|
+
* disables it (confidence 1).
|
|
24
|
+
*
|
|
25
|
+
* The stored radiance is `E / π` (cosine-weighted mean); three.js's lightmap path
|
|
26
|
+
* multiplies it back by `π · albedo / π = albedo`, preserving surface colour.
|
|
27
|
+
*
|
|
28
|
+
* @param {Float32Array|number[]} out 4 channels written: linear r, g, b, luminance variance-of-mean
|
|
29
|
+
* @param {number} px world-space point x (already nudged off the surface)
|
|
30
|
+
* @param {number} py world-space point y
|
|
31
|
+
* @param {number} pz world-space point z
|
|
32
|
+
* @param {number} nx world-space surface normal x (unit)
|
|
33
|
+
* @param {number} ny world-space surface normal y
|
|
34
|
+
* @param {number} nz world-space surface normal z
|
|
35
|
+
* @param {number} texel_world_size world-space size of one lightmap texel at this point
|
|
36
|
+
* @param {PathTracedScene} scene
|
|
37
|
+
* @param {PathTracer} path_tracer
|
|
38
|
+
* @param {{samples:number, max_samples:number, variance_target:number, min_bounce:number, max_bounce:number, confidence_probes:number, inside_probe_texels:number, supersample:number}} cfg
|
|
39
|
+
* `samples` is the minimum count; sampling continues up to `max_samples` while the
|
|
40
|
+
* relative variance-of-mean exceeds `variance_target` (0 = fixed `samples`).
|
|
41
|
+
* @param {function():number} random
|
|
42
|
+
* @returns {number} confidence in [0,1]
|
|
43
|
+
*/
|
|
44
|
+
export function lightmap_gather(out: Float32Array | number[], px: number, py: number, pz: number, nx: number, ny: number, nz: number, texel_world_size: number, scene: PathTracedScene, path_tracer: PathTracer, cfg: {
|
|
45
|
+
samples: number;
|
|
46
|
+
max_samples: number;
|
|
47
|
+
variance_target: number;
|
|
48
|
+
min_bounce: number;
|
|
49
|
+
max_bounce: number;
|
|
50
|
+
confidence_probes: number;
|
|
51
|
+
inside_probe_texels: number;
|
|
52
|
+
supersample: number;
|
|
53
|
+
}, random: () => number): number;
|
|
54
|
+
//# sourceMappingURL=lightmap_gather.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightmap_gather.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_gather.js"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qCAhBW,YAAY,GAAC,MAAM,EAAE,MACrB,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,oBACN,MAAM;aAGG,MAAM;iBAAc,MAAM;qBAAkB,MAAM;gBAAa,MAAM;gBAAa,MAAM;uBAAoB,MAAM;yBAAsB,MAAM;iBAAc,MAAM;iBAGhK,MAAM,GACf,MAAM,CA6GlB"}
|