@babylonjs/lite 0.1.1 → 1.0.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/_mat4-storage-f64-CjDoht2w.js +11 -0
- package/_mat4-storage-f64-CjDoht2w.js.map +1 -0
- package/{alpha-test-fragment-CUiHCw7W.js → alpha-test-fragment-B7DjSnF7.js} +2 -2
- package/{alpha-test-fragment-CUiHCw7W.js.map → alpha-test-fragment-B7DjSnF7.js.map} +1 -1
- package/assets/splat-sort-worker-DT3eybMZ.js.map +1 -0
- package/{background-dds-skybox-yHTqabU3.js → background-dds-skybox-BEX309u3.js} +14 -14
- package/background-dds-skybox-BEX309u3.js.map +1 -0
- package/{background-ground-DIw6D3qf.js → background-ground-BU0HOcM4.js} +20 -20
- package/background-ground-BU0HOcM4.js.map +1 -0
- package/{background-hdr-skybox-c4uuTmkP.js → background-hdr-skybox--RRRic_K.js} +10 -10
- package/background-hdr-skybox--RRRic_K.js.map +1 -0
- package/{background-solid-skybox-DPGBpPbm.js → background-solid-skybox-BrH2fXSu.js} +12 -13
- package/background-solid-skybox-BrH2fXSu.js.map +1 -0
- package/{billboard-renderable-D8mlVGCd.js → billboard-renderable-BHWryAeC.js} +46 -10
- package/billboard-renderable-BHWryAeC.js.map +1 -0
- package/{clamp-block-BdII67hT.js → clamp-block-DqbwnQGW.js} +2 -2
- package/{clamp-block-BdII67hT.js.map → clamp-block-DqbwnQGW.js.map} +1 -1
- package/{clearcoat-fragment-LCiG98Rf.js → clearcoat-fragment-D6FSCie1.js} +2 -2
- package/{clearcoat-fragment-LCiG98Rf.js.map → clearcoat-fragment-D6FSCie1.js.map} +1 -1
- package/{create-skeleton-C9JdIJnb.js → create-skeleton-D_uplboC.js} +9 -9
- package/create-skeleton-D_uplboC.js.map +1 -0
- package/{cubemap-skybox-material-DvXMVc4k.js → cubemap-skybox-material-DQcMMdf-.js} +6 -7
- package/cubemap-skybox-material-DQcMMdf-.js.map +1 -0
- package/{curve-block-BlJpXVYv.js → curve-block-21rT0JjG.js} +2 -2
- package/{curve-block-BlJpXVYv.js.map → curve-block-21rT0JjG.js.map} +1 -1
- package/{emissive-fragment-BnNvbBCw.js → emissive-fragment-C5FtBs3y.js} +3 -3
- package/emissive-fragment-C5FtBs3y.js.map +1 -0
- package/{esm-shadow-view-DN9HIaM4.js → esm-shadow-view-Cl3rPGof.js} +2 -2
- package/{esm-shadow-view-DN9HIaM4.js.map → esm-shadow-view-Cl3rPGof.js.map} +1 -1
- package/{esm-shadow-view-Dk9NFtLq.js → esm-shadow-view-Gtd1LWRP.js} +2 -2
- package/{esm-shadow-view-Dk9NFtLq.js.map → esm-shadow-view-Gtd1LWRP.js.map} +1 -1
- package/{esm-shadow-view-DGKdF1NI.js → esm-shadow-view-c5YV4Eg9.js} +2 -2
- package/{esm-shadow-view-DGKdF1NI.js.map → esm-shadow-view-c5YV4Eg9.js.map} +1 -1
- package/{gaussian-splatting-pipeline-sh-DgJl7l56.js → gaussian-splatting-pipeline-sh-7J31V23x.js} +19 -19
- package/gaussian-splatting-pipeline-sh-7J31V23x.js.map +1 -0
- package/geometry-texture-output-dXk4E9uu.js +41 -0
- package/geometry-texture-output-dXk4E9uu.js.map +1 -0
- package/geometry-view-BsFJpBJa.js +404 -0
- package/geometry-view-BsFJpBJa.js.map +1 -0
- package/{gltf-animation-D7uyTyO3.js → gltf-animation-K_zZxj_d.js} +7 -7
- package/gltf-animation-K_zZxj_d.js.map +1 -0
- package/gltf-color-normalize-Qxl-9C48.js +29 -0
- package/gltf-color-normalize-Qxl-9C48.js.map +1 -0
- package/{gltf-ext-basisu-CPg5kPrx.js → gltf-ext-basisu-CDbPclzZ.js} +53 -18
- package/gltf-ext-basisu-CDbPclzZ.js.map +1 -0
- package/{gltf-ext-node-visibility-MafA9ot2.js → gltf-ext-node-visibility-DXCJEYr6.js} +2 -2
- package/{gltf-ext-node-visibility-MafA9ot2.js.map → gltf-ext-node-visibility-DXCJEYr6.js.map} +1 -1
- package/{gltf-ext-quantization-CpZyLDIz.js → gltf-ext-quantization-CvHI_0Vg.js} +4 -3
- package/gltf-ext-quantization-CvHI_0Vg.js.map +1 -0
- package/{gltf-ext-uv-transform-CE_-T1Tr.js → gltf-ext-uv-transform-DgYazJBs.js} +2 -2
- package/{gltf-ext-uv-transform-CE_-T1Tr.js.map → gltf-ext-uv-transform-DgYazJBs.js.map} +1 -1
- package/{gltf-feature-animation-pointer-BjpwOOqo.js → gltf-feature-animation-pointer-D1RJRFBw.js} +9 -9
- package/gltf-feature-animation-pointer-D1RJRFBw.js.map +1 -0
- package/{gltf-feature-animations-CCizegp8.js → gltf-feature-animations-Cmc1uoIu.js} +2 -2
- package/{gltf-feature-animations-CCizegp8.js.map → gltf-feature-animations-Cmc1uoIu.js.map} +1 -1
- package/{gltf-feature-draco-yGSMGTE3.js → gltf-feature-draco-CKKzT5E3.js} +6 -5
- package/gltf-feature-draco-CKKzT5E3.js.map +1 -0
- package/{gltf-feature-gpu-instancing-2e_CFQnl.js → gltf-feature-gpu-instancing-n87SO6Vh.js} +7 -6
- package/gltf-feature-gpu-instancing-n87SO6Vh.js.map +1 -0
- package/{gltf-feature-lights-punctual-DDDg4j0U.js → gltf-feature-lights-punctual-Ckm3ciL8.js} +5 -5
- package/{gltf-feature-lights-punctual-DDDg4j0U.js.map → gltf-feature-lights-punctual-Ckm3ciL8.js.map} +1 -1
- package/{gltf-feature-meshopt-Des96YFI.js → gltf-feature-meshopt-DLC4SF1E.js} +7 -6
- package/gltf-feature-meshopt-DLC4SF1E.js.map +1 -0
- package/{gltf-feature-morph-CKCw6tkX.js → gltf-feature-morph-Cjtu7hYa.js} +4 -4
- package/gltf-feature-morph-Cjtu7hYa.js.map +1 -0
- package/gltf-feature-registry-C63Hjp9w.js +59 -0
- package/gltf-feature-registry-C63Hjp9w.js.map +1 -0
- package/{gltf-feature-skeleton-D8hWLqi2.js → gltf-feature-skeleton-DKbOGidp.js} +3 -3
- package/{gltf-feature-skeleton-D8hWLqi2.js.map → gltf-feature-skeleton-DKbOGidp.js.map} +1 -1
- package/{gltf-feature-variants-Ds6v9byg.js → gltf-feature-variants-Cmzu0O0e.js} +2 -2
- package/{gltf-feature-variants-Ds6v9byg.js.map → gltf-feature-variants-Cmzu0O0e.js.map} +1 -1
- package/{gltf-glb-parser-D6UZWFuC.js → gltf-glb-parser-Cj5MHS-v.js} +5 -4
- package/gltf-glb-parser-Cj5MHS-v.js.map +1 -0
- package/{gltf-interleave-DGnUlz28.js → gltf-interleave-gHf9_t0i.js} +14 -14
- package/gltf-interleave-gHf9_t0i.js.map +1 -0
- package/gltf-normals-b2h74380.js +37 -0
- package/gltf-normals-b2h74380.js.map +1 -0
- package/{gltf-pbr-builder-ext-BFOxOCnQ.js → gltf-pbr-builder-ext-edNcjwPf.js} +5 -5
- package/gltf-pbr-builder-ext-edNcjwPf.js.map +1 -0
- package/{gltf-variants-DFbr8EES.js → gltf-variants-CPxNdtP4.js} +4 -4
- package/{gltf-variants-DFbr8EES.js.map → gltf-variants-CPxNdtP4.js.map} +1 -1
- package/{gs-picking-pipeline-DzfMASL9.js → gs-picking-pipeline-DYaW_Lg3.js} +14 -14
- package/gs-picking-pipeline-DYaW_Lg3.js.map +1 -0
- package/havok-floating-origin-Dr-18Nds.js +198 -0
- package/havok-floating-origin-Dr-18Nds.js.map +1 -0
- package/index-CLElg2Bo.js +39209 -0
- package/index-CLElg2Bo.js.map +1 -0
- package/index-CYZDclhF.js +918 -0
- package/index-CYZDclhF.js.map +1 -0
- package/index-SMJ67XwT.js +3330 -0
- package/index-SMJ67XwT.js.map +1 -0
- package/index.d.ts +2508 -119
- package/index.js +444 -302
- package/{input-block-DgAJBzN_.js → input-block-DqEedWF2.js} +2 -2
- package/{input-block-DgAJBzN_.js.map → input-block-DqEedWF2.js.map} +1 -1
- package/{iridescence-fragment-Gymp7or5.js → iridescence-fragment-BHU59-gQ.js} +2 -2
- package/{iridescence-fragment-Gymp7or5.js.map → iridescence-fragment-BHU59-gQ.js.map} +1 -1
- package/{light-block-B11ew7FA.js → light-block-Bv37V8vl.js} +2 -2
- package/{light-block-B11ew7FA.js.map → light-block-Bv37V8vl.js.map} +1 -1
- package/{loop-block-Bb23EOMb.js → loop-block-qTg8vb99.js} +2 -2
- package/{loop-block-Bb23EOMb.js.map → loop-block-qTg8vb99.js.map} +1 -1
- package/{morph-fragment-DOVo70gP.js → morph-fragment-BRCUr2wQ.js} +2 -2
- package/{morph-fragment-DOVo70gP.js.map → morph-fragment-BRCUr2wQ.js.map} +1 -1
- package/{multilight-wgsl-BGyiIOp3.js → multilight-wgsl-DMeppAdZ.js} +4 -4
- package/{multilight-wgsl-BGyiIOp3.js.map → multilight-wgsl-DMeppAdZ.js.map} +1 -1
- package/{node-env-BPZXZzBf.js → node-env-Bc559GmY.js} +6 -5
- package/node-env-Bc559GmY.js.map +1 -0
- package/node-geometry-view-COmWsRXK.js +291 -0
- package/node-geometry-view-COmWsRXK.js.map +1 -0
- package/{node-registry-extra-compat-Dhrw8fDQ.js → node-registry-extra-compat-dWrv7gpS.js} +2 -2
- package/{node-registry-extra-compat-Dhrw8fDQ.js.map → node-registry-extra-compat-dWrv7gpS.js.map} +1 -1
- package/{node-registry-extra-math-CsAHvIZo.js → node-registry-extra-math-Bn854sX9.js} +2 -2
- package/{node-registry-extra-math-CsAHvIZo.js.map → node-registry-extra-math-Bn854sX9.js.map} +1 -1
- package/{node-renderable-DlLIdBmd.js → node-renderable-B5G8WcdH.js} +41 -22
- package/node-renderable-B5G8WcdH.js.map +1 -0
- package/{node-shadow-DKrcqmNg.js → node-shadow-CVIUlNf0.js} +7 -7
- package/node-shadow-CVIUlNf0.js.map +1 -0
- package/{normal-map-fragment-DpsIXrJf.js → normal-map-fragment-CQSxhjCy.js} +3 -3
- package/{normal-map-fragment-DpsIXrJf.js.map → normal-map-fragment-CQSxhjCy.js.map} +1 -1
- package/pack-mat4-with-offset-BqB8Jqo7.js +37 -0
- package/pack-mat4-with-offset-BqB8Jqo7.js.map +1 -0
- package/package.json +3 -10
- package/{parse-camera-DM3oJJeT.js → parse-camera-pBRT_6i5.js} +2 -2
- package/{parse-camera-DM3oJJeT.js.map → parse-camera-pBRT_6i5.js.map} +1 -1
- package/pbr-fog-wgsl-BqdCid6r.js +8 -0
- package/pbr-fog-wgsl-BqdCid6r.js.map +1 -0
- package/pbr-geometry-view-NiZY_juX.js +491 -0
- package/pbr-geometry-view-NiZY_juX.js.map +1 -0
- package/{pbr-metallic-roughness-block-h_KAOZrW.js → pbr-metallic-roughness-block-JBSi-tQN.js} +2 -2
- package/{pbr-metallic-roughness-block-h_KAOZrW.js.map → pbr-metallic-roughness-block-JBSi-tQN.js.map} +1 -1
- package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js → pbr-metallic-roughness-block-full-Ta9lR2cz.js} +2 -2
- package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js.map → pbr-metallic-roughness-block-full-Ta9lR2cz.js.map} +1 -1
- package/{pbr-mr-helper-core-CIwm-T1G.js → pbr-mr-helper-core-BVWNR08D.js} +2 -2
- package/{pbr-mr-helper-core-CIwm-T1G.js.map → pbr-mr-helper-core-BVWNR08D.js.map} +1 -1
- package/{pbr-refraction-DGmMSa2v.js → pbr-refraction-C9FvFmAp.js} +2 -2
- package/{pbr-refraction-DGmMSa2v.js.map → pbr-refraction-C9FvFmAp.js.map} +1 -1
- package/{pbr-renderable-BJxUtPBb.js → pbr-renderable-DzUF2QIk.js} +118 -58
- package/pbr-renderable-DzUF2QIk.js.map +1 -0
- package/{pbr-shadow-fragment-LO9SlbJj.js → pbr-shadow-fragment-CnqnbGYS.js} +6 -1
- package/pbr-shadow-fragment-CnqnbGYS.js.map +1 -0
- package/{pbr-template-ext-8q7BcTDf.js → pbr-template-ext-CGgB2n2y.js} +3 -2
- package/{pbr-template-ext-8q7BcTDf.js.map → pbr-template-ext-CGgB2n2y.js.map} +1 -1
- package/{pbr-tracking-B3alzn91.js → pbr-tracking-3tU1kqea.js} +2 -2
- package/{pbr-tracking-B3alzn91.js.map → pbr-tracking-3tU1kqea.js.map} +1 -1
- package/pbr-transmission-ext-BcLjRxfB.js +190 -0
- package/pbr-transmission-ext-BcLjRxfB.js.map +1 -0
- package/recast-navigation.wasm-DG_0AFuk.js +8706 -0
- package/recast-navigation.wasm-DG_0AFuk.js.map +1 -0
- package/recast-navigation.wasm-compat-C-Bf2ylB.js +8692 -0
- package/recast-navigation.wasm-compat-C-Bf2ylB.js.map +1 -0
- package/{reflectance-fragment-BCrgPmrt.js → reflectance-fragment-Dbpgw3Jt.js} +2 -2
- package/{reflectance-fragment-BCrgPmrt.js.map → reflectance-fragment-Dbpgw3Jt.js.map} +1 -1
- package/{rgbd-decode-DCvzUYeI.js → rgbd-decode-DoyUquy3.js} +7 -6
- package/rgbd-decode-DoyUquy3.js.map +1 -0
- package/{scene-material-swap-C2ykv55W.js → scene-material-swap-nNUH4nGn.js} +11 -4
- package/scene-material-swap-nNUH4nGn.js.map +1 -0
- package/screenshot-readback-D0Sj9qq3.js +92 -0
- package/screenshot-readback-D0Sj9qq3.js.map +1 -0
- package/{mesh-features-BLENkYVt.js → shader-composer-BUD_pSX4.js} +7 -55
- package/shader-composer-BUD_pSX4.js.map +1 -0
- package/{shader-renderable-D-6796KR.js → shader-renderable-D7-RyVxa.js} +62 -27
- package/shader-renderable-D7-RyVxa.js.map +1 -0
- package/shader-thin-instance-DuBotxDO.js +150 -0
- package/shader-thin-instance-DuBotxDO.js.map +1 -0
- package/shadow-fragment-core-DHN2G6FI.js.map +1 -1
- package/{sheen-fragment-Dze2f7XJ.js → sheen-fragment-1MkEMcbc.js} +2 -2
- package/{sheen-fragment-Dze2f7XJ.js.map → sheen-fragment-1MkEMcbc.js.map} +1 -1
- package/{singlelight-directional-wgsl-CmUDZxwz.js → singlelight-directional-wgsl-BsV8G456.js} +2 -2
- package/{singlelight-directional-wgsl-CmUDZxwz.js.map → singlelight-directional-wgsl-BsV8G456.js.map} +1 -1
- package/{singlelight-hemispheric-wgsl-t-83IP_s.js → singlelight-hemispheric-wgsl-Bo0jKlW5.js} +2 -2
- package/{singlelight-hemispheric-wgsl-t-83IP_s.js.map → singlelight-hemispheric-wgsl-Bo0jKlW5.js.map} +1 -1
- package/{singlelight-point-wgsl-CLzULIYV.js → singlelight-point-wgsl-DV39UP5Y.js} +2 -2
- package/{singlelight-point-wgsl-CLzULIYV.js.map → singlelight-point-wgsl-DV39UP5Y.js.map} +1 -1
- package/{singlelight-spot-wgsl-DEEUrfVM.js → singlelight-spot-wgsl-yg3od6vL.js} +2 -2
- package/{singlelight-spot-wgsl-DEEUrfVM.js.map → singlelight-spot-wgsl-yg3od6vL.js.map} +1 -1
- package/{skeleton-fragment-B_XlFbtx.js → skeleton-fragment-DdxYG6kv.js} +2 -2
- package/{skeleton-fragment-B_XlFbtx.js.map → skeleton-fragment-DdxYG6kv.js.map} +1 -1
- package/{skybox-renderable-DDwzu-PT.js → skybox-renderable-CJD4XmX5.js} +8 -9
- package/skybox-renderable-CJD4XmX5.js.map +1 -0
- package/{splat-ply-compressed-BahdBG1r.js → splat-ply-compressed-DHjyiVmI.js} +9 -8
- package/splat-ply-compressed-DHjyiVmI.js.map +1 -0
- package/{standard-renderable-GjxL9xSf.js → standard-pipeline-XTbHL7MY.js} +12 -257
- package/standard-pipeline-XTbHL7MY.js.map +1 -0
- package/standard-renderable-CREWLNHI.js +191 -0
- package/standard-renderable-CREWLNHI.js.map +1 -0
- package/{std-ambient-fragment-BoUsD06w.js → std-ambient-fragment-Bjx3VFrr.js} +2 -2
- package/{std-ambient-fragment-BoUsD06w.js.map → std-ambient-fragment-Bjx3VFrr.js.map} +1 -1
- package/{std-cube-reflection-fragment-ulqc3bsP.js → std-cube-reflection-fragment-y9WWdXUt.js} +2 -2
- package/{std-cube-reflection-fragment-ulqc3bsP.js.map → std-cube-reflection-fragment-y9WWdXUt.js.map} +1 -1
- package/{std-emissive-fragment-DNGj1HdQ.js → std-emissive-fragment-C8Lnmojh.js} +2 -2
- package/{std-emissive-fragment-DNGj1HdQ.js.map → std-emissive-fragment-C8Lnmojh.js.map} +1 -1
- package/{std-lightmap-fragment-Bqj89aIe.js → std-lightmap-fragment-DFxGcoA5.js} +2 -2
- package/{std-lightmap-fragment-Bqj89aIe.js.map → std-lightmap-fragment-DFxGcoA5.js.map} +1 -1
- package/{std-opacity-fragment-KuPh5N2Z.js → std-opacity-fragment-EXzFWiSp.js} +2 -2
- package/{std-opacity-fragment-KuPh5N2Z.js.map → std-opacity-fragment-EXzFWiSp.js.map} +1 -1
- package/{std-reflection-fragment-BA5Ghn_M.js → std-reflection-fragment-BoJORqpG.js} +2 -2
- package/{std-reflection-fragment-BA5Ghn_M.js.map → std-reflection-fragment-BoJORqpG.js.map} +1 -1
- package/std-shadow-fragment-Bq-Wc8UJ.js +13 -0
- package/std-shadow-fragment-Bq-Wc8UJ.js.map +1 -0
- package/{std-specular-fragment-CE-6scqd.js → std-specular-fragment-CM5R5j2g.js} +2 -2
- package/{std-specular-fragment-CE-6scqd.js.map → std-specular-fragment-CM5R5j2g.js.map} +1 -1
- package/{std-tracking-CNKZ-hJN.js → std-tracking-Cif_wXeT.js} +2 -2
- package/{std-tracking-CNKZ-hJN.js.map → std-tracking-Cif_wXeT.js.map} +1 -1
- package/{subsurface-fragment-liM3y2-P.js → subsurface-fragment-BEaAXYXz.js} +2 -2
- package/{subsurface-fragment-liM3y2-P.js.map → subsurface-fragment-BEaAXYXz.js.map} +1 -1
- package/swapchain-overlay-UCLilhbq.js +37 -0
- package/swapchain-overlay-UCLilhbq.js.map +1 -0
- package/thin-instance-cull-binding-DWKUt5ZN.js +310 -0
- package/thin-instance-cull-binding-DWKUt5ZN.js.map +1 -0
- package/{thin-instance-gpu-C9Gv_Z1w.js → thin-instance-gpu-BDdRcNAh.js} +30 -5
- package/thin-instance-gpu-BDdRcNAh.js.map +1 -0
- package/{tracking-primitives-wgdBY85t.js → tracking-primitives-CglRNTlX.js} +2 -2
- package/{tracking-primitives-wgdBY85t.js.map → tracking-primitives-CglRNTlX.js.map} +1 -1
- package/{unlit-fragment-BIlhJpz6.js → unlit-fragment-kxfZWlnp.js} +2 -2
- package/{unlit-fragment-BIlhJpz6.js.map → unlit-fragment-kxfZWlnp.js.map} +1 -1
- package/{wgsl-helpers-DyzNzCeE.js → wgsl-helpers-D8sl1VVA.js} +4 -4
- package/{wgsl-helpers-DyzNzCeE.js.map → wgsl-helpers-D8sl1VVA.js.map} +1 -1
- package/assets/splat-sort-worker-Crg3CaCc.js.map +0 -1
- package/background-dds-skybox-yHTqabU3.js.map +0 -1
- package/background-ground-DIw6D3qf.js.map +0 -1
- package/background-hdr-skybox-c4uuTmkP.js.map +0 -1
- package/background-solid-skybox-DPGBpPbm.js.map +0 -1
- package/billboard-renderable-D8mlVGCd.js.map +0 -1
- package/create-skeleton-C9JdIJnb.js.map +0 -1
- package/cubemap-skybox-material-DvXMVc4k.js.map +0 -1
- package/emissive-fragment-BnNvbBCw.js.map +0 -1
- package/gaussian-splatting-pipeline-sh-DgJl7l56.js.map +0 -1
- package/gltf-animation-D7uyTyO3.js.map +0 -1
- package/gltf-ext-basisu-CPg5kPrx.js.map +0 -1
- package/gltf-ext-quantization-CpZyLDIz.js.map +0 -1
- package/gltf-feature-animation-pointer-BjpwOOqo.js.map +0 -1
- package/gltf-feature-draco-yGSMGTE3.js.map +0 -1
- package/gltf-feature-gpu-instancing-2e_CFQnl.js.map +0 -1
- package/gltf-feature-meshopt-Des96YFI.js.map +0 -1
- package/gltf-feature-morph-CKCw6tkX.js.map +0 -1
- package/gltf-glb-parser-D6UZWFuC.js.map +0 -1
- package/gltf-interleave-DGnUlz28.js.map +0 -1
- package/gltf-pbr-builder-ext-BFOxOCnQ.js.map +0 -1
- package/gs-picking-pipeline-DzfMASL9.js.map +0 -1
- package/index-C8HOR2sB.js +0 -19222
- package/index-C8HOR2sB.js.map +0 -1
- package/mesh-features-BLENkYVt.js.map +0 -1
- package/node-env-BPZXZzBf.js.map +0 -1
- package/node-registry-DwgC4yth.js +0 -190
- package/node-registry-DwgC4yth.js.map +0 -1
- package/node-renderable-DlLIdBmd.js.map +0 -1
- package/node-shadow-DKrcqmNg.js.map +0 -1
- package/pbr-renderable-BJxUtPBb.js.map +0 -1
- package/pbr-shadow-fragment-LO9SlbJj.js.map +0 -1
- package/pbr-transmission-ext-BxW4CEGu.js +0 -581
- package/pbr-transmission-ext-BxW4CEGu.js.map +0 -1
- package/rgbd-decode-DCvzUYeI.js.map +0 -1
- package/scene-material-swap-C2ykv55W.js.map +0 -1
- package/shader-renderable-D-6796KR.js.map +0 -1
- package/skybox-renderable-DDwzu-PT.js.map +0 -1
- package/splat-ply-compressed-BahdBG1r.js.map +0 -1
- package/standard-renderable-GjxL9xSf.js.map +0 -1
- package/std-shadow-fragment-FNQfrJuC.js +0 -8
- package/std-shadow-fragment-FNQfrJuC.js.map +0 -1
- package/swapchain-overlay-DcCSFDp7.js +0 -35
- package/swapchain-overlay-DcCSFDp7.js.map +0 -1
- package/thin-instance-gpu-C9Gv_Z1w.js.map +0 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { B as BU, bN as getViewProjectionMatrix, U as U32, a as F32 } from "./index-CLElg2Bo.js";
|
|
2
|
+
import { syncThinInstanceGpuData } from "./thin-instance-gpu-BDdRcNAh.js";
|
|
3
|
+
const WORKGROUP_SIZE = 64;
|
|
4
|
+
const PARAM_BYTES = 192;
|
|
5
|
+
const COUNT_U32_OFFSET = 44;
|
|
6
|
+
const MESH_WORLD_FLOAT_OFFSET = 24;
|
|
7
|
+
const LOCAL_SPHERE_FLOAT_OFFSET = 40;
|
|
8
|
+
const INDIRECT_ARGS_BYTES = 20;
|
|
9
|
+
const CULL_WGSL_NO_COLOR = (
|
|
10
|
+
/* wgsl */
|
|
11
|
+
`
|
|
12
|
+
struct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32};
|
|
13
|
+
@group(0)@binding(0)var<storage,read> srcMatrices:array<mat4x4<f32>>;
|
|
14
|
+
@group(0)@binding(1)var<storage,read_write> dstMatrices:array<mat4x4<f32>>;
|
|
15
|
+
@group(0)@binding(2)var<storage,read_write> args:array<atomic<u32>>;
|
|
16
|
+
@group(0)@binding(3)var<uniform> params:CullParams;
|
|
17
|
+
fn visible(world:mat4x4<f32>)->bool{
|
|
18
|
+
let center=(world*vec4<f32>(params.localSphere.xyz,1.0)).xyz;
|
|
19
|
+
let sx=length(world[0].xyz);
|
|
20
|
+
let sy=length(world[1].xyz);
|
|
21
|
+
let sz=length(world[2].xyz);
|
|
22
|
+
let radius=params.localSphere.w*max(max(sx,sy),sz)+0.0001;
|
|
23
|
+
for(var i=0u;i<6u;i++){
|
|
24
|
+
let p=params.planes[i];
|
|
25
|
+
if(dot(p.xyz,center)+p.w < -radius){return false;}
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
@compute @workgroup_size(64)
|
|
30
|
+
fn main(@builtin(global_invocation_id) gid:vec3<u32>){
|
|
31
|
+
let i=gid.x;
|
|
32
|
+
if(i>=params.count){return;}
|
|
33
|
+
let world=params.meshWorld*srcMatrices[i];
|
|
34
|
+
if(!visible(world)){return;}
|
|
35
|
+
let outIndex=atomicAdd(&args[1],1u);
|
|
36
|
+
dstMatrices[outIndex]=srcMatrices[i];
|
|
37
|
+
}`
|
|
38
|
+
);
|
|
39
|
+
const CULL_WGSL_COLOR = `${CULL_WGSL_NO_COLOR}
|
|
40
|
+
@group(0)@binding(4)var<storage,read> srcColors:array<vec4<f32>>;
|
|
41
|
+
@group(0)@binding(5)var<storage,read_write> dstColors:array<vec4<f32>>;
|
|
42
|
+
@compute @workgroup_size(64)
|
|
43
|
+
fn mainColor(@builtin(global_invocation_id) gid:vec3<u32>){
|
|
44
|
+
let i=gid.x;
|
|
45
|
+
if(i>=params.count){return;}
|
|
46
|
+
let world=params.meshWorld*srcMatrices[i];
|
|
47
|
+
if(!visible(world)){return;}
|
|
48
|
+
let outIndex=atomicAdd(&args[1],1u);
|
|
49
|
+
dstMatrices[outIndex]=srcMatrices[i];
|
|
50
|
+
dstColors[outIndex]=srcColors[i];
|
|
51
|
+
}`;
|
|
52
|
+
let _cachedDevice = null;
|
|
53
|
+
let _pipelineNoColor = null;
|
|
54
|
+
let _pipelineColor = null;
|
|
55
|
+
function createTiCullState() {
|
|
56
|
+
const paramsBytes = new ArrayBuffer(PARAM_BYTES);
|
|
57
|
+
return {
|
|
58
|
+
_capacity: 0,
|
|
59
|
+
_visibleMatrixBuffer: null,
|
|
60
|
+
_visibleColorBuffer: null,
|
|
61
|
+
_argsBuffer: null,
|
|
62
|
+
_paramsBuffer: null,
|
|
63
|
+
_bindGroup: null,
|
|
64
|
+
_srcMatrixBuffer: null,
|
|
65
|
+
_srcColorBuffer: null,
|
|
66
|
+
_hasColor: false,
|
|
67
|
+
_localSphereReady: false,
|
|
68
|
+
_localSphere: new F32(4),
|
|
69
|
+
_paramsBytes: paramsBytes,
|
|
70
|
+
_paramsF32: new F32(paramsBytes),
|
|
71
|
+
_paramsU32: new U32(paramsBytes),
|
|
72
|
+
_argsData: new U32(5),
|
|
73
|
+
_drawBuffers: null
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function destroyTiCullState(state) {
|
|
77
|
+
var _a, _b, _c, _d;
|
|
78
|
+
(_a = state._visibleMatrixBuffer) == null ? void 0 : _a.destroy();
|
|
79
|
+
(_b = state._visibleColorBuffer) == null ? void 0 : _b.destroy();
|
|
80
|
+
(_c = state._argsBuffer) == null ? void 0 : _c.destroy();
|
|
81
|
+
(_d = state._paramsBuffer) == null ? void 0 : _d.destroy();
|
|
82
|
+
state._visibleMatrixBuffer = null;
|
|
83
|
+
state._visibleColorBuffer = null;
|
|
84
|
+
state._argsBuffer = null;
|
|
85
|
+
state._paramsBuffer = null;
|
|
86
|
+
state._bindGroup = null;
|
|
87
|
+
state._drawBuffers = null;
|
|
88
|
+
}
|
|
89
|
+
function prepareTiCull(engine, state, mesh, gpu, ti, hasColor, context) {
|
|
90
|
+
const camera = context._camera;
|
|
91
|
+
if (!ti._gpuCullingEnabled || !camera || mesh.visible === false || ti.count === 0) {
|
|
92
|
+
state._drawBuffers = null;
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (hasColor && !ti.colors) {
|
|
96
|
+
state._drawBuffers = null;
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (!state._localSphereReady && !computeLocalSphere(mesh, state._localSphere)) {
|
|
100
|
+
state._drawBuffers = null;
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
state._localSphereReady = true;
|
|
104
|
+
syncThinInstanceGpuData(engine, ti, hasColor);
|
|
105
|
+
const sourceMatrixBuffer = ti._gpuBuffer;
|
|
106
|
+
const sourceColorBuffer = hasColor ? ti._colorGpuBuffer : null;
|
|
107
|
+
if (!sourceMatrixBuffer || hasColor && !sourceColorBuffer) {
|
|
108
|
+
state._drawBuffers = null;
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
ensureCullBuffers(engine, state, ti._capacity, hasColor);
|
|
112
|
+
const visibleMatrixBuffer = state._visibleMatrixBuffer;
|
|
113
|
+
const visibleColorBuffer = hasColor ? state._visibleColorBuffer : null;
|
|
114
|
+
const argsBuffer = state._argsBuffer;
|
|
115
|
+
const paramsBuffer = state._paramsBuffer;
|
|
116
|
+
const pipeline = getCullPipeline(engine, hasColor);
|
|
117
|
+
if (state._bindGroup === null || state._srcMatrixBuffer !== sourceMatrixBuffer || state._srcColorBuffer !== sourceColorBuffer || state._hasColor !== hasColor) {
|
|
118
|
+
const entries = [
|
|
119
|
+
{ binding: 0, resource: { buffer: sourceMatrixBuffer } },
|
|
120
|
+
{ binding: 1, resource: { buffer: visibleMatrixBuffer } },
|
|
121
|
+
{ binding: 2, resource: { buffer: argsBuffer } },
|
|
122
|
+
{ binding: 3, resource: { buffer: paramsBuffer } }
|
|
123
|
+
];
|
|
124
|
+
if (hasColor) {
|
|
125
|
+
entries.push({ binding: 4, resource: { buffer: sourceColorBuffer } }, { binding: 5, resource: { buffer: visibleColorBuffer } });
|
|
126
|
+
}
|
|
127
|
+
state._bindGroup = engine._device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries });
|
|
128
|
+
state._srcMatrixBuffer = sourceMatrixBuffer;
|
|
129
|
+
state._srcColorBuffer = sourceColorBuffer;
|
|
130
|
+
state._hasColor = hasColor;
|
|
131
|
+
}
|
|
132
|
+
const v = camera.viewport;
|
|
133
|
+
const aspect = context.targetWidth / context.targetHeight * (v ? v.width / v.height : 1);
|
|
134
|
+
writeCullParams(engine, state, mesh, gpu.indexCount, ti.count, camera, aspect);
|
|
135
|
+
const pass = engine._currentEncoder.beginComputePass();
|
|
136
|
+
pass.setPipeline(pipeline);
|
|
137
|
+
pass.setBindGroup(0, state._bindGroup);
|
|
138
|
+
pass.dispatchWorkgroups(Math.ceil(ti.count / WORKGROUP_SIZE));
|
|
139
|
+
pass.end();
|
|
140
|
+
state._drawBuffers = { matrixBuffer: visibleMatrixBuffer, colorBuffer: visibleColorBuffer };
|
|
141
|
+
return { drawBuffers: state._drawBuffers, argsBuffer };
|
|
142
|
+
}
|
|
143
|
+
function ensureCullBuffers(engine, state, capacity, hasColor) {
|
|
144
|
+
var _a, _b;
|
|
145
|
+
const device = engine._device;
|
|
146
|
+
if (state._capacity < capacity) {
|
|
147
|
+
(_a = state._visibleMatrixBuffer) == null ? void 0 : _a.destroy();
|
|
148
|
+
(_b = state._visibleColorBuffer) == null ? void 0 : _b.destroy();
|
|
149
|
+
state._visibleMatrixBuffer = device.createBuffer({
|
|
150
|
+
size: Math.max(capacity * 64, 4),
|
|
151
|
+
usage: BU.VERTEX | BU.STORAGE
|
|
152
|
+
});
|
|
153
|
+
state._visibleColorBuffer = hasColor ? device.createBuffer({
|
|
154
|
+
size: Math.max(capacity * 16, 4),
|
|
155
|
+
usage: BU.VERTEX | BU.STORAGE
|
|
156
|
+
}) : null;
|
|
157
|
+
state._capacity = capacity;
|
|
158
|
+
state._bindGroup = null;
|
|
159
|
+
state._drawBuffers = null;
|
|
160
|
+
} else if (hasColor && !state._visibleColorBuffer) {
|
|
161
|
+
state._visibleColorBuffer = device.createBuffer({
|
|
162
|
+
size: Math.max(state._capacity * 16, 4),
|
|
163
|
+
usage: BU.VERTEX | BU.STORAGE
|
|
164
|
+
});
|
|
165
|
+
state._bindGroup = null;
|
|
166
|
+
state._drawBuffers = null;
|
|
167
|
+
}
|
|
168
|
+
if (!state._argsBuffer) {
|
|
169
|
+
state._argsBuffer = device.createBuffer({
|
|
170
|
+
size: INDIRECT_ARGS_BYTES,
|
|
171
|
+
usage: BU.INDIRECT | BU.STORAGE | BU.COPY_DST
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (!state._paramsBuffer) {
|
|
175
|
+
state._paramsBuffer = device.createBuffer({
|
|
176
|
+
size: PARAM_BYTES,
|
|
177
|
+
usage: BU.UNIFORM | BU.COPY_DST
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function getCullPipeline(engine, hasColor) {
|
|
182
|
+
const device = engine._device;
|
|
183
|
+
if (_cachedDevice !== device) {
|
|
184
|
+
_cachedDevice = device;
|
|
185
|
+
_pipelineNoColor = null;
|
|
186
|
+
_pipelineColor = null;
|
|
187
|
+
}
|
|
188
|
+
if (hasColor) {
|
|
189
|
+
_pipelineColor ?? (_pipelineColor = device.createComputePipeline({
|
|
190
|
+
layout: "auto",
|
|
191
|
+
compute: { module: device.createShaderModule({ code: CULL_WGSL_COLOR }), entryPoint: "mainColor" }
|
|
192
|
+
}));
|
|
193
|
+
return _pipelineColor;
|
|
194
|
+
}
|
|
195
|
+
_pipelineNoColor ?? (_pipelineNoColor = device.createComputePipeline({
|
|
196
|
+
layout: "auto",
|
|
197
|
+
compute: { module: device.createShaderModule({ code: CULL_WGSL_NO_COLOR }), entryPoint: "main" }
|
|
198
|
+
}));
|
|
199
|
+
return _pipelineNoColor;
|
|
200
|
+
}
|
|
201
|
+
function writeCullParams(engine, state, mesh, indexCount, instanceCount, camera, aspect) {
|
|
202
|
+
const params = state._paramsF32;
|
|
203
|
+
const viewProjection = getViewProjectionMatrix(camera, aspect);
|
|
204
|
+
writeFrustumPlanes(params, viewProjection);
|
|
205
|
+
params.set(mesh.worldMatrix, MESH_WORLD_FLOAT_OFFSET);
|
|
206
|
+
params.set(state._localSphere, LOCAL_SPHERE_FLOAT_OFFSET);
|
|
207
|
+
state._paramsU32[COUNT_U32_OFFSET] = instanceCount;
|
|
208
|
+
const args = state._argsData;
|
|
209
|
+
args[0] = indexCount;
|
|
210
|
+
args[1] = 0;
|
|
211
|
+
args[2] = 0;
|
|
212
|
+
args[3] = 0;
|
|
213
|
+
args[4] = 0;
|
|
214
|
+
engine._device.queue.writeBuffer(state._argsBuffer, 0, args.buffer, args.byteOffset, args.byteLength);
|
|
215
|
+
engine._device.queue.writeBuffer(state._paramsBuffer, 0, state._paramsBytes);
|
|
216
|
+
}
|
|
217
|
+
function writeFrustumPlanes(out, m) {
|
|
218
|
+
writePlane(out, 0, m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]);
|
|
219
|
+
writePlane(out, 4, m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]);
|
|
220
|
+
writePlane(out, 8, m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]);
|
|
221
|
+
writePlane(out, 12, m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]);
|
|
222
|
+
writePlane(out, 16, m[2], m[6], m[10], m[14]);
|
|
223
|
+
writePlane(out, 20, m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]);
|
|
224
|
+
}
|
|
225
|
+
function writePlane(out, offset, x, y, z, w) {
|
|
226
|
+
const invLen = 1 / Math.hypot(x, y, z);
|
|
227
|
+
out[offset] = x * invLen;
|
|
228
|
+
out[offset + 1] = y * invLen;
|
|
229
|
+
out[offset + 2] = z * invLen;
|
|
230
|
+
out[offset + 3] = w * invLen;
|
|
231
|
+
}
|
|
232
|
+
function computeLocalSphere(mesh, out) {
|
|
233
|
+
const positions = mesh._cpuPositions;
|
|
234
|
+
if (!positions || positions.length < 3) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
238
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
239
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
240
|
+
const x = positions[i];
|
|
241
|
+
const y = positions[i + 1];
|
|
242
|
+
const z = positions[i + 2];
|
|
243
|
+
if (x < minX) {
|
|
244
|
+
minX = x;
|
|
245
|
+
}
|
|
246
|
+
if (x > maxX) {
|
|
247
|
+
maxX = x;
|
|
248
|
+
}
|
|
249
|
+
if (y < minY) {
|
|
250
|
+
minY = y;
|
|
251
|
+
}
|
|
252
|
+
if (y > maxY) {
|
|
253
|
+
maxY = y;
|
|
254
|
+
}
|
|
255
|
+
if (z < minZ) {
|
|
256
|
+
minZ = z;
|
|
257
|
+
}
|
|
258
|
+
if (z > maxZ) {
|
|
259
|
+
maxZ = z;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (!isFinite(minX)) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
const cx = (minX + maxX) * 0.5;
|
|
266
|
+
const cy = (minY + maxY) * 0.5;
|
|
267
|
+
const cz = (minZ + maxZ) * 0.5;
|
|
268
|
+
const dx = maxX - cx;
|
|
269
|
+
const dy = maxY - cy;
|
|
270
|
+
const dz = maxZ - cz;
|
|
271
|
+
out[0] = cx;
|
|
272
|
+
out[1] = cy;
|
|
273
|
+
out[2] = cz;
|
|
274
|
+
out[3] = Math.hypot(dx, dy, dz);
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
function tryBind(renderable, scene, mesh, engine, hasColor, excluded, baseUpdate) {
|
|
278
|
+
var _a;
|
|
279
|
+
const ti = mesh.thinInstances;
|
|
280
|
+
if (excluded || !(ti == null ? void 0 : ti._gpuCullingEnabled)) {
|
|
281
|
+
return void 0;
|
|
282
|
+
}
|
|
283
|
+
renderable._direct = true;
|
|
284
|
+
const state = createTiCullState();
|
|
285
|
+
(_a = scene._meshDisposables.get(mesh)) == null ? void 0 : _a.push(() => {
|
|
286
|
+
destroyTiCullState(state);
|
|
287
|
+
});
|
|
288
|
+
const binding = {
|
|
289
|
+
cullDrawBufs: null,
|
|
290
|
+
_args: null,
|
|
291
|
+
update(context) {
|
|
292
|
+
baseUpdate == null ? void 0 : baseUpdate(context);
|
|
293
|
+
const res = prepareTiCull(engine, state, mesh, mesh._gpu, ti, hasColor, context);
|
|
294
|
+
binding.cullDrawBufs = (res == null ? void 0 : res.drawBuffers) ?? null;
|
|
295
|
+
binding._args = (res == null ? void 0 : res.argsBuffer) ?? null;
|
|
296
|
+
},
|
|
297
|
+
draw(pass, indexCount, instanceCount) {
|
|
298
|
+
if (binding._args) {
|
|
299
|
+
pass.drawIndexedIndirect(binding._args, 0);
|
|
300
|
+
} else {
|
|
301
|
+
pass.drawIndexed(indexCount, instanceCount);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
return binding;
|
|
306
|
+
}
|
|
307
|
+
export {
|
|
308
|
+
tryBind
|
|
309
|
+
};
|
|
310
|
+
//# sourceMappingURL=thin-instance-cull-binding-DWKUt5ZN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thin-instance-cull-binding-DWKUt5ZN.js","sources":["../src/mesh/thin-instance-gpu-culling.ts","../src/mesh/thin-instance-cull-binding.ts"],"sourcesContent":["/** GPU frustum culling for opt-in thin instances.\n *\n * Dynamically imported only when a scene enables thin-instance GPU culling.\n * Each render binding owns its own state so render tasks with different cameras\n * never clobber one another's compacted instance buffers or indirect args.\n */\n\nimport { F32, U32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Camera } from \"../camera/camera.js\";\nimport { getViewProjectionMatrix } from \"../camera/camera.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { DrawUpdateContext } from \"../render/renderable.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Mesh, MeshGPU } from \"./mesh.js\";\nimport type { ThinInstanceData } from \"./thin-instance.js\";\nimport { syncThinInstanceGpuData } from \"./thin-instance-gpu.js\";\nimport type { ThinInstanceDrawBuffers } from \"./thin-instance-gpu.js\";\n\nconst WORKGROUP_SIZE = 64;\nconst PARAM_BYTES = 192;\nconst COUNT_U32_OFFSET = 44;\nconst MESH_WORLD_FLOAT_OFFSET = 24;\nconst LOCAL_SPHERE_FLOAT_OFFSET = 40;\nconst INDIRECT_ARGS_BYTES = 20;\n\nconst CULL_WGSL_NO_COLOR = /* wgsl */ `\nstruct CullParams{planes:array<vec4<f32>,6>,meshWorld:mat4x4<f32>,localSphere:vec4<f32>,count:u32};\n@group(0)@binding(0)var<storage,read> srcMatrices:array<mat4x4<f32>>;\n@group(0)@binding(1)var<storage,read_write> dstMatrices:array<mat4x4<f32>>;\n@group(0)@binding(2)var<storage,read_write> args:array<atomic<u32>>;\n@group(0)@binding(3)var<uniform> params:CullParams;\nfn visible(world:mat4x4<f32>)->bool{\nlet center=(world*vec4<f32>(params.localSphere.xyz,1.0)).xyz;\nlet sx=length(world[0].xyz);\nlet sy=length(world[1].xyz);\nlet sz=length(world[2].xyz);\nlet radius=params.localSphere.w*max(max(sx,sy),sz)+0.0001;\nfor(var i=0u;i<6u;i++){\nlet p=params.planes[i];\nif(dot(p.xyz,center)+p.w < -radius){return false;}\n}\nreturn true;\n}\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\n}`;\n\nconst CULL_WGSL_COLOR = `${CULL_WGSL_NO_COLOR}\n@group(0)@binding(4)var<storage,read> srcColors:array<vec4<f32>>;\n@group(0)@binding(5)var<storage,read_write> dstColors:array<vec4<f32>>;\n@compute @workgroup_size(64)\nfn mainColor(@builtin(global_invocation_id) gid:vec3<u32>){\nlet i=gid.x;\nif(i>=params.count){return;}\nlet world=params.meshWorld*srcMatrices[i];\nif(!visible(world)){return;}\nlet outIndex=atomicAdd(&args[1],1u);\ndstMatrices[outIndex]=srcMatrices[i];\ndstColors[outIndex]=srcColors[i];\n}`;\n\n/** Per-render-binding GPU culling state. */\nexport interface ThinInstanceGpuCullState {\n /** @internal */\n _capacity: number;\n /** @internal */\n _visibleMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _visibleColorBuffer: GPUBuffer | null;\n /** @internal */\n _argsBuffer: GPUBuffer | null;\n /** @internal */\n _paramsBuffer: GPUBuffer | null;\n /** @internal */\n _bindGroup: GPUBindGroup | null;\n /** @internal */\n _srcMatrixBuffer: GPUBuffer | null;\n /** @internal */\n _srcColorBuffer: GPUBuffer | null;\n /** @internal */\n _hasColor: boolean;\n /** @internal */\n _localSphereReady: boolean;\n /** @internal */\n _localSphere: Float32Array;\n /** @internal */\n _paramsBytes: ArrayBuffer;\n /** @internal */\n _paramsF32: Float32Array;\n /** @internal */\n _paramsU32: Uint32Array;\n /** @internal */\n _argsData: Uint32Array;\n /** @internal */\n _drawBuffers: ThinInstanceDrawBuffers | null;\n}\n\n/** Result consumed by a material draw closure after culling has run for the active pass. */\nexport interface ThinInstanceGpuCullResult {\n readonly drawBuffers: ThinInstanceDrawBuffers;\n readonly argsBuffer: GPUBuffer;\n}\n\nlet _cachedDevice: GPUDevice | null = null;\nlet _pipelineNoColor: GPUComputePipeline | null = null;\nlet _pipelineColor: GPUComputePipeline | null = null;\n\n/** Create per-binding culling state. */\nexport function createTiCullState(): ThinInstanceGpuCullState {\n const paramsBytes = new ArrayBuffer(PARAM_BYTES);\n return {\n _capacity: 0,\n _visibleMatrixBuffer: null,\n _visibleColorBuffer: null,\n _argsBuffer: null,\n _paramsBuffer: null,\n _bindGroup: null,\n _srcMatrixBuffer: null,\n _srcColorBuffer: null,\n _hasColor: false,\n _localSphereReady: false,\n _localSphere: new F32(4),\n _paramsBytes: paramsBytes,\n _paramsF32: new F32(paramsBytes),\n _paramsU32: new U32(paramsBytes),\n _argsData: new U32(5),\n _drawBuffers: null,\n };\n}\n\n/** Destroy GPU resources owned by a per-binding cull state. */\nexport function destroyTiCullState(state: ThinInstanceGpuCullState): void {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._argsBuffer?.destroy();\n state._paramsBuffer?.destroy();\n state._visibleMatrixBuffer = null;\n state._visibleColorBuffer = null;\n state._argsBuffer = null;\n state._paramsBuffer = null;\n state._bindGroup = null;\n state._drawBuffers = null;\n}\n\n/** Run culling for one render binding and return buffers for the subsequent indirect draw. */\nexport function prepareTiCull(\n engine: EngineContext,\n state: ThinInstanceGpuCullState,\n mesh: Mesh,\n gpu: MeshGPU,\n ti: ThinInstanceData,\n hasColor: boolean,\n context: DrawUpdateContext\n): ThinInstanceGpuCullResult | null {\n const camera = context._camera;\n if (!ti._gpuCullingEnabled || !camera || mesh.visible === false || ti.count === 0) {\n state._drawBuffers = null;\n return null;\n }\n if (hasColor && !ti.colors) {\n state._drawBuffers = null;\n return null;\n }\n if (!state._localSphereReady && !computeLocalSphere(mesh as Mesh, state._localSphere)) {\n state._drawBuffers = null;\n return null;\n }\n state._localSphereReady = true;\n\n syncThinInstanceGpuData(engine, ti, hasColor);\n const sourceMatrixBuffer = ti._gpuBuffer;\n const sourceColorBuffer = hasColor ? ti._colorGpuBuffer : null;\n if (!sourceMatrixBuffer || (hasColor && !sourceColorBuffer)) {\n state._drawBuffers = null;\n return null;\n }\n\n ensureCullBuffers(engine, state, ti._capacity, hasColor);\n const visibleMatrixBuffer = state._visibleMatrixBuffer!;\n const visibleColorBuffer = hasColor ? state._visibleColorBuffer! : null;\n const argsBuffer = state._argsBuffer!;\n const paramsBuffer = state._paramsBuffer!;\n const pipeline = getCullPipeline(engine, hasColor);\n\n if (state._bindGroup === null || state._srcMatrixBuffer !== sourceMatrixBuffer || state._srcColorBuffer !== sourceColorBuffer || state._hasColor !== hasColor) {\n const entries: GPUBindGroupEntry[] = [\n { binding: 0, resource: { buffer: sourceMatrixBuffer } },\n { binding: 1, resource: { buffer: visibleMatrixBuffer } },\n { binding: 2, resource: { buffer: argsBuffer } },\n { binding: 3, resource: { buffer: paramsBuffer } },\n ];\n if (hasColor) {\n entries.push({ binding: 4, resource: { buffer: sourceColorBuffer! } }, { binding: 5, resource: { buffer: visibleColorBuffer! } });\n }\n state._bindGroup = engine._device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries });\n state._srcMatrixBuffer = sourceMatrixBuffer;\n state._srcColorBuffer = sourceColorBuffer;\n state._hasColor = hasColor;\n }\n\n const v = camera.viewport;\n const aspect = (context.targetWidth / context.targetHeight) * (v ? v.width / v.height : 1);\n writeCullParams(engine, state, mesh, gpu.indexCount, ti.count, camera, aspect);\n\n const pass = engine._currentEncoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, state._bindGroup);\n pass.dispatchWorkgroups(Math.ceil(ti.count / WORKGROUP_SIZE));\n pass.end();\n\n state._drawBuffers = { matrixBuffer: visibleMatrixBuffer, colorBuffer: visibleColorBuffer };\n return { drawBuffers: state._drawBuffers, argsBuffer };\n}\n\nfunction ensureCullBuffers(engine: EngineContext, state: ThinInstanceGpuCullState, capacity: number, hasColor: boolean): void {\n const device = engine._device;\n if (state._capacity < capacity) {\n state._visibleMatrixBuffer?.destroy();\n state._visibleColorBuffer?.destroy();\n state._visibleMatrixBuffer = device.createBuffer({\n size: Math.max(capacity * 64, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._visibleColorBuffer = hasColor\n ? device.createBuffer({\n size: Math.max(capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n })\n : null;\n state._capacity = capacity;\n state._bindGroup = null;\n state._drawBuffers = null;\n } else if (hasColor && !state._visibleColorBuffer) {\n state._visibleColorBuffer = device.createBuffer({\n size: Math.max(state._capacity * 16, 4),\n usage: BU.VERTEX | BU.STORAGE,\n });\n state._bindGroup = null;\n state._drawBuffers = null;\n }\n if (!state._argsBuffer) {\n state._argsBuffer = device.createBuffer({\n size: INDIRECT_ARGS_BYTES,\n usage: BU.INDIRECT | BU.STORAGE | BU.COPY_DST,\n });\n }\n if (!state._paramsBuffer) {\n state._paramsBuffer = device.createBuffer({\n size: PARAM_BYTES,\n usage: BU.UNIFORM | BU.COPY_DST,\n });\n }\n}\n\nfunction getCullPipeline(engine: EngineContext, hasColor: boolean): GPUComputePipeline {\n const device = engine._device;\n if (_cachedDevice !== device) {\n _cachedDevice = device;\n _pipelineNoColor = null;\n _pipelineColor = null;\n }\n if (hasColor) {\n _pipelineColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_COLOR }), entryPoint: \"mainColor\" },\n });\n return _pipelineColor;\n }\n _pipelineNoColor ??= device.createComputePipeline({\n layout: \"auto\",\n compute: { module: device.createShaderModule({ code: CULL_WGSL_NO_COLOR }), entryPoint: \"main\" },\n });\n return _pipelineNoColor;\n}\n\nfunction writeCullParams(engine: EngineContext, state: ThinInstanceGpuCullState, mesh: Mesh, indexCount: number, instanceCount: number, camera: Camera, aspect: number): void {\n const params = state._paramsF32;\n const viewProjection = getViewProjectionMatrix(camera, aspect);\n writeFrustumPlanes(params, viewProjection);\n params.set(mesh.worldMatrix, MESH_WORLD_FLOAT_OFFSET);\n params.set(state._localSphere, LOCAL_SPHERE_FLOAT_OFFSET);\n state._paramsU32[COUNT_U32_OFFSET] = instanceCount;\n\n const args = state._argsData;\n args[0] = indexCount;\n args[1] = 0;\n args[2] = 0;\n args[3] = 0;\n args[4] = 0;\n\n engine._device.queue.writeBuffer(state._argsBuffer!, 0, args.buffer, args.byteOffset, args.byteLength);\n engine._device.queue.writeBuffer(state._paramsBuffer!, 0, state._paramsBytes);\n}\n\nfunction writeFrustumPlanes(out: Float32Array, m: Mat4): void {\n writePlane(out, 0, m[3]! + m[0]!, m[7]! + m[4]!, m[11]! + m[8]!, m[15]! + m[12]!);\n writePlane(out, 4, m[3]! - m[0]!, m[7]! - m[4]!, m[11]! - m[8]!, m[15]! - m[12]!);\n writePlane(out, 8, m[3]! + m[1]!, m[7]! + m[5]!, m[11]! + m[9]!, m[15]! + m[13]!);\n writePlane(out, 12, m[3]! - m[1]!, m[7]! - m[5]!, m[11]! - m[9]!, m[15]! - m[13]!);\n writePlane(out, 16, m[2]!, m[6]!, m[10]!, m[14]!);\n writePlane(out, 20, m[3]! - m[2]!, m[7]! - m[6]!, m[11]! - m[10]!, m[15]! - m[14]!);\n}\n\nfunction writePlane(out: Float32Array, offset: number, x: number, y: number, z: number, w: number): void {\n const invLen = 1 / Math.hypot(x, y, z);\n out[offset] = x * invLen;\n out[offset + 1] = y * invLen;\n out[offset + 2] = z * invLen;\n out[offset + 3] = w * invLen;\n}\n\nfunction computeLocalSphere(mesh: Mesh, out: Float32Array): boolean {\n const positions = mesh._cpuPositions;\n if (!positions || positions.length < 3) {\n return false;\n }\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n for (let i = 0; i < positions.length; i += 3) {\n const x = positions[i]!;\n const y = positions[i + 1]!;\n const z = positions[i + 2]!;\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n if (z < minZ) {\n minZ = z;\n }\n if (z > maxZ) {\n maxZ = z;\n }\n }\n if (!isFinite(minX)) {\n return false;\n }\n const cx = (minX + maxX) * 0.5;\n const cy = (minY + maxY) * 0.5;\n const cz = (minZ + maxZ) * 0.5;\n const dx = maxX - cx;\n const dy = maxY - cy;\n const dz = maxZ - cz;\n out[0] = cx;\n out[1] = cy;\n out[2] = cz;\n out[3] = Math.hypot(dx, dy, dz);\n return true;\n}\n","/** Shared per-binding GPU frustum-culling lifecycle for thin-instanced renderables.\n *\n * Dynamically imported only when a scene enables thin-instance GPU culling, and\n * it statically pulls in the compute-cull module — so non-culling scenes fetch\n * neither this helper nor `thin-instance-gpu-culling.ts`.\n *\n * Factored here so Standard, PBR, and ShaderMaterial renderables share one\n * implementation of the cull lifecycle instead of copy-pasting it three times.\n * `tryBind` is the single seam a renderable's `bind()` calls: it does the\n * opaque-only gate + per-mesh `_gpuCullingEnabled` check, marks the renderable\n * `_direct` (read by the render task's buildBindings right after `bind()`\n * returns), and creates the per-binding state. The renderable then reads\n * `cullDrawBufs` for the compacted instance source and calls `binding.draw(...)`\n * for the indirect-vs-fallback draw call. Keeping these few seams tiny is what\n * lets non-culling scenes — which still fetch the per-material renderable\n * chunks — stay within their bundle-size ceilings. */\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { SceneContext } from \"../scene/scene.js\";\nimport type { DrawUpdateContext, Renderable } from \"../render/renderable.js\";\nimport type { Mesh } from \"./mesh.js\";\nimport type { ThinInstanceDrawBuffers } from \"./thin-instance-gpu.js\";\nimport { createTiCullState, destroyTiCullState, prepareTiCull } from \"./thin-instance-gpu-culling.js\";\n\n/** Per-binding cull lifecycle. The renderable's `bind()` obtains one from\n * `tryBind`, uses `update` as the binding's update, reads `cullDrawBufs` (the\n * compacted instance source) and calls `draw()` for the final draw call. */\nexport interface TiCullBinding {\n /** Run the binding's base update, then dispatch the compute cull pass and stash the result. */\n update(context: DrawUpdateContext): void;\n /** Compacted visible-instance buffers, or null to fall back to a full instanced draw. */\n cullDrawBufs: ThinInstanceDrawBuffers | null;\n /** @internal Indirect draw-args buffer (null until/unless culling ran this frame). */\n _args: GPUBuffer | null;\n /** Issue the indirect (culled) draw when visible instances were compacted, else a full instanced draw. */\n draw(pass: GPURenderPassEncoder | GPURenderBundleEncoder, indexCount: number, instanceCount: number): void;\n}\n\n/** Create a per-binding cull lifecycle for one thin-instanced renderable binding,\n * iff the mesh opts in and is not excluded (transparent / transmissive — v1 is\n * opaque-only). Marks the renderable `_direct` so it leaves the cached opaque\n * bundle; this is safe to do during `bind()` because buildBindings reads\n * `_direct` only after `bind()` returns. Returns undefined when culling does not\n * apply, so the caller falls back to a normal instanced draw. */\nexport function tryBind(\n renderable: Renderable,\n scene: SceneContext,\n mesh: Mesh,\n engine: EngineContext,\n hasColor: boolean,\n excluded: boolean,\n baseUpdate: ((context: DrawUpdateContext) => void) | undefined\n): TiCullBinding | undefined {\n const ti = mesh.thinInstances;\n if (excluded || !ti?._gpuCullingEnabled) {\n return undefined;\n }\n (renderable as { _direct?: boolean })._direct = true;\n const state = createTiCullState();\n scene._meshDisposables.get(mesh)?.push(() => {\n destroyTiCullState(state);\n });\n const binding: TiCullBinding = {\n cullDrawBufs: null,\n _args: null,\n update(context: DrawUpdateContext): void {\n baseUpdate?.(context);\n const res = prepareTiCull(engine, state, mesh, mesh._gpu, ti, hasColor, context);\n binding.cullDrawBufs = res?.drawBuffers ?? null;\n binding._args = res?.argsBuffer ?? null;\n },\n draw(pass: GPURenderPassEncoder | GPURenderBundleEncoder, indexCount: number, instanceCount: number): void {\n if (binding._args) {\n pass.drawIndexedIndirect(binding._args, 0);\n } else {\n pass.drawIndexed(indexCount, instanceCount);\n }\n },\n };\n return binding;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { B as BU, a as F32, p as packMat4IntoF32 } from "./index-CLElg2Bo.js";
|
|
1
2
|
function syncThinInstanceGpuData(engine, ti, hasColor) {
|
|
2
3
|
var _a, _b;
|
|
3
4
|
const device = engine._device;
|
|
@@ -9,7 +10,11 @@ function syncThinInstanceGpuData(engine, ti, hasColor) {
|
|
|
9
10
|
(_a = ti._gpuBuffer) == null ? void 0 : _a.destroy();
|
|
10
11
|
ti._gpuBuffer = device.createBuffer({
|
|
11
12
|
size: Math.max(ti._capacity * 64, 4),
|
|
12
|
-
|
|
13
|
+
// STORAGE is always included: the GPU picker binds this matrix
|
|
14
|
+
// buffer as a read-only storage buffer for thin-instance picking,
|
|
15
|
+
// so it must be storage-capable even when compute culling is off
|
|
16
|
+
// (otherwise the whole pick pass is invalidated → nothing is pickable).
|
|
17
|
+
usage: BU.VERTEX | BU.COPY_DST | BU.STORAGE
|
|
13
18
|
});
|
|
14
19
|
ti._gpuBufferStorage = needsStorage;
|
|
15
20
|
bufferRecreated = true;
|
|
@@ -19,7 +24,19 @@ function syncThinInstanceGpuData(engine, ti, hasColor) {
|
|
|
19
24
|
if (dirtyMax > dirtyMin) {
|
|
20
25
|
const minByte = dirtyMin * 64;
|
|
21
26
|
const maxByte = dirtyMax * 64;
|
|
22
|
-
|
|
27
|
+
if (ti.matrices instanceof F32) {
|
|
28
|
+
device.queue.writeBuffer(ti._gpuBuffer, minByte, ti.matrices.buffer, ti.matrices.byteOffset + minByte, maxByte - minByte);
|
|
29
|
+
} else {
|
|
30
|
+
const neededFloats = ti._capacity * 16;
|
|
31
|
+
if (!ti._uploadF32 || ti._uploadF32.length < neededFloats) {
|
|
32
|
+
ti._uploadF32 = new F32(neededFloats);
|
|
33
|
+
}
|
|
34
|
+
const upload = ti._uploadF32;
|
|
35
|
+
for (let i = dirtyMin; i < dirtyMax; i++) {
|
|
36
|
+
packMat4IntoF32(upload, ti.matrices, i * 16, i * 16);
|
|
37
|
+
}
|
|
38
|
+
device.queue.writeBuffer(ti._gpuBuffer, minByte, upload.buffer, upload.byteOffset + minByte, maxByte - minByte);
|
|
39
|
+
}
|
|
23
40
|
}
|
|
24
41
|
ti._dirtyMin = ti.count;
|
|
25
42
|
ti._dirtyMax = 0;
|
|
@@ -28,15 +45,23 @@ function syncThinInstanceGpuData(engine, ti, hasColor) {
|
|
|
28
45
|
if (hasColor && ti.colors) {
|
|
29
46
|
if (ti._colorVersion !== ti._colorGpuVersion || ti._colorGpuBufferStorage !== needsStorage) {
|
|
30
47
|
const colorByteSize = ti.count * 16;
|
|
48
|
+
let colorRecreated = false;
|
|
31
49
|
if (!ti._colorGpuBuffer || ti._colorGpuBuffer.size < colorByteSize || ti._colorGpuBufferStorage !== needsStorage) {
|
|
32
50
|
(_b = ti._colorGpuBuffer) == null ? void 0 : _b.destroy();
|
|
33
51
|
ti._colorGpuBuffer = device.createBuffer({
|
|
34
52
|
size: Math.max(ti._capacity * 16, 4),
|
|
35
|
-
usage:
|
|
53
|
+
usage: BU.VERTEX | BU.COPY_DST | (needsStorage ? BU.STORAGE : 0)
|
|
36
54
|
});
|
|
37
55
|
ti._colorGpuBufferStorage = needsStorage;
|
|
56
|
+
colorRecreated = true;
|
|
57
|
+
}
|
|
58
|
+
const cMin = colorRecreated ? 0 : ti._colorDirtyMin;
|
|
59
|
+
const cMax = colorRecreated ? ti.count : Math.min(ti._colorDirtyMax, ti.count);
|
|
60
|
+
if (cMax > cMin) {
|
|
61
|
+
device.queue.writeBuffer(ti._colorGpuBuffer, cMin * 16, ti.colors.buffer, ti.colors.byteOffset + cMin * 16, (cMax - cMin) * 16);
|
|
38
62
|
}
|
|
39
|
-
|
|
63
|
+
ti._colorDirtyMin = ti.count;
|
|
64
|
+
ti._colorDirtyMax = 0;
|
|
40
65
|
ti._colorGpuVersion = ti._colorVersion;
|
|
41
66
|
}
|
|
42
67
|
}
|
|
@@ -59,4 +84,4 @@ export {
|
|
|
59
84
|
syncThinInstanceBuffers,
|
|
60
85
|
syncThinInstanceGpuData
|
|
61
86
|
};
|
|
62
|
-
//# sourceMappingURL=thin-instance-gpu-
|
|
87
|
+
//# sourceMappingURL=thin-instance-gpu-BDdRcNAh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thin-instance-gpu-BDdRcNAh.js","sources":["../src/mesh/thin-instance-gpu.ts"],"sourcesContent":["/** Thin instance GPU buffer sync — dynamically loaded only by scenes with thin instances.\n * Keeps the standard renderable chunk unchanged for scenes without thin instances. */\n\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { ThinInstanceData } from \"./thin-instance.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { packMat4IntoF32 } from \"../math/pack-mat4-into-f32.js\";\n\n/** @internal Optional replacement buffers used by GPU culling after it compacts visible instances. */\nexport interface ThinInstanceDrawBuffers {\n readonly matrixBuffer: GPUBuffer;\n readonly colorBuffer: GPUBuffer | null;\n}\n\n/** @internal Sync CPU thin-instance data to GPU buffers, optionally with STORAGE usage for compute culling. */\nexport function syncThinInstanceGpuData(engine: EngineContext, ti: ThinInstanceData, hasColor: boolean): void {\n const device = engine._device;\n const needsStorage = ti._gpuCullingEnabled;\n if (ti._version !== ti._gpuVersion || ti._gpuBufferStorage !== needsStorage) {\n const byteSize = ti.count * 64;\n let bufferRecreated = false;\n if (!ti._gpuBuffer || ti._gpuBuffer.size < byteSize || ti._gpuBufferStorage !== needsStorage) {\n ti._gpuBuffer?.destroy();\n ti._gpuBuffer = device.createBuffer({\n size: Math.max(ti._capacity * 64, 4),\n // STORAGE is always included: the GPU picker binds this matrix\n // buffer as a read-only storage buffer for thin-instance picking,\n // so it must be storage-capable even when compute culling is off\n // (otherwise the whole pick pass is invalidated → nothing is pickable).\n usage: BU.VERTEX | BU.COPY_DST | BU.STORAGE,\n });\n ti._gpuBufferStorage = needsStorage;\n bufferRecreated = true;\n }\n // Upload only the dirty range (or full range if buffer was just created)\n const dirtyMin = bufferRecreated ? 0 : ti._dirtyMin;\n const dirtyMax = bufferRecreated ? ti.count : Math.min(ti._dirtyMax, ti.count);\n if (dirtyMax > dirtyMin) {\n const minByte = dirtyMin * 64;\n const maxByte = dirtyMax * 64;\n if (ti.matrices instanceof F32) {\n // Fast path: F32 source — direct byte copy, no per-instance pack.\n device.queue.writeBuffer(ti._gpuBuffer, minByte, ti.matrices.buffer, ti.matrices.byteOffset + minByte, maxByte - minByte);\n } else {\n // F64 source (HPM-on path) — pack each dirty instance into a\n // per-mesh reused F32 upload scratch, then writeBuffer the\n // dirty subrange. Scratch is sized to capacity in F32 floats\n // and grown when capacity grows; never per-frame allocated.\n const neededFloats = ti._capacity * 16;\n if (!ti._uploadF32 || ti._uploadF32.length < neededFloats) {\n ti._uploadF32 = new F32(neededFloats);\n }\n const upload = ti._uploadF32;\n for (let i = dirtyMin; i < dirtyMax; i++) {\n packMat4IntoF32(upload, ti.matrices, i * 16, i * 16);\n }\n device.queue.writeBuffer(ti._gpuBuffer, minByte, upload.buffer, upload.byteOffset + minByte, maxByte - minByte);\n }\n }\n ti._dirtyMin = ti.count;\n ti._dirtyMax = 0;\n ti._gpuVersion = ti._version;\n }\n\n if (hasColor && ti.colors) {\n if (ti._colorVersion !== ti._colorGpuVersion || ti._colorGpuBufferStorage !== needsStorage) {\n const colorByteSize = ti.count * 16;\n let colorRecreated = false;\n if (!ti._colorGpuBuffer || ti._colorGpuBuffer.size < colorByteSize || ti._colorGpuBufferStorage !== needsStorage) {\n ti._colorGpuBuffer?.destroy();\n ti._colorGpuBuffer = device.createBuffer({\n size: Math.max(ti._capacity * 16, 4),\n usage: BU.VERTEX | BU.COPY_DST | (needsStorage ? BU.STORAGE : 0),\n });\n ti._colorGpuBufferStorage = needsStorage;\n colorRecreated = true;\n }\n // Upload only the dirty colour range (mirrors the matrix path) — full range on (re)create.\n const cMin = colorRecreated ? 0 : ti._colorDirtyMin;\n const cMax = colorRecreated ? ti.count : Math.min(ti._colorDirtyMax, ti.count);\n if (cMax > cMin) {\n device.queue.writeBuffer(ti._colorGpuBuffer, cMin * 16, ti.colors.buffer, ti.colors.byteOffset + cMin * 16, (cMax - cMin) * 16);\n }\n ti._colorDirtyMin = ti.count;\n ti._colorDirtyMax = 0;\n ti._colorGpuVersion = ti._colorVersion;\n }\n }\n}\n\n/** Sync thin instance matrix + optional color GPU buffers and bind to vertex slots. */\nexport function syncThinInstanceBuffers(\n engine: EngineContext,\n ti: ThinInstanceData,\n pass: GPURenderPassEncoder | GPURenderBundleEncoder,\n slot: number,\n hasColor: boolean,\n drawBuffers?: ThinInstanceDrawBuffers | null\n): number {\n syncThinInstanceGpuData(engine, ti, hasColor);\n const matrixBuffer = drawBuffers?.matrixBuffer ?? ti._gpuBuffer;\n if (matrixBuffer) {\n pass.setVertexBuffer(slot++, matrixBuffer);\n }\n\n if (hasColor) {\n const colorBuffer = drawBuffers?.colorBuffer ?? ti._colorGpuBuffer;\n if (colorBuffer) {\n pass.setVertexBuffer(slot++, colorBuffer);\n }\n }\n\n return slot;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as markMaterialUboDirty } from "./index-
|
|
1
|
+
import { m as markMaterialUboDirty } from "./index-CLElg2Bo.js";
|
|
2
2
|
function observableColor3(r, g, b, owner) {
|
|
3
3
|
const arr = [r, g, b];
|
|
4
4
|
for (let i = 0; i < 3; i++) {
|
|
@@ -79,4 +79,4 @@ export {
|
|
|
79
79
|
observableColor3 as o,
|
|
80
80
|
trackScalar as t
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=tracking-primitives-
|
|
82
|
+
//# sourceMappingURL=tracking-primitives-CglRNTlX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking-primitives-
|
|
1
|
+
{"version":3,"file":"tracking-primitives-CglRNTlX.js","sources":["../src/material/tracking/tracking-primitives.ts"],"sourcesContent":["/** Shared tracking primitives for observable material properties. */\n\nimport type { Material } from \"../material.js\";\nimport { markMaterialUboDirty } from \"../material-dirty.js\";\n\nexport function observableColor3(r: number, g: number, b: number, owner: Material): [number, number, number] {\n const arr = [r, g, b] as [number, number, number];\n for (let i = 0; i < 3; i++) {\n let val = arr[i]!;\n Object.defineProperty(arr, i, {\n get() {\n return val;\n },\n set(v: number) {\n if (val !== v) {\n val = v;\n markMaterialUboDirty(owner);\n }\n },\n configurable: true,\n enumerable: true,\n });\n }\n return arr;\n}\n\nexport function observableVec2(x: number, y: number, owner: Material): [number, number] {\n const arr = [x, y] as [number, number];\n for (let i = 0; i < 2; i++) {\n let val = arr[i]!;\n Object.defineProperty(arr, i, {\n get() {\n return val;\n },\n set(v: number) {\n if (val !== v) {\n val = v;\n markMaterialUboDirty(owner);\n }\n },\n configurable: true,\n enumerable: true,\n });\n }\n return arr;\n}\n\nexport function trackScalar(obj: any, key: string): void {\n let val = obj[key];\n Object.defineProperty(obj, key, {\n get() {\n return val;\n },\n set(v: any) {\n if (val !== v) {\n val = v;\n markMaterialUboDirty(obj as Material);\n }\n },\n configurable: true,\n enumerable: true,\n });\n}\n\nexport function trackSubProps(parent: Material, sub: any, keys: string[]): void {\n for (const key of keys) {\n let val = sub[key];\n Object.defineProperty(sub, key, {\n get() {\n return val;\n },\n set(v: any) {\n if (val !== v) {\n val = v;\n markMaterialUboDirty(parent);\n }\n },\n configurable: true,\n enumerable: true,\n });\n }\n}\n"],"names":[],"mappings":";AAKO,SAAS,iBAAiB,GAAW,GAAW,GAAW,OAA2C;AACzG,QAAM,MAAM,CAAC,GAAG,GAAG,CAAC;AACpB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,QAAI,MAAM,IAAI,CAAC;AACf,WAAO,eAAe,KAAK,GAAG;AAAA,MAC1B,MAAM;AACF,eAAO;AAAA,MACX;AAAA,MACA,IAAI,GAAW;AACX,YAAI,QAAQ,GAAG;AACX,gBAAM;AACN,+BAAqB,KAAK;AAAA,QAC9B;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,MACd,YAAY;AAAA,IAAA,CACf;AAAA,EACL;AACA,SAAO;AACX;AAEO,SAAS,eAAe,GAAW,GAAW,OAAmC;AACpF,QAAM,MAAM,CAAC,GAAG,CAAC;AACjB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,QAAI,MAAM,IAAI,CAAC;AACf,WAAO,eAAe,KAAK,GAAG;AAAA,MAC1B,MAAM;AACF,eAAO;AAAA,MACX;AAAA,MACA,IAAI,GAAW;AACX,YAAI,QAAQ,GAAG;AACX,gBAAM;AACN,+BAAqB,KAAK;AAAA,QAC9B;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,MACd,YAAY;AAAA,IAAA,CACf;AAAA,EACL;AACA,SAAO;AACX;AAEO,SAAS,YAAY,KAAU,KAAmB;AACrD,MAAI,MAAM,IAAI,GAAG;AACjB,SAAO,eAAe,KAAK,KAAK;AAAA,IAC5B,MAAM;AACF,aAAO;AAAA,IACX;AAAA,IACA,IAAI,GAAQ;AACR,UAAI,QAAQ,GAAG;AACX,cAAM;AACN,6BAAqB,GAAe;AAAA,MACxC;AAAA,IACJ;AAAA,IACA,cAAc;AAAA,IACd,YAAY;AAAA,EAAA,CACf;AACL;AAEO,SAAS,cAAc,QAAkB,KAAU,MAAsB;AAC5E,aAAW,OAAO,MAAM;AACpB,QAAI,MAAM,IAAI,GAAG;AACjB,WAAO,eAAe,KAAK,KAAK;AAAA,MAC5B,MAAM;AACF,eAAO;AAAA,MACX;AAAA,MACA,IAAI,GAAQ;AACR,YAAI,QAAQ,GAAG;AACX,gBAAM;AACN,+BAAqB,MAAM;AAAA,QAC/B;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,MACd,YAAY;AAAA,IAAA,CACf;AAAA,EACL;AACJ;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b3 as PBR2_HAS_UNLIT } from "./index-CLElg2Bo.js";
|
|
2
2
|
function createUnlitFragment(hasIbl) {
|
|
3
3
|
const assign = `color = baseColor * material.unlitColor;`;
|
|
4
4
|
return {
|
|
@@ -40,4 +40,4 @@ export {
|
|
|
40
40
|
pbrExt,
|
|
41
41
|
writeUnlitUBO
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=unlit-fragment-
|
|
43
|
+
//# sourceMappingURL=unlit-fragment-kxfZWlnp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlit-fragment-
|
|
1
|
+
{"version":3,"file":"unlit-fragment-kxfZWlnp.js","sources":["../src/material/pbr/fragments/unlit-fragment.ts"],"sourcesContent":["/**\n * Unlit Fragment (KHR_materials_unlit).\n *\n * Replaces the lit-color computation with `baseColor * unlitColor` right\n * before the tonemap/gamma/contrast chain runs. Depends on the IBL fragment\n * when present so our AI injection runs *after* IBL's, overwriting the IBL\n * color contribution. The subsequent tonemap/gamma/contrast stages still\n * apply, matching BJS's unlit output under `createDefaultEnvironment`.\n *\n * Zero bytes in bundles for scenes that don't use unlit materials.\n */\n\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR2_HAS_UNLIT } from \"../pbr-flag-bits.js\";\n\nexport function createUnlitFragment(hasIbl: boolean): ShaderFragment {\n const assign = `color = baseColor * material.unlitColor;`;\n return {\n _id: \"unlit\",\n _dependencies: hasIbl ? [\"ibl\"] : undefined,\n _uboFields: [\n { _name: \"unlitColor\", _type: \"vec3<f32>\" },\n { _name: \"_unlitColorPad\", _type: \"f32\" },\n ],\n _fragmentSlots: hasIbl ? { AI: assign } : { NI: assign },\n };\n}\n\n/** Write the unlit material-UBO slice. */\nexport function writeUnlitUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n if (!material.unlit || !offsets.has(\"unlitColor\")) {\n return;\n }\n const off = offsets.get(\"unlitColor\")! / 4;\n const tint = material.unlitColor ?? [1, 1, 1];\n data[off] = tint[0]!;\n data[off + 1] = tint[1]!;\n data[off + 2] = tint[2]!;\n}\n\nexport const pbrExt: PbrExt = {\n id: \"unlit\",\n phase: \"fragment\",\n detect(mat) {\n return (mat as PbrMaterialProps).unlit ? { f: 0, f2: PBR2_HAS_UNLIT } : { f: 0, f2: 0 };\n },\n frag(ctx) {\n if (!(ctx._features2 & PBR2_HAS_UNLIT)) {\n return null;\n }\n return createUnlitFragment(ctx._hasIbl);\n },\n writeUbo: writeUnlitUBO as PbrExt[\"writeUbo\"],\n};\n"],"names":[],"mappings":";AAiBO,SAAS,oBAAoB,QAAiC;AACjE,QAAM,SAAS;AACf,SAAO;AAAA,IACH,KAAK;AAAA,IACL,eAAe,SAAS,CAAC,KAAK,IAAI;AAAA,IAClC,YAAY;AAAA,MACR,EAAE,OAAO,cAAc,OAAO,YAAA;AAAA,MAC9B,EAAE,OAAO,kBAAkB,OAAO,MAAA;AAAA,IAAM;AAAA,IAE5C,gBAAgB,SAAS,EAAE,IAAI,WAAW,EAAE,IAAI,OAAA;AAAA,EAAO;AAE/D;AAGO,SAAS,cAAc,MAAoB,UAA4B,SAA4C;AACtH,MAAI,CAAC,SAAS,SAAS,CAAC,QAAQ,IAAI,YAAY,GAAG;AAC/C;AAAA,EACJ;AACA,QAAM,MAAM,QAAQ,IAAI,YAAY,IAAK;AACzC,QAAM,OAAO,SAAS,cAAc,CAAC,GAAG,GAAG,CAAC;AAC5C,OAAK,GAAG,IAAI,KAAK,CAAC;AAClB,OAAK,MAAM,CAAC,IAAI,KAAK,CAAC;AACtB,OAAK,MAAM,CAAC,IAAI,KAAK,CAAC;AAC1B;AAEO,MAAM,SAAiB;AAAA,EAC1B,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,OAAO,KAAK;AACR,WAAQ,IAAyB,QAAQ,EAAE,GAAG,GAAG,IAAI,eAAA,IAAmB,EAAE,GAAG,GAAG,IAAI,EAAA;AAAA,EACxF;AAAA,EACA,KAAK,KAAK;AACN,QAAI,EAAE,IAAI,aAAa,iBAAiB;AACpC,aAAO;AAAA,IACX;AACA,WAAO,oBAAoB,IAAI,OAAO;AAAA,EAC1C;AAAA,EACA,UAAU;AACd;"}
|
|
@@ -41,8 +41,8 @@ return mix(-normVariance, normVariance, rand);
|
|
|
41
41
|
const WGSL_NO_DITHER = "fn dither(a:vec2<f32>,b:f32)->f32{return 0.0;}";
|
|
42
42
|
export {
|
|
43
43
|
WGSL_PERTURB_NORMAL as W,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
WGSL_FOG as a,
|
|
45
|
+
WGSL_DITHER as b,
|
|
46
|
+
WGSL_NO_DITHER as c
|
|
47
47
|
};
|
|
48
|
-
//# sourceMappingURL=wgsl-helpers-
|
|
48
|
+
//# sourceMappingURL=wgsl-helpers-D8sl1VVA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgsl-helpers-
|
|
1
|
+
{"version":3,"file":"wgsl-helpers-D8sl1VVA.js","sources":["../src/shader/wgsl-helpers.ts"],"sourcesContent":["/** Shared WGSL helper snippets used by both PBR and Standard material systems.\n *\n * These are pure WGSL function strings — no bindings, no UBO declarations.\n * Each material system wraps them with its own binding declarations. */\n\n/** Cotangent-frame bump mapping.\n * Requires: `bT` (texture_2d) and `bS` (sampler) in scope. */\nexport const WGSL_PERTURB_NORMAL = `\nfn perturbNormal(vNormalW: vec3<f32>, positionW: vec3<f32>, uv: vec2<f32>, bumpScale: f32) -> vec3<f32> {\nlet normalSample = textureSample(bT, bS, uv).rgb * 2.0 - 1.0;\nlet N = normalize(vNormalW) * bumpScale;\nlet dp1 = dpdx(positionW);\nlet dp2 = -dpdy(positionW);\nlet duv1 = dpdx(uv);\nlet duv2 = -dpdy(uv);\nlet dp2perp = cross(dp2, N);\nlet dp1perp = cross(N, dp1);\nvar tangent = dp2perp * duv1.x + dp1perp * duv2.x;\nvar bitangent = dp2perp * duv1.y + dp1perp * duv2.y;\nlet det = max(dot(tangent, tangent), dot(bitangent, bitangent));\nlet invmax = select(inverseSqrt(det), 0.0, det == 0.0);\nlet cotangentFrame = mat3x3<f32>(tangent * invmax, bitangent * invmax, N);\nreturn normalize(cotangentFrame * normalSample);\n}\n`;\n\n/** ESM shadow helper functions.\n * Requires: `shadowTex` (texture_2d), `shadowSampler` (sampler) in scope. */\nexport const WGSL_SHADOW_ESM = `\nfn computeFallOff(value: f32, clipSpace: vec2<f32>, frustumEdgeFalloff: f32) -> f32 {\nlet mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpace, clipSpace), 0.0, 1.0));\nreturn mix(value, 1.0, mask);\n}\nfn computeShadowWithESM(posFromLight: vec4<f32>, depthMetric: f32, darkness: f32, depthScale: f32, frustumEdgeFalloff: f32) -> f32 {\nlet clipSpace = posFromLight.xyz / posFromLight.w;\nlet uv = vec2<f32>(0.5 * clipSpace.x + 0.5, 0.5 - 0.5 * clipSpace.y);\nif (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return 1.0; }\nlet shadowPixelDepth = clamp(depthMetric, 0.0, 1.0);\nlet shadowMapSample = textureSampleLevel(shadowTex, shadowSampler, uv, 0.0).x;\nlet esm = 1.0 - clamp(exp(min(87.0, depthScale * shadowPixelDepth)) * shadowMapSample, 0.0, 1.0 - darkness);\nreturn computeFallOff(esm, clipSpace.xy, frustumEdgeFalloff);\n}\n`;\n\n/** Fog calculation helper.\n * Requires: `scene.vFogInfos` (vec4) in scope. */\nexport const WGSL_FOG = `\nconst E_FOG: f32 = 2.71828;\nfn calcFogFactor(fogDistance: vec3<f32>) -> f32 {\nvar fogCoeff: f32 = 1.0;\nlet fogMode = scene.vFogInfos.x;\nlet fogStart = scene.vFogInfos.y;\nlet fogEnd = scene.vFogInfos.z;\nlet fogDensity = scene.vFogInfos.w;\nlet dist = length(fogDistance);\nif (fogMode == 3.0) { fogCoeff = (fogEnd - dist) / (fogEnd - fogStart); }\nelse if (fogMode == 1.0) { fogCoeff = 1.0 / pow(E_FOG, dist * fogDensity); }\nelse if (fogMode == 2.0) { fogCoeff = 1.0 / pow(E_FOG, dist * dist * fogDensity * fogDensity); }\nreturn clamp(fogCoeff, 0.0, 1.0);\n}\n`;\n\n/** Dither noise function.\n * Pure math — no UBO dependency. */\nexport const WGSL_DITHER = `\nfn dither(seed: vec2<f32>, varianceAmount: f32) -> f32 {\nlet rand = fract(sin(dot(seed, vec2<f32>(12.9898, 78.233))) * 43758.5453);\nlet normVariance = varianceAmount / 255.0;\nreturn mix(-normVariance, normVariance, rand);\n}\n`;\n\n/** Noise-disabled replacement for shaders that still call dither(). */\nexport const WGSL_NO_DITHER = \"fn dither(a:vec2<f32>,b:f32)->f32{return 0.0;}\";\n"],"names":[],"mappings":"AAOO,MAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuC5B,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBjB,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB,MAAM,iBAAiB;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"splat-sort-worker-Crg3CaCc.js","sources":["../src/loader-splat/splat-sort-worker.ts"],"sourcesContent":["/** Splat sort worker.\n *\n * Vite import: `import SortWorker from './splat-sort-worker.ts?worker&inline'`.\n * The `?worker&inline` query keeps the bundled worker JS embedded as a base-64\n * blob in the splat scene chunk — it adds zero bytes to any other scene\n * because the whole `loader-splat/` module is dynamic-imported.\n *\n * Protocol\n * --------\n * Init (once): `{ p: Float32Array, n: number }`\n * — buffer is transferred and retained on the worker side.\n * — positions are in mesh-LOCAL space (stride 3, xyz per splat).\n * Sort (N×): `{ m: Float32Array(16), f: Float32Array(3), c: Float32Array(3), d: BigInt64Array }`\n * — depthMix is round-tripped via transferable; layout is\n * high-32 bits = packed depth (then bit-inverted), low-32 bits = splat index.\n * After sort, low-32 bits give the back-to-front order.\n *\n * Depth recipe (mirrors BJS `_CreateWorker`)\n * ------------------------------------------\n * Per-frame the main thread sends the mesh's world matrix, the camera's\n * world-space forward vector and the camera's world-space position. The\n * worker collapses these into 4 scalars (a, b, c, d) such that\n * depth = a*localX + b*localY + c*localZ + d\n * = cameraForward · (world · localPos - cameraPosition).\n * This is more robust than the previous `10000 - dot(view-row, pos)` recipe:\n * - it accounts for non-identity world matrices (BJS Lite previously ignored them);\n * - it has no magic reference value, so it doesn't lose precision when\n * depths are large or wrap signs when depths exceed the reference;\n * - the back-to-front order is produced by bit-inverting the high 32 bits\n * of each i64 slot (`~indices[2j+1]`) instead of subtracting depths from\n * a constant — this preserves the full float precision range. */\n\nlet positions: Float32Array | null = null;\nlet vertexCount = 0;\n\nself.onmessage = (e: MessageEvent) => {\n const data = e.data as {\n p?: Float32Array;\n n?: number;\n m?: Float32Array;\n f?: Float32Array;\n c?: Float32Array;\n d?: BigInt64Array;\n };\n\n if (data.p) {\n positions = data.p;\n vertexCount = data.n ?? 0;\n return;\n }\n\n if (!positions || !data.m || !data.f || !data.c || !data.d) {\n return;\n }\n\n const m = data.m;\n const cf = data.f;\n const cp = data.c;\n const depthMix = data.d;\n const indices = new Uint32Array(depthMix.buffer);\n const floatMix = new Float32Array(depthMix.buffer);\n\n // Collapse cameraForward · (world · localPos - cameraPos) into (a*x + b*y + c*z + d).\n // Lite column-major: world's column k lives at indices [4k, 4k+1, 4k+2, 4k+3]\n // (the 4th row is always [0,0,0,1] for an affine matrix, so we skip m[3,7,11,15]).\n const camDot = cf[0]! * cp[0]! + cf[1]! * cp[1]! + cf[2]! * cp[2]!;\n const a = cf[0]! * m[0]! + cf[1]! * m[1]! + cf[2]! * m[2]!;\n const b = cf[0]! * m[4]! + cf[1]! * m[5]! + cf[2]! * m[6]!;\n const c = cf[0]! * m[8]! + cf[1]! * m[9]! + cf[2]! * m[10]!;\n const d = cf[0]! * m[12]! + cf[1]! * m[13]! + cf[2]! * m[14]! - camDot;\n\n for (let j = 0; j < vertexCount; j++) {\n indices[2 * j] = j;\n floatMix[2 * j + 1] = a * positions[3 * j]! + b * positions[3 * j + 1]! + c * positions[3 * j + 2]! + d;\n // Bit-invert the high 32 bits (where the depth float lives) so that\n // BigInt64Array.sort() yields back-to-front order without subtracting\n // depths from a constant (which would cap range and erode precision).\n indices[2 * j + 1] = ~indices[2 * j + 1]!;\n }\n\n depthMix.sort();\n\n (self as unknown as { postMessage: (m: unknown, t?: Transferable[]) => void }).postMessage({ d: depthMix }, [depthMix.buffer]);\n};\n"],"names":[],"mappings":";;AAgCA,MAAI,YAAiC;AACrC,MAAI,cAAc;AAElB,OAAK,YAAY,CAAC,MAAoB;AAClC,UAAM,OAAO,EAAE;AASf,QAAI,KAAK,GAAG;AACR,kBAAY,KAAK;AACjB,oBAAc,KAAK,KAAK;AACxB;AAAA,IACJ;AAEA,QAAI,CAAC,aAAa,CAAC,KAAK,KAAK,CAAC,KAAK,KAAK,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG;AACxD;AAAA,IACJ;AAEA,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK;AAChB,UAAM,WAAW,KAAK;AACtB,UAAM,UAAU,IAAI,YAAY,SAAS,MAAM;AAC/C,UAAM,WAAW,IAAI,aAAa,SAAS,MAAM;AAKjD,UAAM,SAAS,GAAG,CAAC,IAAK,GAAG,CAAC,IAAK,GAAG,CAAC,IAAK,GAAG,CAAC,IAAK,GAAG,CAAC,IAAK,GAAG,CAAC;AAChE,UAAM,IAAI,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,CAAC;AACxD,UAAM,IAAI,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,CAAC;AACxD,UAAM,IAAI,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,CAAC,IAAK,GAAG,CAAC,IAAK,EAAE,EAAE;AACzD,UAAM,IAAI,GAAG,CAAC,IAAK,EAAE,EAAE,IAAK,GAAG,CAAC,IAAK,EAAE,EAAE,IAAK,GAAG,CAAC,IAAK,EAAE,EAAE,IAAK;AAEhE,aAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AAClC,cAAQ,IAAI,CAAC,IAAI;AACjB,eAAS,IAAI,IAAI,CAAC,IAAI,IAAI,UAAU,IAAI,CAAC,IAAK,IAAI,UAAU,IAAI,IAAI,CAAC,IAAK,IAAI,UAAU,IAAI,IAAI,CAAC,IAAK;AAItG,cAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC3C;AAEA,aAAS,KAAA;AAER,SAA8E,YAAY,EAAE,GAAG,YAAY,CAAC,SAAS,MAAM,CAAC;AAAA,EACjI;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"background-dds-skybox-yHTqabU3.js","sources":["../shaders/skybox-dds.vertex.wgsl?raw","../shaders/skybox-dds.fragment.wgsl?raw","../src/material/pbr/background-dds-skybox.ts"],"sourcesContent":["export default \"// DDS Skybox Vertex Shader — standard world transform.\\n// positionUVW uses local position for cube direction lookup.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) clipPos: vec4<f32>,\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@vertex\\nfn main(@location(0) position: vec3<f32>) -> VertexOutput {\\n var output: VertexOutput;\\n output.positionUVW = position;\\n let worldPos = (mesh.world * vec4<f32>(position, 1.0)).xyz;\\n output.positionW = worldPos;\\n output.clipPos = scene.viewProjection * vec4<f32>(worldPos, 1.0);\\n return output;\\n}\\n\"","export default \"// DDS Cube Skybox Fragment Shader — samples DDS cube texture with BJS image processing.\\n// Used by scenes that load backgroundSkybox.dds (createDefaultEnvironment).\\n// Pipeline: exposure → Reinhard tonemap → gamma → contrast → dither.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n exposureLinear: f32,\\n contrast: f32,\\n _pad1: f32,\\n _pad2: f32,\\n _pad3: f32,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n@group(1) @binding(1) var envCubemap: texture_cube<f32>;\\n@group(1) @binding(2) var envSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let dir = normalize(input.positionUVW);\\n var color = textureSampleLevel(envCubemap, envSampler, dir, 0.0).rgb;\\n\\n // BJS BackgroundMaterial: colorBase = reflectionColor.rgb * primaryColor.rgb\\n color *= mesh.primaryColor;\\n\\n if (scene.vImageInfos.w >= 0.0) {\\n // Exposure\\n color *= mesh.exposureLinear;\\n // Reinhard tonemap (matches BJS toneMappingType 0)\\n color = 1.0 - exp2(-1.590579 * color);\\n // Gamma\\n color = pow(color, vec3<f32>(1.0 / 2.2));\\n color = saturate(color);\\n\\n // Contrast\\n let highContrast = color * color * (3.0 - 2.0 * color);\\n color = mix(color, highContrast, mesh.contrast - 1.0);\\n\\n // Dithering (enableNoise=true, variance=0.5)\\n color = color + vec3<f32>(dither(input.positionW.xy, 0.5));\\n color = max(color, vec3<f32>(0.0));\\n }\\n\\n return vec4<f32>(color, 1.0);\\n}\\n\"","/** DDS cube skybox — lazy-loaded only when skyboxUrl ends with .dds.\n * Loads backgroundSkybox.dds and renders it with BJS image processing. */\n\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport { getOrCreateSampler } from \"../../resource/gpu-pool.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { WGSL_DITHER, WGSL_NO_DITHER } from \"../../shader/wgsl-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createCubemapSkyboxMaterial } from \"./cubemap-skybox-material.js\";\nimport ddsSkyboxVertSrc from \"../../../shaders/skybox-dds.vertex.wgsl?raw\";\nimport ddsSkyboxFragSrc from \"../../../shaders/skybox-dds.fragment.wgsl?raw\";\n\nconst SKY_DDS_UNIFORM_SIZE = 96;\nconst DEFAULT_SKY_URL = \"https://assets.babylonjs.com/core/environments/backgroundSkybox.dds\";\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer; idxCount: number } {\n // prettier-ignore\n const positions = new Float32Array([\n S,-S, S, -S,-S, S, -S, S, S, S, S, S,\n S, S,-S, -S, S,-S, -S,-S,-S, S,-S,-S,\n S, S,-S, S,-S,-S, S,-S, S, S, S, S,\n -S, S, S, -S,-S, S, -S,-S,-S, -S, S,-S,\n -S, S, S, -S, S,-S, S, S,-S, S, S, S,\n S,-S, S, S,-S,-S, -S,-S,-S, -S,-S, S,\n ]);\n // prettier-ignore\n const indices = new Uint16Array([\n 2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4,\n 10, 9, 8, 11,10, 8, 14,13,12, 15,14,12,\n 18,17,16, 19,18,16, 22,21,20, 23,22,20,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, GPUBufferUsage.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, GPUBufferUsage.INDEX),\n idxCount: 36,\n };\n}\n\nfunction buildSkyboxWorldMatrix(rootPosition: [number, number, number]): Mat4 {\n const world = new Float32Array(16) as Mat4;\n world[0] = 1;\n world[5] = 1;\n world[10] = 1;\n world[15] = 1;\n world[12] = rootPosition[0];\n world[13] = rootPosition[1];\n world[14] = rootPosition[2];\n return world;\n}\n\n/** Build a DDS cube skybox as a complete Renderable (order 0). */\nexport async function buildDdsSkyboxRenderable(\n scene: SceneContext,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number],\n skyboxTextureUrl?: string,\n enableNoise = true\n): Promise<Renderable> {\n const engine = scene.engine;\n\n const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);\n\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n const { cubeView, sampler } = await loadDdsCube(engine, skyboxTextureUrl ?? DEFAULT_SKY_URL);\n\n const fragCode = SCENE_UBO_WGSL + (enableNoise ? WGSL_DITHER : WGSL_NO_DITHER) + ddsSkyboxFragSrc;\n const mat = createCubemapSkyboxMaterial(enableNoise ? \"skybox-dds\" : \"skybox-dds0\", SCENE_UBO_WGSL + ddsSkyboxVertSrc, fragCode);\n const ubo = createDdsMeshUBO(engine, skyboxWorld, primaryColor, scene.imageProcessing.exposure, scene.imageProcessing.contrast);\n const bindGroup = mat.createBindGroup(engine, ubo, cubeView, sampler);\n\n const r: Renderable = {\n order: 0,\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: mat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(skyBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── DDS Skybox UBO ──────────────────────────────────────────────────────────\n\nfunction createDdsMeshUBO(engine: EngineContext, world: Float32Array, primaryColor: [number, number, number], exposureLinear: number, contrast: number): GPUBuffer {\n const data = new Float32Array(SKY_DDS_UNIFORM_SIZE / 4);\n data.set(world, 0);\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[19] = exposureLinear;\n data[20] = contrast;\n return createUniformBuffer(engine, data);\n}\n\n// ─── DDS Cube Texture Loader ─────────────────────────────────────────────────\n\n/** Load a DDS cube texture (rgba16float) and return a cube texture view + sampler.\n * Uploads only mip 0 from the DDS file and generates remaining mipmaps on the\n * GPU so that cube face edges blend seamlessly — matching BJS's behaviour. */\nasync function loadDdsCube(engine: EngineContext, url: string): Promise<{ cubeView: GPUTextureView; sampler: GPUSampler }> {\n const device = engine._device;\n const buf = await (await fetch(url)).arrayBuffer();\n const header = new Int32Array(buf, 0, 32);\n const width = header[3]!;\n const height = header[4]!;\n const mipCount = Math.max(header[7]!, 1);\n\n // DDS pixel format offset 76..107 — for rgba16float, FourCC = 'DX10'\n // DDS_HEADER_DX10 at byte 128: dxgiFormat, resourceDimension, miscFlag, arraySize, etc.\n // For cube: miscFlag has RESOURCE_MISC_TEXTURECUBE (0x4), arraySize = 1 (6 faces in data)\n const dataOffset = header[21] === 0x30315844 /* 'DX10' */ ? 128 + 20 : 128;\n const raw = new Uint8Array(buf, dataOffset);\n\n const fmt: GPUTextureFormat = \"rgba16float\";\n const tex = device.createTexture({\n size: [width, height, 6],\n format: fmt,\n mipLevelCount: mipCount,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n dimension: \"2d\",\n });\n\n // Upload all mip levels for each face from the DDS (face-major layout).\n // Even though the skybox shader samples mip 0 explicitly, uploading all\n // mips avoids the need for GPU-side mipmap generation.\n let offset = 0;\n for (let face = 0; face < 6; face++) {\n for (let m = 0; m < mipCount; m++) {\n const s = Math.max(width >> m, 1);\n device.queue.writeTexture(\n { texture: tex, origin: { x: 0, y: 0, z: face }, mipLevel: m },\n raw.buffer,\n { offset: raw.byteOffset + offset, bytesPerRow: s * 8 },\n { width: s, height: s }\n );\n offset += s * s * 8;\n }\n }\n\n const cubeView = tex.createView({ dimension: \"cube\" });\n const sampler = getOrCreateSampler(engine, {\n magFilter: \"linear\",\n minFilter: \"linear\",\n mipmapFilter: \"linear\",\n addressModeU: \"clamp-to-edge\",\n addressModeV: \"clamp-to-edge\",\n addressModeW: \"clamp-to-edge\",\n maxAnisotropy: 4,\n });\n\n return { cubeView, sampler };\n}\n"],"names":[],"mappings":"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"}
|