@woosh/meep-engine 3.13.0 → 3.14.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/README.md +257 -119
- package/editor/prototypeEditorShell.js +26 -2
- package/package.json +4 -3
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/ConvexHullShape3D.js +41 -25
- package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PosedShape3D.js +7 -2
- package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts +47 -0
- package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -0
- package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +109 -0
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts +28 -16
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +111 -92
- package/src/engine/graphics3/FogOfWarSystem.d.ts +1 -1
- package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
- package/src/engine/graphics3/FogOfWarSystem.js +1 -1
- package/src/engine/graphics3/HighlightOutlineSystem.d.ts +99 -0
- package/src/engine/graphics3/HighlightOutlineSystem.d.ts.map +1 -0
- package/src/engine/graphics3/HighlightOutlineSystem.js +240 -0
- package/src/engine/graphics3/HighlightSystem.d.ts +14 -77
- package/src/engine/graphics3/HighlightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/HighlightSystem.js +19 -233
- package/src/engine/graphics3/HighlightSystem3.d.ts +7 -4
- package/src/engine/graphics3/HighlightSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/HighlightSystem3.js +15 -10
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +13 -8
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.js +14 -8
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +579 -568
- package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +19 -14
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +1 -1
- package/src/shade/renderer/scene/Mesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/Mesh.js +4 -6
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +16 -7
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1342 -1322
- package/src/shade/renderer/shadow/map/Shadowmap.d.ts +13 -0
- package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/Shadowmap.js +14 -0
- package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts +79 -0
- package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.js +196 -0
- package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts +91 -0
- package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/ShadowmapRegistry.js +156 -0
- package/src/engine/graphics/ecs/highlight/plugin/HighlightRenderElementSource.d.ts +0 -9
- package/src/engine/graphics/ecs/highlight/plugin/HighlightRenderElementSource.d.ts.map +0 -1
- package/src/engine/graphics/ecs/highlight/plugin/HighlightRenderElementSource.js +0 -12
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderElement.d.ts +0 -16
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderElement.d.ts.map +0 -1
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderElement.js +0 -44
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderGroup.d.ts +0 -20
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderGroup.d.ts.map +0 -1
- package/src/engine/graphics/ecs/highlight/renderer/HighlightRenderGroup.js +0 -29
- package/src/engine/graphics/ecs/highlight/renderer/makeGaussianBlurShader.d.ts +0 -8
- package/src/engine/graphics/ecs/highlight/renderer/makeGaussianBlurShader.d.ts.map +0 -1
- package/src/engine/graphics/ecs/highlight/renderer/makeGaussianBlurShader.js +0 -58
- package/src/engine/graphics/ecs/highlight/renderer/traverseThreeObject.d.ts +0 -8
- package/src/engine/graphics/ecs/highlight/renderer/traverseThreeObject.d.ts.map +0 -1
- package/src/engine/graphics/ecs/highlight/renderer/traverseThreeObject.js +0 -18
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_scalar_2Dx1Dx1D_128x128x64x1_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec1_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec2_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_cosine_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64.dat +0 -1
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_unitvec3_forest_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec1_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec2_2Dx1D_128x128x64_9.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64.dat +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64.mag.xy.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64.mag.xz.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_0.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_1.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_10.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_11.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_12.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_13.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_14.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_15.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_16.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_17.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_18.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_19.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_2.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_20.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_21.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_22.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_23.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_24.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_25.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_26.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_27.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_28.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_29.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_3.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_30.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_31.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_32.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_33.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_34.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_35.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_36.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_37.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_38.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_39.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_4.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_40.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_41.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_42.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_43.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_44.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_45.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_46.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_47.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_48.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_49.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_5.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_50.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_51.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_52.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_53.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_54.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_55.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_56.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_57.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_58.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_59.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_6.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_60.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_61.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_62.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_63.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_7.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_8.png +0 -0
- package/src/shade/renderer/texture/noise/stbn/images/stbn_vec3_2Dx1D_128x128x64_9.png +0 -0
|
@@ -1,1322 +1,1342 @@
|
|
|
1
|
-
import { assert } from "../../../../core/assert.js";
|
|
2
|
-
import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
|
|
3
|
-
import { MaxRectanglesPacker } from "../../../../core/geom/packing/max-rect/MaxRectanglesPacker.js";
|
|
4
|
-
import { FrameGraph } from "../../../../engine/graphics/render/frame_graph/FrameGraph.js";
|
|
5
|
-
import { TextureResourceDescriptor } from "../../../device/graph/TextureResourceDescriptor.js";
|
|
6
|
-
import { CameraManager } from "../../camera/CameraManager.js";
|
|
7
|
-
import { OrthographicCamera } from "../../camera/OrthographicCamera.js";
|
|
8
|
-
import { PerspectiveCamera } from "../../camera/PerspectiveCamera.js";
|
|
9
|
-
import { CullPolicy } from "../../rasterize/bucket/construct_primitive_state.js";
|
|
10
|
-
import { graph_mesh_sphere_cull } from "../../rasterize/compute/graph_mesh_sphere_cull.js";
|
|
11
|
-
import { execute_rasterization_jobs } from "../../rasterize/execute_rasterization_jobs.js";
|
|
12
|
-
import {
|
|
13
|
-
shadow_rasterization_alpha_tested_pass_descriptor
|
|
14
|
-
} from "../../rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js";
|
|
15
|
-
import {
|
|
16
|
-
shadow_rasterization_pass_descriptor
|
|
17
|
-
} from "../../rasterize/native/depth/shadow_rasterization_pass_descriptor.js";
|
|
18
|
-
import { RasterizationJob, RasterizationPipelineType } from "../../rasterize/RasterizationJob.js";
|
|
19
|
-
import { graph_rasterize_scene_fast_raw } from "../../rasterize/fast/graph_rasterize_scene_fast.js";
|
|
20
|
-
import { graph_create_texture, graph_import_texture } from "../../shader/graph/graph_import_texture.js";
|
|
21
|
-
import { GPUTextureContext } from "../../texture/GPUTextureContext.js";
|
|
22
|
-
import { RenderTarget } from "../../texture/RenderTarget.js";
|
|
23
|
-
import { View } from "../../view/View.js";
|
|
24
|
-
import { ViewManager } from "../../view/ViewManager.js";
|
|
25
|
-
import { SHADOWMAP_CSM_CASCADE_COUNT } from "./csm/SHADOWMAP_CSM_CASCADE_COUNT.js";
|
|
26
|
-
import { DirectionalLightShadowmap } from "./DirectionalLightShadowmap.js";
|
|
27
|
-
import { POINT_SHADOW_CUBE_COLS, POINT_SHADOW_CUBE_ROWS } from "./POINT_SHADOW_CUBE_LAYOUT.js";
|
|
28
|
-
import {
|
|
29
|
-
POINT_SHADOW_TETRA_COLS,
|
|
30
|
-
POINT_SHADOW_TETRA_FACE_COUNT,
|
|
31
|
-
POINT_SHADOW_TETRA_MAPPING_RESOLUTION_SCALE,
|
|
32
|
-
POINT_SHADOW_TETRA_ROWS,
|
|
33
|
-
} from "./POINT_SHADOW_TETRAHEDRON_LAYOUT.js";
|
|
34
|
-
import { PointLightShadowmap } from "./PointLightShadowmap.js";
|
|
35
|
-
import {
|
|
36
|
-
shader_shadowmap_remap_cube_to_octahedral
|
|
37
|
-
} from "./shader/shader_shadowmap_remap_cube_to_octahedral.js";
|
|
38
|
-
import {
|
|
39
|
-
POINT_SHADOW_TETRA_REMAP_SETTINGS,
|
|
40
|
-
shader_shadowmap_remap_tetrahedron_to_octahedral
|
|
41
|
-
} from "./shader/shader_shadowmap_remap_tetrahedron_to_octahedral.js";
|
|
42
|
-
import { SHADOWMAP_ATLAS_BORDER } from "./SHADOWMAP_ATLAS_BORDER.js";
|
|
43
|
-
import { TetrahedronPointLightShadowmap } from "./TetrahedronPointLightShadowmap.js";
|
|
44
|
-
import { compute_light_projected_area_px
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
*
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*
|
|
120
|
-
* @
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
*
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* @type {
|
|
175
|
-
*/
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
*
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
*
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
* records
|
|
244
|
-
* @
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
*
|
|
254
|
-
* @
|
|
255
|
-
*
|
|
256
|
-
*/
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
{
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
this.#
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
//
|
|
598
|
-
//
|
|
599
|
-
|
|
600
|
-
if (
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
atlas_rect.
|
|
840
|
-
atlas_rect.
|
|
841
|
-
atlas_rect.
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
//
|
|
906
|
-
// per-face
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
]
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
*
|
|
1045
|
-
*
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
*
|
|
1067
|
-
*
|
|
1068
|
-
*
|
|
1069
|
-
*
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
if (
|
|
1136
|
-
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
const map =
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
//
|
|
1263
|
-
//
|
|
1264
|
-
//
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
|
|
3
|
+
import { MaxRectanglesPacker } from "../../../../core/geom/packing/max-rect/MaxRectanglesPacker.js";
|
|
4
|
+
import { FrameGraph } from "../../../../engine/graphics/render/frame_graph/FrameGraph.js";
|
|
5
|
+
import { TextureResourceDescriptor } from "../../../device/graph/TextureResourceDescriptor.js";
|
|
6
|
+
import { CameraManager } from "../../camera/CameraManager.js";
|
|
7
|
+
import { OrthographicCamera } from "../../camera/OrthographicCamera.js";
|
|
8
|
+
import { PerspectiveCamera } from "../../camera/PerspectiveCamera.js";
|
|
9
|
+
import { CullPolicy } from "../../rasterize/bucket/construct_primitive_state.js";
|
|
10
|
+
import { graph_mesh_sphere_cull } from "../../rasterize/compute/graph_mesh_sphere_cull.js";
|
|
11
|
+
import { execute_rasterization_jobs } from "../../rasterize/execute_rasterization_jobs.js";
|
|
12
|
+
import {
|
|
13
|
+
shadow_rasterization_alpha_tested_pass_descriptor
|
|
14
|
+
} from "../../rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js";
|
|
15
|
+
import {
|
|
16
|
+
shadow_rasterization_pass_descriptor
|
|
17
|
+
} from "../../rasterize/native/depth/shadow_rasterization_pass_descriptor.js";
|
|
18
|
+
import { RasterizationJob, RasterizationPipelineType } from "../../rasterize/RasterizationJob.js";
|
|
19
|
+
import { graph_rasterize_scene_fast_raw } from "../../rasterize/fast/graph_rasterize_scene_fast.js";
|
|
20
|
+
import { graph_create_texture, graph_import_texture } from "../../shader/graph/graph_import_texture.js";
|
|
21
|
+
import { GPUTextureContext } from "../../texture/GPUTextureContext.js";
|
|
22
|
+
import { RenderTarget } from "../../texture/RenderTarget.js";
|
|
23
|
+
import { View } from "../../view/View.js";
|
|
24
|
+
import { ViewManager } from "../../view/ViewManager.js";
|
|
25
|
+
import { SHADOWMAP_CSM_CASCADE_COUNT } from "./csm/SHADOWMAP_CSM_CASCADE_COUNT.js";
|
|
26
|
+
import { DirectionalLightShadowmap } from "./DirectionalLightShadowmap.js";
|
|
27
|
+
import { POINT_SHADOW_CUBE_COLS, POINT_SHADOW_CUBE_ROWS } from "./POINT_SHADOW_CUBE_LAYOUT.js";
|
|
28
|
+
import {
|
|
29
|
+
POINT_SHADOW_TETRA_COLS,
|
|
30
|
+
POINT_SHADOW_TETRA_FACE_COUNT,
|
|
31
|
+
POINT_SHADOW_TETRA_MAPPING_RESOLUTION_SCALE,
|
|
32
|
+
POINT_SHADOW_TETRA_ROWS,
|
|
33
|
+
} from "./POINT_SHADOW_TETRAHEDRON_LAYOUT.js";
|
|
34
|
+
import { PointLightShadowmap } from "./PointLightShadowmap.js";
|
|
35
|
+
import {
|
|
36
|
+
shader_shadowmap_remap_cube_to_octahedral
|
|
37
|
+
} from "./shader/shader_shadowmap_remap_cube_to_octahedral.js";
|
|
38
|
+
import {
|
|
39
|
+
POINT_SHADOW_TETRA_REMAP_SETTINGS,
|
|
40
|
+
shader_shadowmap_remap_tetrahedron_to_octahedral
|
|
41
|
+
} from "./shader/shader_shadowmap_remap_tetrahedron_to_octahedral.js";
|
|
42
|
+
import { SHADOWMAP_ATLAS_BORDER } from "./SHADOWMAP_ATLAS_BORDER.js";
|
|
43
|
+
import { TetrahedronPointLightShadowmap } from "./TetrahedronPointLightShadowmap.js";
|
|
44
|
+
import { compute_light_projected_area_px } from "./shadowmap_update_score.js";
|
|
45
|
+
import { ShadowmapDrawSelector } from "./ShadowmapDrawSelector.js";
|
|
46
|
+
import { ShadowmapRegistry } from "./ShadowmapRegistry.js";
|
|
47
|
+
import { ShadowmapResolutionPolicy } from "./ShadowmapResolutionPolicy.js";
|
|
48
|
+
import { SpotLightShadowmap } from "./SpotLightShadowmap.js";
|
|
49
|
+
|
|
50
|
+
const DEFAULT_SHADOWMAP_ATLAS_RESOLUTION = 4096 * 2;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Resolution by cascade.
|
|
54
|
+
* If the number of cascades is greater than the array length, the last resolution is used.
|
|
55
|
+
* @type {number[]}
|
|
56
|
+
*/
|
|
57
|
+
const DEFAULT_SHADOWMAP_DIRECTIONAL_RESOLUTION = [
|
|
58
|
+
1740, // first cascade
|
|
59
|
+
1440,
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Placeholder resolution for local-light shadowmaps (spot/point).
|
|
64
|
+
* A proper implementation will project the light's bounding volume into screen space to derive this at runtime.
|
|
65
|
+
* @type {number}
|
|
66
|
+
*/
|
|
67
|
+
const DEFAULT_SHADOWMAP_LOCAL_RESOLUTION = 128;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Per-frame shadow refresh budget, measured in **views** (one cube face counts as one view,
|
|
71
|
+
* one CSM cascade counts as one view, etc.). A point light costs 6 views, a spot light 1, a
|
|
72
|
+
* directional SHADOWMAP_CSM_CASCADE_COUNT. A bigger light consumes more of the budget, which
|
|
73
|
+
* keeps the cost of the refresh step roughly proportional to how much work we're asking the
|
|
74
|
+
* GPU to do — a single point light running the meshlet rasterization pipeline 6 times is
|
|
75
|
+
* equivalent work to 6 spot lights.
|
|
76
|
+
*
|
|
77
|
+
* Directional lights are always refreshed unconditionally (they drive the whole scene) and
|
|
78
|
+
* their view cost is charged against the budget, so they effectively reduce the pool available
|
|
79
|
+
* for local lights that frame.
|
|
80
|
+
*
|
|
81
|
+
* Unused budget is carried over between frames when demand exceeds supply — see
|
|
82
|
+
* {@link GPUSceneShadowmapContext.#budget_carry_over}. This lets a light that's too expensive
|
|
83
|
+
* to fit in a single frame (e.g. a point needing 6 views when only 2 are free) eventually get
|
|
84
|
+
* its turn without permanently starving other lights.
|
|
85
|
+
* @type {number}
|
|
86
|
+
*/
|
|
87
|
+
const SHADOWMAP_UPDATE_BUDGET = 8;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Shadows for a single scene
|
|
91
|
+
*/
|
|
92
|
+
export class GPUSceneShadowmapContext {
|
|
93
|
+
atlas = new MaxRectanglesPacker(DEFAULT_SHADOWMAP_ATLAS_RESOLUTION, DEFAULT_SHADOWMAP_ATLAS_RESOLUTION);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Depth texture atlas used for shadowmaps.
|
|
97
|
+
* @type {GPUTextureContext}
|
|
98
|
+
*/
|
|
99
|
+
texture;
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @type {GraphicsContext}
|
|
104
|
+
*/
|
|
105
|
+
#graphics;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Dedicated ViewManager for the cube/cascade/perspective shadow views this context
|
|
109
|
+
* creates and rasterizes into the atlas. Decoupled from the renderer-level ViewManager
|
|
110
|
+
* so the ownership chain stays self-contained — the shadow context creates the views,
|
|
111
|
+
* caches their GPU contexts, and disposes them with itself. The shared SceneManager
|
|
112
|
+
* lookup is short-circuited with a tiny object that always returns our owning
|
|
113
|
+
* GPUSceneContext (every shadow view here is for the same scene by construction).
|
|
114
|
+
* @type {ViewManager}
|
|
115
|
+
*/
|
|
116
|
+
shadow_view_manager;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Internal CameraManager backing {@link shadow_view_manager}. Shadow cameras are
|
|
120
|
+
* created locally in {@link process_lights} and only referenced by this context, so
|
|
121
|
+
* they don't need to share the renderer-level CameraManager.
|
|
122
|
+
* @type {CameraManager}
|
|
123
|
+
*/
|
|
124
|
+
#cameras;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @type {RenderTarget}
|
|
128
|
+
*/
|
|
129
|
+
#render_target;
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Every shadowmap this scene holds, plus the light -> map index and the reconciliation marks
|
|
134
|
+
* that make {@link process_lights} O(lights + maps) instead of O(lights x maps).
|
|
135
|
+
* @type {ShadowmapRegistry}
|
|
136
|
+
*/
|
|
137
|
+
#registry = new ShadowmapRegistry();
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Scores and picks the maps to refresh each frame. Holds the heap it selects with across
|
|
141
|
+
* frames, so the per-frame scoring allocates nothing.
|
|
142
|
+
* @type {ShadowmapDrawSelector}
|
|
143
|
+
*/
|
|
144
|
+
#selector = new ShadowmapDrawSelector();
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Scratch list of lights that need a shadowmap allocated, handed from pass 1 of
|
|
148
|
+
* {@link process_lights} to pass 3. Held across frames rather than allocated per call — it is
|
|
149
|
+
* empty on every frame where the light set didn't move, which is nearly all of them.
|
|
150
|
+
* @type {Light[]}
|
|
151
|
+
*/
|
|
152
|
+
#reconcile_newcomers = [];
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Master kill switch for shadows on this scene. Defaults true; the renderer sets it from
|
|
156
|
+
* its own `feature_shadows_enabled` flag before each frame's light update. When false,
|
|
157
|
+
* {@link process_lights} evicts all maps so the next light-record build clears
|
|
158
|
+
* CASTS_SHADOW_BIT on every light. {@link select_for_draw} and {@link draw} are still
|
|
159
|
+
* gated externally by the renderer; this flag exists to keep the GPU light records in
|
|
160
|
+
* sync with that gating without needing to thread the renderer's flag down further.
|
|
161
|
+
* @type {boolean}
|
|
162
|
+
*/
|
|
163
|
+
enabled = true;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Selects the tetrahedral point-light shadow generator (4 face frusta) over the default
|
|
167
|
+
* cube generator (6 faces). The renderer pushes this from its
|
|
168
|
+
* `feature_tetrahedron_point_shadows` flag before each light update, alongside {@link enabled}.
|
|
169
|
+
*
|
|
170
|
+
* Only affects how a point light's shadow is GENERATED — both paths remap into the same
|
|
171
|
+
* octahedral atlas encoding, so the sampler is identical and this can be toggled at runtime.
|
|
172
|
+
* A flip is picked up in {@link process_lights}: existing point maps whose generator no longer
|
|
173
|
+
* matches this flag are evicted and rebuilt with the correct face count on the same pass.
|
|
174
|
+
* @type {boolean}
|
|
175
|
+
*/
|
|
176
|
+
use_tetrahedron_point_shadows = false;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Frame index of the most recent {@link select_for_draw} call. Passed to {@link draw} via
|
|
180
|
+
* this field so we don't have to thread it through the call again — draw() stamps
|
|
181
|
+
* `map.last_updated_frame_index` with this value after each successful rasterization.
|
|
182
|
+
* @type {number}
|
|
183
|
+
*/
|
|
184
|
+
#current_frame_index = -1;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* View-budget surplus carried forward from prior frames. Accumulates whenever we had
|
|
188
|
+
* non-directional candidates that couldn't fit in the per-frame budget (i.e. a point light
|
|
189
|
+
* wanted 6 views but only 2 were free after directionals + earlier locals consumed their
|
|
190
|
+
* share). Resets to 0 on any frame where the full demand was satisfied, so the carryover
|
|
191
|
+
* doesn't grow unboundedly when the scene is quiet.
|
|
192
|
+
* @type {number}
|
|
193
|
+
*/
|
|
194
|
+
#budget_carry_over = 0;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Adjusts per-map atlas footprints each frame based on projected on-screen area. Lazily
|
|
198
|
+
* tied to {@link atlas} in the constructor.
|
|
199
|
+
* @type {ShadowmapResolutionPolicy}
|
|
200
|
+
*/
|
|
201
|
+
#resolution_policy;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Number of shadowmaps actually rasterized by the most recent {@link draw} call. Reset at
|
|
205
|
+
* the start of draw(), incremented once per map that went through the raster path. Exposed
|
|
206
|
+
* for debugging scheduling behaviour — a persistently oscillating value (e.g. 36/20/15
|
|
207
|
+
* repeating) indicates some maps are being invalidated every frame and forcing a redraw,
|
|
208
|
+
* which usually means the resolution policy or selector is churning.
|
|
209
|
+
* @type {number}
|
|
210
|
+
*/
|
|
211
|
+
#debug_render_count = 0;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @returns {number} number of shadowmaps rasterized in the most recent draw pass
|
|
215
|
+
*/
|
|
216
|
+
get debug_render_count() {
|
|
217
|
+
return this.#debug_render_count;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Most recently measured atlas occupancy (placed area / total area, including pending
|
|
222
|
+
* reservations), in [0, 1]. Forwards from the resolution policy. Useful for the debug
|
|
223
|
+
* overlay alongside {@link debug_drop_size_scale} — together they show whether the global
|
|
224
|
+
* shrink/grow feedback has converged or is still chasing the target band.
|
|
225
|
+
* @returns {number}
|
|
226
|
+
*/
|
|
227
|
+
get debug_atlas_occupancy() {
|
|
228
|
+
return this.#resolution_policy.last_occupancy;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Current value of the global drop-size scale applied by the resolution policy. 1 means no
|
|
233
|
+
* shrink; values below 1 mean atlas pressure has trimmed every light's target size
|
|
234
|
+
* proportionally. Forwarded from the resolution policy for debug overlays.
|
|
235
|
+
* @returns {number}
|
|
236
|
+
*/
|
|
237
|
+
get debug_drop_size_scale() {
|
|
238
|
+
return this.#resolution_policy.drop_size_scale;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Per-type counts of shadow records written to the GPU database in the previous
|
|
244
|
+
* {@link draw} pass. Used to identify trailing slots that must be zeroed when the
|
|
245
|
+
* map count for a given type shrinks (e.g. a shadow-casting light is removed),
|
|
246
|
+
* mirroring the bookkeeping in {@link GPULightCollection.#build}.
|
|
247
|
+
*/
|
|
248
|
+
#prev_point_count = 0;
|
|
249
|
+
#prev_spot_count = 0;
|
|
250
|
+
#prev_directional_count = 0;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* The Scene this context manages shadows for. Captured at construction so
|
|
254
|
+
* {@link process_lights} doesn't need it threaded back through every frame.
|
|
255
|
+
* @type {Scene}
|
|
256
|
+
*/
|
|
257
|
+
#scene;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Owning light collection — gives us access to the GPU database where shadow
|
|
261
|
+
* records live and to the source LightCollection. Set in the constructor.
|
|
262
|
+
* @type {GPULightCollection}
|
|
263
|
+
*/
|
|
264
|
+
#owner;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
*
|
|
268
|
+
* @param {GraphicsContext} graphics
|
|
269
|
+
* @param {GPUSceneContext} scene_ctx the GPU-side context for the Scene we manage
|
|
270
|
+
* shadows for. Used as the (single) destination of {@link shadow_view_manager}'s
|
|
271
|
+
* scene lookup — every shadow view is for this scene, so the lookup short-circuits.
|
|
272
|
+
* @param {GPULightCollection} owner the parent light collection — gives us back-access
|
|
273
|
+
* to the GPU database we publish records into during {@link draw}.
|
|
274
|
+
*/
|
|
275
|
+
constructor(
|
|
276
|
+
graphics,
|
|
277
|
+
scene_ctx,
|
|
278
|
+
owner,
|
|
279
|
+
) {
|
|
280
|
+
assert.defined(graphics, 'graphics');
|
|
281
|
+
assert.defined(scene_ctx, 'scene_ctx');
|
|
282
|
+
assert.equal(scene_ctx.isGPUSceneContext, true, 'scene_ctx.isGPUSceneContext !== true');
|
|
283
|
+
assert.defined(owner, 'owner');
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
const initial_atlas_resolution = Math.min(
|
|
287
|
+
graphics.device.limits.maxTextureDimension2D,
|
|
288
|
+
DEFAULT_SHADOWMAP_ATLAS_RESOLUTION,
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
{
|
|
292
|
+
const t = this.texture = new GPUTextureContext(graphics.device);
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
const descriptor = t.descriptor;
|
|
296
|
+
|
|
297
|
+
descriptor.format = "depth32float";
|
|
298
|
+
descriptor.dimension = "2d";
|
|
299
|
+
descriptor.label = "Shadowmap atlas";
|
|
300
|
+
descriptor.usage = GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC;
|
|
301
|
+
|
|
302
|
+
t.resize(
|
|
303
|
+
initial_atlas_resolution,
|
|
304
|
+
initial_atlas_resolution
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
// ensure atlas size matches
|
|
308
|
+
this.atlas.resize(
|
|
309
|
+
initial_atlas_resolution,
|
|
310
|
+
initial_atlas_resolution
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this.#graphics = graphics;
|
|
315
|
+
this.#scene = scene_ctx.scene;
|
|
316
|
+
this.#owner = owner;
|
|
317
|
+
|
|
318
|
+
// Local CameraManager + ViewManager dedicated to shadow rasterization. We don't
|
|
319
|
+
// share with the renderer-level managers because the cameras and views here are
|
|
320
|
+
// owned by this context and only referenced from inside it. The "scenes" lookup
|
|
321
|
+
// is a stub that always returns the owning scene context — every shadow view is
|
|
322
|
+
// for `this.#scene` by construction.
|
|
323
|
+
this.#cameras = new CameraManager(graphics.device);
|
|
324
|
+
this.shadow_view_manager = new ViewManager(graphics, this.#cameras, {
|
|
325
|
+
obtain: () => scene_ctx,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
this.#render_target = RenderTarget.from({
|
|
329
|
+
depth: this.texture,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
this.#resolution_policy = new ShadowmapResolutionPolicy(this.atlas);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
*
|
|
337
|
+
* @param {Light} light
|
|
338
|
+
* @returns {Shadowmap|undefined}
|
|
339
|
+
*/
|
|
340
|
+
get_map(light) {
|
|
341
|
+
return this.#registry.get(light);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Decide which shadowmaps should be rasterized this frame.
|
|
346
|
+
*
|
|
347
|
+
* Runs at the top of every frame, before {@link draw}. Responsibilities:
|
|
348
|
+
*
|
|
349
|
+
* 1. **Reset per-frame signals.** `should_draw` is cleared on every map so a stale "yes"
|
|
350
|
+
* from a prior frame can never cause a spurious extra raster. Folded into the selector's
|
|
351
|
+
* scoring pass, which walks every map anyway.
|
|
352
|
+
* 2. **Measure on-screen presence.** `projected_area_px` is computed once per map and stored
|
|
353
|
+
* on the map itself — consumed by the resolution policy, the scorer, and the selector,
|
|
354
|
+
* and exposed for debug tooling.
|
|
355
|
+
* 3. **Reserve pending atlas footprints.** {@link ShadowmapResolutionPolicy.adjust} may
|
|
356
|
+
* attach a `pending_layout` to maps whose projected area has shifted enough to warrant a
|
|
357
|
+
* resize. The committed `layout` is left untouched so sampling remains valid; the
|
|
358
|
+
* pending is consumed later by {@link draw} when the scheduler naturally picks this map
|
|
359
|
+
* up (no forced redraw).
|
|
360
|
+
* 4. **Score + select.** Delegated to {@link ShadowmapDrawSelector}, which sets `should_draw`
|
|
361
|
+
* on the winners and reports the view spend and whether any candidate went unmet:
|
|
362
|
+
* - **Directional** → always selected (infinite score); view cost still charged.
|
|
363
|
+
* - **Local, off-screen** (`projected_area_px <= 0`) → skipped entirely.
|
|
364
|
+
* - **Local, in-view, invalid** → MUST draw. `is_invalid` means the committed layout
|
|
365
|
+
* has never held valid depth (freshly created map); sampling it would display
|
|
366
|
+
* garbage, so we bypass the budget. Resizes no longer invalidate under the dual-
|
|
367
|
+
* layout model — this flag fires only on first-draw.
|
|
368
|
+
* - **Local, in-view, valid** → compete for the remaining budget by score. Ordering
|
|
369
|
+
* is descending score so the most important (largest-on-screen, stalest) maps win.
|
|
370
|
+
* 5. **Fit the winners.** `map.update()` on each selected map, so its projection matrices
|
|
371
|
+
* reflect the current frame. The `last_updated_frame_index` stamp is deferred to
|
|
372
|
+
* {@link draw} — it records when the atlas contents become current, not when the
|
|
373
|
+
* projection is fitted.
|
|
374
|
+
*
|
|
375
|
+
* Shadow records are NOT written here; they're written at the end of {@link draw} so the
|
|
376
|
+
* shader reads slots that reflect any just-committed pending swaps within the same frame.
|
|
377
|
+
*
|
|
378
|
+
* See {@link compute_shadowmap_update_score} for the scoring formula and rationale, and
|
|
379
|
+
* {@link ShadowmapDrawSelector} for why the ordering is a heap drain rather than a sort.
|
|
380
|
+
*
|
|
381
|
+
* @param {Camera} main_camera used both for rendering the final frame and for projected-area
|
|
382
|
+
* computation and directional CSM fit; must be callable for `.update()`
|
|
383
|
+
* @param {GPUSceneContext} scene
|
|
384
|
+
* @param {number} frame_index monotonically increasing frame counter, used for staleness
|
|
385
|
+
* @param {ArrayLike<number>} view_resolution [width, height] of the main view in pixels; used
|
|
386
|
+
* to convert projected sphere extents into a pixel-area score
|
|
387
|
+
*/
|
|
388
|
+
select_for_draw(main_camera, scene, frame_index, view_resolution) {
|
|
389
|
+
assert.defined(main_camera, 'main_camera');
|
|
390
|
+
assert.isObject(main_camera, 'main_camera');
|
|
391
|
+
assert.equal(scene.isGPUSceneContext, true, 'scene.isGPUSceneContext !== true');
|
|
392
|
+
assert.isNumber(frame_index, 'frame_index');
|
|
393
|
+
assert.defined(view_resolution, 'view_resolution');
|
|
394
|
+
|
|
395
|
+
// make sure the camera is updated — both our scoring (projected area) and any downstream
|
|
396
|
+
// map.update() reads depend on view/projection matrices being current
|
|
397
|
+
main_camera.update();
|
|
398
|
+
|
|
399
|
+
this.#current_frame_index = frame_index;
|
|
400
|
+
|
|
401
|
+
const shadowmaps = this.#registry.maps;
|
|
402
|
+
const n = shadowmaps.length;
|
|
403
|
+
|
|
404
|
+
// Step 1 (clearing the stale per-frame `should_draw`) happens inside the selector's own
|
|
405
|
+
// scoring pass, so there is no separate walk for it here.
|
|
406
|
+
|
|
407
|
+
// Step 2: recompute projected areas. Writing onto the map so the policy + scorer can
|
|
408
|
+
// just read `map.projected_area_px` without threading a parallel array through.
|
|
409
|
+
for (let i = 0; i < n; i++) {
|
|
410
|
+
const m = shadowmaps[i];
|
|
411
|
+
m.projected_area_px = compute_light_projected_area_px(m.light, main_camera, view_resolution);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Step 3: policy reserves pending resize footprints alongside committed layouts. It
|
|
415
|
+
// never mutates layout and never invalidates — sampling continues against the old
|
|
416
|
+
// region until draw() commits the pending during a normal raster pass. Directionals and
|
|
417
|
+
// off-screen locals are skipped (off-screen locals also get any stale pending released
|
|
418
|
+
// so an idle reservation can't tie up atlas space).
|
|
419
|
+
this.#resolution_policy.adjust(shadowmaps, frame_index);
|
|
420
|
+
|
|
421
|
+
// Steps 4 and 5: score every map and greedy-fill the view budget in score order. See
|
|
422
|
+
// ShadowmapDrawSelector for why this is a heap drain rather than a sort — the budget
|
|
423
|
+
// consumes a handful of winners out of however many candidates the scene has.
|
|
424
|
+
const budget_total = SHADOWMAP_UPDATE_BUDGET + this.#budget_carry_over;
|
|
425
|
+
const selector = this.#selector;
|
|
426
|
+
|
|
427
|
+
selector.select(shadowmaps, frame_index, budget_total);
|
|
428
|
+
|
|
429
|
+
// Fit the winners' projections to the current frame. Kept out of the selector because it
|
|
430
|
+
// needs the camera and the scene, and the selector is deliberately free of both.
|
|
431
|
+
//
|
|
432
|
+
// Maps that lost keep their prior metadata + atlas contents — a never-refreshed map
|
|
433
|
+
// samples the initial depth-cleared rect, which reads as "fully lit" under the reverse-Z
|
|
434
|
+
// greater compare. Acceptable behavior until the map eventually wins a slot.
|
|
435
|
+
const selected = selector.selected;
|
|
436
|
+
for (let i = 0; i < selected.length; i++) {
|
|
437
|
+
selected[i].update(main_camera, scene);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Carry over the unused pool only when there was demand we couldn't meet. When the whole
|
|
441
|
+
// scene's demand was satisfied, reset to 0 so idle frames don't inflate the pool. If
|
|
442
|
+
// must-draw bypasses over-spent the pool (views_spent > budget_total), clamp at zero —
|
|
443
|
+
// we can't owe future frames for past over-spend, that way lies runaway starvation.
|
|
444
|
+
if (selector.had_unfit_candidates) {
|
|
445
|
+
this.#budget_carry_over = Math.max(0, budget_total - selector.views_spent);
|
|
446
|
+
} else {
|
|
447
|
+
this.#budget_carry_over = 0;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Publish per-shadowmap records into the scene's GPU database. Each map writes its record
|
|
453
|
+
* into the type-specific shadow_* table at the slot identified by `light._gpu_shadowmap_id`
|
|
454
|
+
* (which is itself the per-type index, set by {@link process_lights}). Trailing slots from
|
|
455
|
+
* previous frames are zeroed when the map count for a type shrinks, so stale entries don't
|
|
456
|
+
* linger.
|
|
457
|
+
*
|
|
458
|
+
* Only maps with `metadata_changed === true` are re-uploaded; the flag is cleared after
|
|
459
|
+
* the slot is queued so unchanged maps don't pay for an upload they don't need. Trim writes
|
|
460
|
+
* always run regardless of the flag — they zero slots that no longer correspond to any map.
|
|
461
|
+
*
|
|
462
|
+
* The type-bucket order here MUST match the per-type id assignment in {@link process_lights}
|
|
463
|
+
* (Point → Spot → Directional) so the shadow_id stamped onto each light record points at the
|
|
464
|
+
* slot we write here.
|
|
465
|
+
*
|
|
466
|
+
* Caller must invoke `database.update(cmd)` afterwards to upload the writes — that is done
|
|
467
|
+
* by {@link draw} once for both the new records and any zeroed trailing slots.
|
|
468
|
+
*
|
|
469
|
+
* @param {GPUDatabase} database
|
|
470
|
+
*/
|
|
471
|
+
#write_shadow_records(database) {
|
|
472
|
+
const t_point = database.get('shadow_point');
|
|
473
|
+
const t_spot = database.get('shadow_spot');
|
|
474
|
+
const t_directional = database.get('shadow_directional');
|
|
475
|
+
|
|
476
|
+
const maps = this.#registry.maps;
|
|
477
|
+
let pc = 0;
|
|
478
|
+
let sc = 0;
|
|
479
|
+
let dc = 0;
|
|
480
|
+
|
|
481
|
+
for (let i = 0; i < maps.length; i++) {
|
|
482
|
+
const map = maps[i];
|
|
483
|
+
const light = map.light;
|
|
484
|
+
|
|
485
|
+
let table;
|
|
486
|
+
let slot;
|
|
487
|
+
if (light.isPointLight) {
|
|
488
|
+
table = t_point;
|
|
489
|
+
slot = pc++;
|
|
490
|
+
} else if (light.isSpotLight) {
|
|
491
|
+
table = t_spot;
|
|
492
|
+
slot = sc++;
|
|
493
|
+
} else if (light.isDirectionalLight) {
|
|
494
|
+
table = t_directional;
|
|
495
|
+
slot = dc++;
|
|
496
|
+
} else {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (map.metadata_changed) {
|
|
501
|
+
table.set(slot, map.make_record());
|
|
502
|
+
map.metadata_changed = false;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// trim trailing slots from previous frames so disused entries don't leak
|
|
507
|
+
for (let i = pc; i < this.#prev_point_count; i++) {
|
|
508
|
+
t_point.remove(i);
|
|
509
|
+
}
|
|
510
|
+
for (let i = sc; i < this.#prev_spot_count; i++) {
|
|
511
|
+
t_spot.remove(i);
|
|
512
|
+
}
|
|
513
|
+
for (let i = dc; i < this.#prev_directional_count; i++) {
|
|
514
|
+
t_directional.remove(i);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
this.#prev_point_count = pc;
|
|
518
|
+
this.#prev_spot_count = sc;
|
|
519
|
+
this.#prev_directional_count = dc;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Rasterize every shadowmap flagged by {@link select_for_draw} for a refresh this frame,
|
|
524
|
+
* committing any pending resize reservations in the process, then publish per-shadow
|
|
525
|
+
* metadata into the scene's GPU database.
|
|
526
|
+
*
|
|
527
|
+
* For each map with `should_draw` set:
|
|
528
|
+
*
|
|
529
|
+
* 1. If the map has a {@link Shadowmap.pending_layout} reservation, swap it into place
|
|
530
|
+
* BEFORE rasterization so the draw targets the new region. The old committed rects
|
|
531
|
+
* are remembered for step 3.
|
|
532
|
+
* 2. Dispatch to the type-specific raster path:
|
|
533
|
+
* - **Directional / spot**: direct raster into the atlas's sub-rects (one job per
|
|
534
|
+
* cascade for directionals, one job per spot).
|
|
535
|
+
* - **Point**: 6 cube-face depth passes into a shared intermediate texture, then
|
|
536
|
+
* cube→octahedral remap into the atlas. Point lights are serialised so they can
|
|
537
|
+
* reuse the intermediate texture.
|
|
538
|
+
* 3. If a commit happened in step 1, release the old committed rects from the atlas now
|
|
539
|
+
* that the new region holds valid depth.
|
|
540
|
+
* 4. Clear per-frame flags (`should_draw`, `is_invalid`) and stamp
|
|
541
|
+
* `last_updated_frame_index` with the current frame.
|
|
542
|
+
*
|
|
543
|
+
* After the loop, each map's metadata record is written into the corresponding
|
|
544
|
+
* `shadow_point` / `shadow_spot` / `shadow_directional` table on the owning light
|
|
545
|
+
* collection's database, then the database is uploaded — this is where the committed
|
|
546
|
+
* swaps become visible to the lighting shader. `#debug_render_count` is reset at entry
|
|
547
|
+
* and incremented per map to expose scheduling behaviour to the debug overlay.
|
|
548
|
+
*
|
|
549
|
+
* No external job list: every path batches its own work internally via
|
|
550
|
+
* {@link execute_rasterization_jobs}. Callers just pass a command context.
|
|
551
|
+
*
|
|
552
|
+
* @param {ShadeGPUCommandContext} command_ctx
|
|
553
|
+
*/
|
|
554
|
+
draw(command_ctx) {
|
|
555
|
+
assert.defined(command_ctx, 'command_ctx');
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
this.#debug_render_count = 0;
|
|
559
|
+
|
|
560
|
+
const frame_index = this.#current_frame_index;
|
|
561
|
+
const maps = this.#registry.maps;
|
|
562
|
+
|
|
563
|
+
for (let i = 0; i < maps.length; i++) {
|
|
564
|
+
const map = maps[i];
|
|
565
|
+
if (!map.should_draw) {
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Step 1: commit any pending-layout reservation before rasterizing. The draw helpers
|
|
570
|
+
// read `map.layout` directly, so swapping here makes the raster target the new
|
|
571
|
+
// region. We stash the old rect(s) locally for step 3's atlas release — once the
|
|
572
|
+
// raster commands are enqueued, the old region's contents will no longer be sampled
|
|
573
|
+
// (the next shadow-record write publishes the new layout), so returning that atlas
|
|
574
|
+
// space to the packer is safe.
|
|
575
|
+
let retired_rects = null;
|
|
576
|
+
if (map.pending_layout !== null) {
|
|
577
|
+
retired_rects = map.layout;
|
|
578
|
+
map.layout = map.pending_layout;
|
|
579
|
+
map.pending_layout = null;
|
|
580
|
+
map.metadata_changed = true;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const light = map.light;
|
|
584
|
+
|
|
585
|
+
if (light.isDirectionalLight || light.isSpotLight) {
|
|
586
|
+
this.#draw_direct(map, command_ctx);
|
|
587
|
+
} else if (light.isPointLight) {
|
|
588
|
+
if (map.isTetrahedron) {
|
|
589
|
+
this.#draw_point_tetrahedron(map, command_ctx);
|
|
590
|
+
} else {
|
|
591
|
+
this.#draw_point(map, command_ctx);
|
|
592
|
+
}
|
|
593
|
+
} else {
|
|
594
|
+
throw new Error(`Unsupported light type ${light.constructor.name}`);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Step 3: release the retired rects from the atlas. Must happen AFTER the raster
|
|
598
|
+
// helpers finish reading map.layout (they may close over retired_rects as scratch
|
|
599
|
+
// memory or view references in some paths; safest order is raster-first).
|
|
600
|
+
if (retired_rects !== null) {
|
|
601
|
+
for (let j = 0; j < retired_rects.length; j++) {
|
|
602
|
+
this.atlas.remove(retired_rects[j]);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// Step 4: atlas contents are now current. Clear per-frame flags and stamp the frame
|
|
607
|
+
// index so the next frame's scorer computes staleness correctly.
|
|
608
|
+
map.should_draw = false;
|
|
609
|
+
map.is_invalid = false;
|
|
610
|
+
map.last_updated_frame_index = frame_index;
|
|
611
|
+
this.#debug_render_count++;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
// Publish metadata AFTER all commits so the lighting shader sees atlas coordinates that
|
|
616
|
+
// match the regions we just rasterised into. Never-drawn maps carry stale-but-valid
|
|
617
|
+
// projection + layout; off-screen maps and skipped candidates publish their prior state.
|
|
618
|
+
const database = this.#owner.database;
|
|
619
|
+
this.#write_shadow_records(database);
|
|
620
|
+
database.update(command_ctx);
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
// finalize rendered views
|
|
624
|
+
for (const map of this.#registry.maps) {
|
|
625
|
+
if (map.last_updated_frame_index !== frame_index) {
|
|
626
|
+
// skip
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
for (const view of map.views) {
|
|
631
|
+
const view_ctx = this.shadow_view_manager.obtain(view);
|
|
632
|
+
view_ctx.finish_frame(command_ctx);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Rasterize a directional or spot shadowmap directly into its atlas rects. One job per
|
|
639
|
+
* `map.views[i]` / `map.layout[i]` pair — directionals have N cascades, spots have one.
|
|
640
|
+
*
|
|
641
|
+
* @param {Shadowmap} map
|
|
642
|
+
* @param {ShadeGPUCommandContext} command_ctx
|
|
643
|
+
*/
|
|
644
|
+
#draw_direct(map, command_ctx) {
|
|
645
|
+
// TODO pre-cull mesh set by sphere-casting the light volume against the main View Frustum
|
|
646
|
+
// see ref: https://www.reddit.com/r/Unity3D/comments/1foe8qi/added_a_way_to_perform_frustum_culling_and_take
|
|
647
|
+
|
|
648
|
+
const graph = new FrameGraph("shadows");
|
|
649
|
+
|
|
650
|
+
const shadow_views = map.views;
|
|
651
|
+
const jobs = new Array(shadow_views.length);
|
|
652
|
+
|
|
653
|
+
for (let i = 0; i < shadow_views.length; i++) {
|
|
654
|
+
const view = shadow_views[i];
|
|
655
|
+
const view_ctx = this.shadow_view_manager.obtain(view);
|
|
656
|
+
|
|
657
|
+
view_ctx.update(this.#graphics);
|
|
658
|
+
|
|
659
|
+
const atlas_aabb = map.layout[i];
|
|
660
|
+
view_ctx.setViewportSize(atlas_aabb.width, atlas_aabb.height);
|
|
661
|
+
|
|
662
|
+
const job = new RasterizationJob();
|
|
663
|
+
job.opaque_pass = shadow_rasterization_pass_descriptor;
|
|
664
|
+
job.alpha_tested_pass = shadow_rasterization_alpha_tested_pass_descriptor;
|
|
665
|
+
job.cull_policy = CullPolicy.Reversed;
|
|
666
|
+
job.render_target = this.#render_target;
|
|
667
|
+
job.view_ctx = view_ctx;
|
|
668
|
+
job.viewport = [atlas_aabb.x0, atlas_aabb.y0, atlas_aabb.width, atlas_aabb.height];
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
jobs[i] = job;
|
|
672
|
+
|
|
673
|
+
// TODO reproject current scene view into shadow map for better occlusion culling,
|
|
674
|
+
// see Assassin's Creed Unity talk on GPU-driven rendering,
|
|
675
|
+
// see "RE ENGINE Meshlet Rendering Pipeline" https://youtu.be/nWgPtCDXlPc?t=2055
|
|
676
|
+
|
|
677
|
+
// TODO need to linearize depth(?)
|
|
678
|
+
// can linearize together with reprojection (TAA)
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
execute_rasterization_jobs({
|
|
682
|
+
jobs,
|
|
683
|
+
limits: this.#graphics.collection_limits,
|
|
684
|
+
command_ctx,
|
|
685
|
+
graph,
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
command_ctx.encodeGraph(graph);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Rasterize a point light's 6 cube faces into the shared intermediate texture, then run the
|
|
693
|
+
* cube→octahedral remap shader to write the encoded depth into this light's atlas rect.
|
|
694
|
+
*
|
|
695
|
+
* Sequencing matters: each point light fully completes (6 cube rasters + remap) before the
|
|
696
|
+
* next one starts, so the intermediate texture can be reused across point lights without
|
|
697
|
+
* cross-contamination.
|
|
698
|
+
*
|
|
699
|
+
* @param {PointLightShadowmap} map
|
|
700
|
+
* @param {ShadeGPUCommandContext} command_ctx
|
|
701
|
+
*/
|
|
702
|
+
#draw_point(
|
|
703
|
+
map,
|
|
704
|
+
command_ctx,
|
|
705
|
+
) {
|
|
706
|
+
|
|
707
|
+
const graph = new FrameGraph("shadows");
|
|
708
|
+
|
|
709
|
+
const gr_atlas_texture = graph_import_texture(graph, this.texture);
|
|
710
|
+
|
|
711
|
+
const atlas_rect = map.layout[0];
|
|
712
|
+
|
|
713
|
+
const octahedral_resolution = atlas_rect.width;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Controls the relationship between octahedral resolution and the cube map used during rendering
|
|
717
|
+
* If this is larger - we get better quality at the cost of rendering more pixels.
|
|
718
|
+
*
|
|
719
|
+
* Solving for solid angle coverage, using the formula `N=POW(1 - SQRT(E/3), 3/2)` we get:
|
|
720
|
+
*
|
|
721
|
+
* 0% error -> 1
|
|
722
|
+
* 1% error -> 0.915
|
|
723
|
+
* 5% error -> 0.81299
|
|
724
|
+
* 10% error -> 0.739
|
|
725
|
+
* 20% error -> 0.639
|
|
726
|
+
* 30% error -> 0.565
|
|
727
|
+
* 40% error -> 0.506
|
|
728
|
+
* 50% error -> 0.455
|
|
729
|
+
*
|
|
730
|
+
* @type {number}
|
|
731
|
+
*/
|
|
732
|
+
const CUBE_MAPPING_RESOLUTION_SCALE = 1;
|
|
733
|
+
|
|
734
|
+
const cube_face_resolution = Math.ceil(octahedral_resolution * CUBE_MAPPING_RESOLUTION_SCALE);
|
|
735
|
+
|
|
736
|
+
// reserve texture
|
|
737
|
+
let cube_packed_texture = graph_create_texture(graph, TextureResourceDescriptor.from({
|
|
738
|
+
resolution: [
|
|
739
|
+
cube_face_resolution * POINT_SHADOW_CUBE_COLS,
|
|
740
|
+
cube_face_resolution * POINT_SHADOW_CUBE_ROWS,
|
|
741
|
+
],
|
|
742
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
743
|
+
format: 'depth32float',
|
|
744
|
+
enableMips: false,
|
|
745
|
+
}));
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
*
|
|
749
|
+
* @type {PointLight}
|
|
750
|
+
*/
|
|
751
|
+
const light = map.light;
|
|
752
|
+
|
|
753
|
+
const scene_ctx = this.shadow_view_manager.obtain(map.views[0]).scene;
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Sphere-culled meshes from the scene.
|
|
757
|
+
* We could do per-face culling, but most point lights are local, and there's already meshlet culling happening later in the pipeline.
|
|
758
|
+
* Good enough.
|
|
759
|
+
* @type {number}
|
|
760
|
+
*/
|
|
761
|
+
const input_meshes = graph_mesh_sphere_cull({
|
|
762
|
+
graph,
|
|
763
|
+
sphere: [...light.position, light.distance],
|
|
764
|
+
scene: scene_ctx,
|
|
765
|
+
limits: this.#graphics.collection_limits,
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
for (let face = 0; face < 6; face++) {
|
|
769
|
+
const view = map.views[face];
|
|
770
|
+
const view_ctx = this.shadow_view_manager.obtain(view);
|
|
771
|
+
|
|
772
|
+
view_ctx.update(this.#graphics);
|
|
773
|
+
view_ctx.setViewportSize(cube_face_resolution, cube_face_resolution);
|
|
774
|
+
|
|
775
|
+
const col = face % POINT_SHADOW_CUBE_COLS;
|
|
776
|
+
const row = Math.floor(face / POINT_SHADOW_CUBE_COLS);
|
|
777
|
+
|
|
778
|
+
const job = new RasterizationJob();
|
|
779
|
+
|
|
780
|
+
job.pipeline_type = RasterizationPipelineType.Fast;
|
|
781
|
+
job.opaque_pass = shadow_rasterization_pass_descriptor;
|
|
782
|
+
job.alpha_tested_pass = shadow_rasterization_alpha_tested_pass_descriptor;
|
|
783
|
+
job.cull_policy = CullPolicy.Reversed;
|
|
784
|
+
job.render_target = null;
|
|
785
|
+
job.view_ctx = view_ctx;
|
|
786
|
+
job.viewport = [
|
|
787
|
+
col * cube_face_resolution,
|
|
788
|
+
row * cube_face_resolution,
|
|
789
|
+
cube_face_resolution,
|
|
790
|
+
cube_face_resolution,
|
|
791
|
+
];
|
|
792
|
+
|
|
793
|
+
cube_packed_texture = graph_rasterize_scene_fast_raw({
|
|
794
|
+
graph,
|
|
795
|
+
meshes: input_meshes,
|
|
796
|
+
limits: this.#graphics.collection_limits,
|
|
797
|
+
target_depth: cube_packed_texture,
|
|
798
|
+
job,
|
|
799
|
+
}).target_depth;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
*
|
|
804
|
+
* @param data
|
|
805
|
+
* @param {FramePassResources} resources
|
|
806
|
+
* @param {GraphicsExecutionContext} context
|
|
807
|
+
*/
|
|
808
|
+
function remap_to_atlas(data, resources, context) {
|
|
809
|
+
const atlas = resources.get(data.atlas);
|
|
810
|
+
const cube_texture = resources.get(data.cube_texture);
|
|
811
|
+
|
|
812
|
+
const settings = {
|
|
813
|
+
atlas_offset: [
|
|
814
|
+
atlas_rect.x0 + SHADOWMAP_ATLAS_BORDER,
|
|
815
|
+
atlas_rect.y0 + SHADOWMAP_ATLAS_BORDER,
|
|
816
|
+
atlas_rect.width - 2 * SHADOWMAP_ATLAS_BORDER,
|
|
817
|
+
atlas_rect.height - 2 * SHADOWMAP_ATLAS_BORDER,
|
|
818
|
+
],
|
|
819
|
+
light_params: [
|
|
820
|
+
map.light.distance,
|
|
821
|
+
map.cube_near,
|
|
822
|
+
0,
|
|
823
|
+
0,
|
|
824
|
+
]
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
shader_shadowmap_remap_cube_to_octahedral.draw({
|
|
828
|
+
encoder: context.encoder,
|
|
829
|
+
bindings: {
|
|
830
|
+
settings: settings,
|
|
831
|
+
cube_faces: cube_texture.obtainView(),
|
|
832
|
+
},
|
|
833
|
+
depthStencilAttachment: {
|
|
834
|
+
view: atlas.obtainView(),
|
|
835
|
+
depthLoadOp: "load",
|
|
836
|
+
depthStoreOp: "store",
|
|
837
|
+
},
|
|
838
|
+
viewport: [
|
|
839
|
+
atlas_rect.x0,
|
|
840
|
+
atlas_rect.y0,
|
|
841
|
+
atlas_rect.width,
|
|
842
|
+
atlas_rect.height,
|
|
843
|
+
]
|
|
844
|
+
})
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
const remap_data = {};
|
|
848
|
+
|
|
849
|
+
const remap_pass = graph.add("remap to atals", remap_data, remap_to_atlas);
|
|
850
|
+
|
|
851
|
+
remap_data.atlas = remap_pass.write(gr_atlas_texture);
|
|
852
|
+
remap_data.cube_texture = remap_pass.read(cube_packed_texture);
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
command_ctx.encodeGraph(graph);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Rasterize a point light's 4 tetrahedron faces into a shared intermediate texture, then run
|
|
860
|
+
* the tetrahedron→octahedral remap to write the encoded depth into this light's atlas rect.
|
|
861
|
+
* The tetrahedral parallel to {@link #draw_point} — same shape, 4 faces in a 2x2 grid instead
|
|
862
|
+
* of 6 in a 3x2 grid, and the remap is handed each face's view-projection matrix so it can
|
|
863
|
+
* select faces and project directions in exact agreement with how the depth was rasterized.
|
|
864
|
+
*
|
|
865
|
+
* @param {TetrahedronPointLightShadowmap} map
|
|
866
|
+
* @param {ShadeGPUCommandContext} command_ctx
|
|
867
|
+
*/
|
|
868
|
+
#draw_point_tetrahedron(
|
|
869
|
+
map,
|
|
870
|
+
command_ctx,
|
|
871
|
+
) {
|
|
872
|
+
|
|
873
|
+
const graph = new FrameGraph("shadows");
|
|
874
|
+
|
|
875
|
+
const gr_atlas_texture = graph_import_texture(graph, this.texture);
|
|
876
|
+
|
|
877
|
+
const atlas_rect = map.layout[0];
|
|
878
|
+
|
|
879
|
+
const octahedral_resolution = atlas_rect.width;
|
|
880
|
+
|
|
881
|
+
// Wider face fov than the cube path (see POINT_SHADOW_TETRA_FOV_DEGREES) needs a larger
|
|
882
|
+
// per-face resolution to hold comparable on-axis density — the analogue of the cube
|
|
883
|
+
// path's CUBE_MAPPING_RESOLUTION_SCALE.
|
|
884
|
+
const face_resolution = Math.ceil(octahedral_resolution * POINT_SHADOW_TETRA_MAPPING_RESOLUTION_SCALE);
|
|
885
|
+
|
|
886
|
+
// reserve intermediate depth texture — 2x2 grid of faces
|
|
887
|
+
let tetra_packed_texture = graph_create_texture(graph, TextureResourceDescriptor.from({
|
|
888
|
+
resolution: [
|
|
889
|
+
face_resolution * POINT_SHADOW_TETRA_COLS,
|
|
890
|
+
face_resolution * POINT_SHADOW_TETRA_ROWS,
|
|
891
|
+
],
|
|
892
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
893
|
+
format: 'depth32float',
|
|
894
|
+
enableMips: false,
|
|
895
|
+
}));
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
*
|
|
899
|
+
* @type {PointLight}
|
|
900
|
+
*/
|
|
901
|
+
const light = map.light;
|
|
902
|
+
|
|
903
|
+
const scene_ctx = this.shadow_view_manager.obtain(map.views[0]).scene;
|
|
904
|
+
|
|
905
|
+
// One sphere cull for all 4 faces — most point lights are local and meshlet culling
|
|
906
|
+
// refines later; per-face culling isn't worth it. Same trade as the cube path.
|
|
907
|
+
const input_meshes = graph_mesh_sphere_cull({
|
|
908
|
+
graph,
|
|
909
|
+
sphere: [...light.position, light.distance],
|
|
910
|
+
scene: scene_ctx,
|
|
911
|
+
limits: this.#graphics.collection_limits,
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
for (let face = 0; face < POINT_SHADOW_TETRA_FACE_COUNT; face++) {
|
|
915
|
+
const view = map.views[face];
|
|
916
|
+
const view_ctx = this.shadow_view_manager.obtain(view);
|
|
917
|
+
|
|
918
|
+
view_ctx.update(this.#graphics);
|
|
919
|
+
view_ctx.setViewportSize(face_resolution, face_resolution);
|
|
920
|
+
|
|
921
|
+
const col = face % POINT_SHADOW_TETRA_COLS;
|
|
922
|
+
const row = Math.floor(face / POINT_SHADOW_TETRA_COLS);
|
|
923
|
+
|
|
924
|
+
const job = new RasterizationJob();
|
|
925
|
+
|
|
926
|
+
job.pipeline_type = RasterizationPipelineType.Fast;
|
|
927
|
+
job.opaque_pass = shadow_rasterization_pass_descriptor;
|
|
928
|
+
job.alpha_tested_pass = shadow_rasterization_alpha_tested_pass_descriptor;
|
|
929
|
+
job.cull_policy = CullPolicy.Reversed;
|
|
930
|
+
job.render_target = null;
|
|
931
|
+
job.view_ctx = view_ctx;
|
|
932
|
+
job.viewport = [
|
|
933
|
+
col * face_resolution,
|
|
934
|
+
row * face_resolution,
|
|
935
|
+
face_resolution,
|
|
936
|
+
face_resolution,
|
|
937
|
+
];
|
|
938
|
+
|
|
939
|
+
tetra_packed_texture = graph_rasterize_scene_fast_raw({
|
|
940
|
+
graph,
|
|
941
|
+
meshes: input_meshes,
|
|
942
|
+
limits: this.#graphics.collection_limits,
|
|
943
|
+
target_depth: tetra_packed_texture,
|
|
944
|
+
job,
|
|
945
|
+
}).target_depth;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const views = map.views;
|
|
949
|
+
const tetra_near = map.tetra_near;
|
|
950
|
+
const light_max_distance = map.light.distance;
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
*
|
|
954
|
+
* @param data
|
|
955
|
+
* @param {FramePassResources} resources
|
|
956
|
+
* @param {GraphicsExecutionContext} context
|
|
957
|
+
*/
|
|
958
|
+
function remap_to_atlas(data, resources, context) {
|
|
959
|
+
const atlas = resources.get(data.atlas);
|
|
960
|
+
const tetra_texture = resources.get(data.tetra_texture);
|
|
961
|
+
|
|
962
|
+
// Read each face camera's view-projection at encode time — set in map.update() and
|
|
963
|
+
// untouched since, and it is exactly the matrix the rasterizer used above.
|
|
964
|
+
const face_view_proj = new Array(POINT_SHADOW_TETRA_FACE_COUNT);
|
|
965
|
+
for (let f = 0; f < POINT_SHADOW_TETRA_FACE_COUNT; f++) {
|
|
966
|
+
face_view_proj[f] = views[f].camera.view_projection_matrix;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const settings = context.encoder.allocateTransientValueBuffer(
|
|
970
|
+
POINT_SHADOW_TETRA_REMAP_SETTINGS,
|
|
971
|
+
{
|
|
972
|
+
atlas_offset: [
|
|
973
|
+
atlas_rect.x0 + SHADOWMAP_ATLAS_BORDER,
|
|
974
|
+
atlas_rect.y0 + SHADOWMAP_ATLAS_BORDER,
|
|
975
|
+
atlas_rect.width - 2 * SHADOWMAP_ATLAS_BORDER,
|
|
976
|
+
atlas_rect.height - 2 * SHADOWMAP_ATLAS_BORDER,
|
|
977
|
+
],
|
|
978
|
+
light_params: [
|
|
979
|
+
light_max_distance,
|
|
980
|
+
tetra_near,
|
|
981
|
+
0,
|
|
982
|
+
0,
|
|
983
|
+
],
|
|
984
|
+
face_view_proj,
|
|
985
|
+
}
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
shader_shadowmap_remap_tetrahedron_to_octahedral.draw({
|
|
989
|
+
encoder: context.encoder,
|
|
990
|
+
bindings: {
|
|
991
|
+
settings: settings,
|
|
992
|
+
tetra_faces: tetra_texture.obtainView(),
|
|
993
|
+
},
|
|
994
|
+
depthStencilAttachment: {
|
|
995
|
+
view: atlas.obtainView(),
|
|
996
|
+
depthLoadOp: "load",
|
|
997
|
+
depthStoreOp: "store",
|
|
998
|
+
},
|
|
999
|
+
viewport: [
|
|
1000
|
+
atlas_rect.x0,
|
|
1001
|
+
atlas_rect.y0,
|
|
1002
|
+
atlas_rect.width,
|
|
1003
|
+
atlas_rect.height,
|
|
1004
|
+
]
|
|
1005
|
+
})
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
const remap_data = {};
|
|
1009
|
+
|
|
1010
|
+
const remap_pass = graph.add("remap tetra to atlas", remap_data, remap_to_atlas);
|
|
1011
|
+
|
|
1012
|
+
remap_data.atlas = remap_pass.write(gr_atlas_texture);
|
|
1013
|
+
remap_data.tetra_texture = remap_pass.read(tetra_packed_texture);
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
command_ctx.encodeGraph(graph);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Release the per-face GPU contexts (each view's uniform/HZB/volumetrics buffers + its camera
|
|
1021
|
+
* uniform) backing a map. The dedicated {@link shadow_view_manager} / {@link #cameras} caches
|
|
1022
|
+
* key on the View/Camera objects and have no GC path, so a map's contexts must be released
|
|
1023
|
+
* explicitly here or their GPU buffers leak for the context's lifetime. Most visible when the
|
|
1024
|
+
* point-shadow generator toggle rebuilds every point map (fresh Views each time), but it also
|
|
1025
|
+
* closes the ordinary eviction leak (light removed / stops casting / shadows disabled).
|
|
1026
|
+
*
|
|
1027
|
+
* In this context Views and Cameras are 1:1 per map (each map creates its own), so releasing a
|
|
1028
|
+
* view's camera alongside it can't strand a still-referenced camera.
|
|
1029
|
+
*
|
|
1030
|
+
* @param {Shadowmap} map
|
|
1031
|
+
*/
|
|
1032
|
+
#release_map_gpu_contexts(map) {
|
|
1033
|
+
const views = map.views;
|
|
1034
|
+
for (let j = 0; j < views.length; j++) {
|
|
1035
|
+
const view = views[j];
|
|
1036
|
+
this.shadow_view_manager.release(view);
|
|
1037
|
+
this.#cameras.release(view.camera);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/**
|
|
1042
|
+
* Release a map's atlas rects + GPU side-resources. Caller is responsible for splicing it
|
|
1043
|
+
* out of {@link #registry}.
|
|
1044
|
+
*
|
|
1045
|
+
* @param {Shadowmap} map
|
|
1046
|
+
*/
|
|
1047
|
+
#evict_map(map) {
|
|
1048
|
+
for (let j = 0; j < map.layout.length; j++) {
|
|
1049
|
+
this.atlas.remove(map.layout[j]);
|
|
1050
|
+
}
|
|
1051
|
+
if (map.pending_layout !== null) {
|
|
1052
|
+
for (let j = 0; j < map.pending_layout.length; j++) {
|
|
1053
|
+
this.atlas.remove(map.pending_layout[j]);
|
|
1054
|
+
}
|
|
1055
|
+
map.pending_layout = null;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// free the per-view/-camera GPU contexts — without this an evicted map's buffers leak
|
|
1059
|
+
this.#release_map_gpu_contexts(map);
|
|
1060
|
+
|
|
1061
|
+
map.light._gpu_shadowmap_id = -1;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* Reconcile shadow allocations against the current scene state. Evicts maps for lights
|
|
1066
|
+
* that no longer cast shadows or have left the scene, allocates maps for new shadow-
|
|
1067
|
+
* casting lights, and reassigns per-type `_gpu_shadowmap_id` when the map ordering
|
|
1068
|
+
* shifts.
|
|
1069
|
+
*
|
|
1070
|
+
* Called from {@link GPULightCollection.update} every frame, including frames where
|
|
1071
|
+
* {@link LightCollection.version} hasn't moved — `light.casts_shadow` flips are not
|
|
1072
|
+
* tracked by version and are detected here.
|
|
1073
|
+
*
|
|
1074
|
+
* Runs as three linear passes — mark, reclaim, allocate — over {@link #registry}, which owns
|
|
1075
|
+
* the light -> map index and the marks. It used to scan the map array once per light to find
|
|
1076
|
+
* out whether that light already had one, which made the pass quadratic: 148us per frame at
|
|
1077
|
+
* 512 lights against 19us now, and 554us against 45us at 1024. See
|
|
1078
|
+
* benchmark/reconcile.spec.js.
|
|
1079
|
+
*
|
|
1080
|
+
* @returns {boolean} true when at least one map was added/evicted or at least one light's
|
|
1081
|
+
* per-type shadow_id moved. The caller uses this to decide whether the light
|
|
1082
|
+
* records need to be re-published (their `shadow_id` and CASTS_SHADOW_BIT may
|
|
1083
|
+
* have shifted).
|
|
1084
|
+
*/
|
|
1085
|
+
process_lights() {
|
|
1086
|
+
const registry = this.#registry;
|
|
1087
|
+
const shadowmaps = registry.maps;
|
|
1088
|
+
|
|
1089
|
+
// When the renderer has shadows disabled, treat every map as evictable so the next
|
|
1090
|
+
// build clears CASTS_SHADOW_BIT on every light. Re-enabling reconstructs everything
|
|
1091
|
+
// from scratch on the following frame — that's a one-frame catch-up cost, considered
|
|
1092
|
+
// an acceptable trade for the simpler invariant ("disabled" = no maps held).
|
|
1093
|
+
if (!this.enabled) {
|
|
1094
|
+
const had_maps = shadowmaps.length > 0;
|
|
1095
|
+
for (let i = shadowmaps.length - 1; i >= 0; i--) {
|
|
1096
|
+
this.#evict_map(shadowmaps[i]);
|
|
1097
|
+
}
|
|
1098
|
+
registry.clear();
|
|
1099
|
+
return had_maps;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
const scene = this.#scene;
|
|
1103
|
+
const lights = scene.lights.elements;
|
|
1104
|
+
let changed = false;
|
|
1105
|
+
|
|
1106
|
+
const use_tetra = this.use_tetrahedron_point_shadows;
|
|
1107
|
+
const newcomers = this.#reconcile_newcomers;
|
|
1108
|
+
|
|
1109
|
+
registry.begin_reconcile();
|
|
1110
|
+
newcomers.length = 0;
|
|
1111
|
+
|
|
1112
|
+
// Pass 1 — mark. One index lookup per light both answers "does this light already have a
|
|
1113
|
+
// map" and stamps that map as belonging to a light still in the scene, which is what lets
|
|
1114
|
+
// the reclamation below run without building a set of live lights first.
|
|
1115
|
+
//
|
|
1116
|
+
// A light that stopped casting is simply not marked; its map falls out in pass 2 on the
|
|
1117
|
+
// strength of the stale mark alone.
|
|
1118
|
+
for (let i = 0; i < lights.length; i++) {
|
|
1119
|
+
const light = lights[i];
|
|
1120
|
+
|
|
1121
|
+
if (!light.casts_shadow) {
|
|
1122
|
+
continue;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
const map = registry.mark_live(light);
|
|
1126
|
+
|
|
1127
|
+
if (map === undefined) {
|
|
1128
|
+
newcomers.push(light);
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// A point map built by the other generator (cube vs tetra) must be rebuilt when the
|
|
1133
|
+
// flag flips — its face count and draw path no longer match. Pass 2 drops it on the
|
|
1134
|
+
// same test; queueing the rebuild here lands it in this pass rather than the next.
|
|
1135
|
+
if (light.isPointLight && Boolean(map.isTetrahedron) !== use_tetra) {
|
|
1136
|
+
newcomers.push(light);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// Pass 2 — reclaim. Anything not marked belongs to a light that left the scene or stopped
|
|
1141
|
+
// casting, and its atlas rect would otherwise stay pinned forever. Walk in reverse so
|
|
1142
|
+
// splice indices stay stable.
|
|
1143
|
+
for (let i = shadowmaps.length - 1; i >= 0; i--) {
|
|
1144
|
+
const map = shadowmaps[i];
|
|
1145
|
+
const light = map.light;
|
|
1146
|
+
|
|
1147
|
+
const generator_mismatch = light.isPointLight
|
|
1148
|
+
&& Boolean(map.isTetrahedron) !== use_tetra;
|
|
1149
|
+
|
|
1150
|
+
if (registry.is_marked(map) && !generator_mismatch) {
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
this.#evict_map(map);
|
|
1154
|
+
registry.remove_at(i);
|
|
1155
|
+
changed = true;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
const add_directional = (light) => {
|
|
1159
|
+
const map = new DirectionalLightShadowmap();
|
|
1160
|
+
map.light = light;
|
|
1161
|
+
|
|
1162
|
+
const bound = [];
|
|
1163
|
+
try {
|
|
1164
|
+
for (let j = 0; j < SHADOWMAP_CSM_CASCADE_COUNT; j++) {
|
|
1165
|
+
const resolution_index = Math.min(j, DEFAULT_SHADOWMAP_DIRECTIONAL_RESOLUTION.length - 1);
|
|
1166
|
+
const resolution = DEFAULT_SHADOWMAP_DIRECTIONAL_RESOLUTION[resolution_index];
|
|
1167
|
+
|
|
1168
|
+
const rect = this.bind(resolution);
|
|
1169
|
+
bound.push(rect);
|
|
1170
|
+
map.layout[j] = rect;
|
|
1171
|
+
|
|
1172
|
+
const camera = new OrthographicCamera();
|
|
1173
|
+
camera.update();
|
|
1174
|
+
|
|
1175
|
+
const view = new View(camera, scene);
|
|
1176
|
+
view.label = `Shadow Cascade ${j}`;
|
|
1177
|
+
|
|
1178
|
+
map.views[j] = view;
|
|
1179
|
+
}
|
|
1180
|
+
} catch (e) {
|
|
1181
|
+
// Partial bind: roll back any cascade rects already inserted so the atlas isn't
|
|
1182
|
+
// left holding orphans for a map that never got registered.
|
|
1183
|
+
for (let j = 0; j < bound.length; j++) {
|
|
1184
|
+
this.atlas.remove(bound[j]);
|
|
1185
|
+
}
|
|
1186
|
+
throw e;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
registry.add(map);
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
const add_spot = (light) => {
|
|
1193
|
+
const map = new SpotLightShadowmap();
|
|
1194
|
+
map.light = light;
|
|
1195
|
+
|
|
1196
|
+
const rect = this.bind(DEFAULT_SHADOWMAP_LOCAL_RESOLUTION);
|
|
1197
|
+
map.layout[0] = rect;
|
|
1198
|
+
|
|
1199
|
+
try {
|
|
1200
|
+
const camera = new PerspectiveCamera();
|
|
1201
|
+
camera.update();
|
|
1202
|
+
|
|
1203
|
+
const view = new View(camera, scene);
|
|
1204
|
+
view.label = `Spot Shadow`;
|
|
1205
|
+
|
|
1206
|
+
map.views[0] = view;
|
|
1207
|
+
} catch (e) {
|
|
1208
|
+
this.atlas.remove(rect);
|
|
1209
|
+
throw e;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
registry.add(map);
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
const add_point = (light) => {
|
|
1216
|
+
|
|
1217
|
+
// Generator picked by `use_tetra` above; both remap into one octahedral slot, they
|
|
1218
|
+
// only differ in how many face frusta feed that remap (tetra 4, cube 6).
|
|
1219
|
+
const map = use_tetra ? new TetrahedronPointLightShadowmap() : new PointLightShadowmap();
|
|
1220
|
+
map.light = light;
|
|
1221
|
+
|
|
1222
|
+
// single atlas rect holds the octahedral-encoded depth for all faces
|
|
1223
|
+
const rect = this.bind(DEFAULT_SHADOWMAP_LOCAL_RESOLUTION);
|
|
1224
|
+
map.layout[0] = rect;
|
|
1225
|
+
|
|
1226
|
+
const face_count = use_tetra ? POINT_SHADOW_TETRA_FACE_COUNT : 6;
|
|
1227
|
+
|
|
1228
|
+
for (let j = 0; j < face_count; j++) {
|
|
1229
|
+
const camera = new PerspectiveCamera();
|
|
1230
|
+
camera.update();
|
|
1231
|
+
|
|
1232
|
+
const view = new View(camera, scene);
|
|
1233
|
+
view.label = use_tetra ? `Point Shadow (tetra) face ${j}` : `Point Shadow face ${j}`;
|
|
1234
|
+
|
|
1235
|
+
map.views[j] = view;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
registry.add(map);
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
const add_light = (light) => {
|
|
1242
|
+
// A light present twice in the scene's light array gets queued twice by pass 1, since
|
|
1243
|
+
// neither occurrence finds a map. LightCollection.add doesn't dedupe, so re-check here
|
|
1244
|
+
// rather than letting the registry's one-map-per-light assert fire every frame. Free
|
|
1245
|
+
// in the normal case — this loop only runs over lights that actually need a map.
|
|
1246
|
+
if (registry.get(light) !== undefined) {
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
if (light.isDirectionalLight) {
|
|
1251
|
+
add_directional(light);
|
|
1252
|
+
changed = true;
|
|
1253
|
+
} else if (light.isSpotLight) {
|
|
1254
|
+
add_spot(light);
|
|
1255
|
+
changed = true;
|
|
1256
|
+
} else if (light.isPointLight) {
|
|
1257
|
+
add_point(light);
|
|
1258
|
+
changed = true;
|
|
1259
|
+
}
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
// Pass 3 — allocate. Only the lights pass 1 flagged, so on the overwhelming majority of
|
|
1263
|
+
// frames (nothing arrived, nothing left) this loop does not run at all. The old version
|
|
1264
|
+
// walked every light here and re-tested casts_shadow on each; pass 1 already answered that.
|
|
1265
|
+
for (let i = 0; i < newcomers.length; i++) {
|
|
1266
|
+
try {
|
|
1267
|
+
add_light(newcomers[i]);
|
|
1268
|
+
} catch (e) {
|
|
1269
|
+
console.error(e);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// Drop the references rather than leaving them until the next call — a light that gets
|
|
1274
|
+
// removed from the scene right after being added here would otherwise stay reachable from
|
|
1275
|
+
// this scratch array for a frame.
|
|
1276
|
+
newcomers.length = 0;
|
|
1277
|
+
|
|
1278
|
+
// Publish per-type shadowmap ids back onto the lights. Each shadow_* table is indexed
|
|
1279
|
+
// independently, so a point light's shadow_id points into shadow_point, a spot's into
|
|
1280
|
+
// shadow_spot, etc. Type-bucket order MUST match {@link #write_shadow_records} so each
|
|
1281
|
+
// light record's stored shadow_id lines up with the slot we'll write into the table.
|
|
1282
|
+
// When a map's slot index actually changes (eviction shifted neighbours up the array),
|
|
1283
|
+
// mark its record dirty so the next #write_shadow_records re-publishes it into the new
|
|
1284
|
+
// slot, and report `changed` so the caller re-publishes the light records too.
|
|
1285
|
+
let pc = 0;
|
|
1286
|
+
let sc = 0;
|
|
1287
|
+
let dc = 0;
|
|
1288
|
+
for (let i = 0; i < shadowmaps.length; i++) {
|
|
1289
|
+
const map = shadowmaps[i];
|
|
1290
|
+
const light = map.light;
|
|
1291
|
+
|
|
1292
|
+
let new_id;
|
|
1293
|
+
if (light.isPointLight) {
|
|
1294
|
+
new_id = pc++;
|
|
1295
|
+
} else if (light.isSpotLight) {
|
|
1296
|
+
new_id = sc++;
|
|
1297
|
+
} else if (light.isDirectionalLight) {
|
|
1298
|
+
new_id = dc++;
|
|
1299
|
+
} else {
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
if (light._gpu_shadowmap_id !== new_id) {
|
|
1304
|
+
light._gpu_shadowmap_id = new_id;
|
|
1305
|
+
map.metadata_changed = true;
|
|
1306
|
+
changed = true;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
return changed;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
*
|
|
1315
|
+
* @param {number} resolution
|
|
1316
|
+
* @returns {AABB2}
|
|
1317
|
+
*/
|
|
1318
|
+
bind(resolution) {
|
|
1319
|
+
|
|
1320
|
+
const rect = new AABB2(0, 0, resolution, resolution);
|
|
1321
|
+
|
|
1322
|
+
if (!this.atlas.add(rect)) {
|
|
1323
|
+
throw new Error(`Failed to add shadowmap to atlas`);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
return rect;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
destroy() {
|
|
1330
|
+
this.texture.destroy();
|
|
1331
|
+
|
|
1332
|
+
const maps = this.#registry.maps;
|
|
1333
|
+
for (let i = 0; i < maps.length; i++) {
|
|
1334
|
+
const map = maps[i];
|
|
1335
|
+
// release the per-view/-camera GPU contexts too — map.destroy() alone doesn't (the
|
|
1336
|
+
// buffers live in the view/camera manager caches, not on the map)
|
|
1337
|
+
this.#release_map_gpu_contexts(map);
|
|
1338
|
+
map.destroy();
|
|
1339
|
+
}
|
|
1340
|
+
this.#registry.clear();
|
|
1341
|
+
}
|
|
1342
|
+
}
|