@babylonjs/lite 1.0.0 → 1.0.1
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 → _mat4-storage-f64-BW9sTaVh.js} +2 -2
- package/{_mat4-storage-f64-CjDoht2w.js.map → _mat4-storage-f64-BW9sTaVh.js.map} +1 -1
- package/{alpha-test-fragment-B7DjSnF7.js → alpha-test-fragment-eUG971h3.js} +2 -2
- package/{alpha-test-fragment-B7DjSnF7.js.map → alpha-test-fragment-eUG971h3.js.map} +1 -1
- package/{background-dds-skybox-BEX309u3.js → background-dds-skybox-BwG0kYQP.js} +3 -3
- package/{background-dds-skybox-BEX309u3.js.map → background-dds-skybox-BwG0kYQP.js.map} +1 -1
- package/{background-ground-BU0HOcM4.js → background-ground-DiFpKJzF.js} +2 -2
- package/{background-ground-BU0HOcM4.js.map → background-ground-DiFpKJzF.js.map} +1 -1
- package/{background-hdr-skybox--RRRic_K.js → background-hdr-skybox-DIgJhvfj.js} +3 -3
- package/{background-hdr-skybox--RRRic_K.js.map → background-hdr-skybox-DIgJhvfj.js.map} +1 -1
- package/{background-solid-skybox-BrH2fXSu.js → background-solid-skybox--fqHdan_.js} +2 -2
- package/{background-solid-skybox-BrH2fXSu.js.map → background-solid-skybox--fqHdan_.js.map} +1 -1
- package/{billboard-renderable-BHWryAeC.js → billboard-renderable-HY2XCd52.js} +2 -2
- package/{billboard-renderable-BHWryAeC.js.map → billboard-renderable-HY2XCd52.js.map} +1 -1
- package/{clamp-block-DqbwnQGW.js → clamp-block-XHdUk2Va.js} +2 -2
- package/{clamp-block-DqbwnQGW.js.map → clamp-block-XHdUk2Va.js.map} +1 -1
- package/{clearcoat-fragment-D6FSCie1.js → clearcoat-fragment-CHYw8MPB.js} +2 -2
- package/{clearcoat-fragment-D6FSCie1.js.map → clearcoat-fragment-CHYw8MPB.js.map} +1 -1
- package/{create-skeleton-D_uplboC.js → create-skeleton-9tdiUjRP.js} +2 -2
- package/{create-skeleton-D_uplboC.js.map → create-skeleton-9tdiUjRP.js.map} +1 -1
- package/{cubemap-skybox-material-DQcMMdf-.js → cubemap-skybox-material-DqQ0dyz8.js} +2 -2
- package/{cubemap-skybox-material-DQcMMdf-.js.map → cubemap-skybox-material-DqQ0dyz8.js.map} +1 -1
- package/{curve-block-21rT0JjG.js → curve-block-S27sXrJQ.js} +2 -2
- package/{curve-block-21rT0JjG.js.map → curve-block-S27sXrJQ.js.map} +1 -1
- package/{emissive-fragment-C5FtBs3y.js → emissive-fragment-CZMQ0_bF.js} +2 -2
- package/{emissive-fragment-C5FtBs3y.js.map → emissive-fragment-CZMQ0_bF.js.map} +1 -1
- package/{esm-shadow-view-Gtd1LWRP.js → esm-shadow-view-CUwxbnMR.js} +2 -2
- package/{esm-shadow-view-Gtd1LWRP.js.map → esm-shadow-view-CUwxbnMR.js.map} +1 -1
- package/{esm-shadow-view-c5YV4Eg9.js → esm-shadow-view-Cl36rOrK.js} +2 -2
- package/{esm-shadow-view-c5YV4Eg9.js.map → esm-shadow-view-Cl36rOrK.js.map} +1 -1
- package/{esm-shadow-view-Cl3rPGof.js → esm-shadow-view-DKQ-FSoV.js} +2 -2
- package/{esm-shadow-view-Cl3rPGof.js.map → esm-shadow-view-DKQ-FSoV.js.map} +1 -1
- package/{gaussian-splatting-pipeline-sh-7J31V23x.js → gaussian-splatting-pipeline-sh-DDo7QQ8l.js} +2 -2
- package/{gaussian-splatting-pipeline-sh-7J31V23x.js.map → gaussian-splatting-pipeline-sh-DDo7QQ8l.js.map} +1 -1
- package/{geometry-texture-output-dXk4E9uu.js → geometry-texture-output-BmuAquio.js} +2 -2
- package/{geometry-texture-output-dXk4E9uu.js.map → geometry-texture-output-BmuAquio.js.map} +1 -1
- package/{geometry-view-BsFJpBJa.js → geometry-view-xWZmq799.js} +4 -4
- package/{geometry-view-BsFJpBJa.js.map → geometry-view-xWZmq799.js.map} +1 -1
- package/{gltf-animation-K_zZxj_d.js → gltf-animation-Bq7k_5HA.js} +2 -2
- package/{gltf-animation-K_zZxj_d.js.map → gltf-animation-Bq7k_5HA.js.map} +1 -1
- package/{gltf-ext-basisu-CDbPclzZ.js → gltf-ext-basisu-C5teqxzQ.js} +2 -202
- package/gltf-ext-basisu-C5teqxzQ.js.map +1 -0
- package/{gltf-ext-node-visibility-DXCJEYr6.js → gltf-ext-node-visibility-DnGTKkMf.js} +2 -2
- package/{gltf-ext-node-visibility-DXCJEYr6.js.map → gltf-ext-node-visibility-DnGTKkMf.js.map} +1 -1
- package/{gltf-ext-quantization-CvHI_0Vg.js → gltf-ext-quantization-DheC7FhB.js} +2 -2
- package/{gltf-ext-quantization-CvHI_0Vg.js.map → gltf-ext-quantization-DheC7FhB.js.map} +1 -1
- package/{gltf-ext-uv-transform-DgYazJBs.js → gltf-ext-uv-transform-DljdVllE.js} +2 -2
- package/{gltf-ext-uv-transform-DgYazJBs.js.map → gltf-ext-uv-transform-DljdVllE.js.map} +1 -1
- package/{gltf-feature-animation-pointer-D1RJRFBw.js → gltf-feature-animation-pointer-DVhymFLK.js} +3 -3
- package/{gltf-feature-animation-pointer-D1RJRFBw.js.map → gltf-feature-animation-pointer-DVhymFLK.js.map} +1 -1
- package/{gltf-feature-animations-Cmc1uoIu.js → gltf-feature-animations-hxC3y3bJ.js} +2 -2
- package/{gltf-feature-animations-Cmc1uoIu.js.map → gltf-feature-animations-hxC3y3bJ.js.map} +1 -1
- package/{gltf-feature-draco-CKKzT5E3.js → gltf-feature-draco-B7Q_cMUv.js} +2 -2
- package/{gltf-feature-draco-CKKzT5E3.js.map → gltf-feature-draco-B7Q_cMUv.js.map} +1 -1
- package/{gltf-feature-gpu-instancing-n87SO6Vh.js → gltf-feature-gpu-instancing-C7sRzWv7.js} +2 -2
- package/{gltf-feature-gpu-instancing-n87SO6Vh.js.map → gltf-feature-gpu-instancing-C7sRzWv7.js.map} +1 -1
- package/{gltf-feature-lights-punctual-Ckm3ciL8.js → gltf-feature-lights-punctual-DF7kya14.js} +5 -5
- package/{gltf-feature-lights-punctual-Ckm3ciL8.js.map → gltf-feature-lights-punctual-DF7kya14.js.map} +1 -1
- package/{gltf-feature-meshopt-DLC4SF1E.js → gltf-feature-meshopt-DRG9hEqT.js} +2 -2
- package/{gltf-feature-meshopt-DLC4SF1E.js.map → gltf-feature-meshopt-DRG9hEqT.js.map} +1 -1
- package/{gltf-feature-morph-Cjtu7hYa.js → gltf-feature-morph-DZydYgWp.js} +3 -3
- package/{gltf-feature-morph-Cjtu7hYa.js.map → gltf-feature-morph-DZydYgWp.js.map} +1 -1
- package/{gltf-feature-registry-C63Hjp9w.js → gltf-feature-registry-DeYdy3DV.js} +15 -15
- package/{gltf-feature-registry-C63Hjp9w.js.map → gltf-feature-registry-DeYdy3DV.js.map} +1 -1
- package/{gltf-feature-skeleton-DKbOGidp.js → gltf-feature-skeleton-B9och1W0.js} +3 -3
- package/{gltf-feature-skeleton-DKbOGidp.js.map → gltf-feature-skeleton-B9och1W0.js.map} +1 -1
- package/{gltf-feature-variants-Cmzu0O0e.js → gltf-feature-variants-CY_Qft7f.js} +2 -2
- package/{gltf-feature-variants-Cmzu0O0e.js.map → gltf-feature-variants-CY_Qft7f.js.map} +1 -1
- package/{gltf-glb-parser-Cj5MHS-v.js → gltf-glb-parser-CqOeXFOz.js} +2 -2
- package/{gltf-glb-parser-Cj5MHS-v.js.map → gltf-glb-parser-CqOeXFOz.js.map} +1 -1
- package/{gltf-interleave-gHf9_t0i.js → gltf-interleave-DWf27t-h.js} +2 -3
- package/{gltf-interleave-gHf9_t0i.js.map → gltf-interleave-DWf27t-h.js.map} +1 -1
- package/{gltf-pbr-builder-ext-edNcjwPf.js → gltf-pbr-builder-ext-DvFxuOqN.js} +2 -2
- package/{gltf-pbr-builder-ext-edNcjwPf.js.map → gltf-pbr-builder-ext-DvFxuOqN.js.map} +1 -1
- package/{gltf-variants-CPxNdtP4.js → gltf-variants-CUvzYGYX.js} +4 -4
- package/{gltf-variants-CPxNdtP4.js.map → gltf-variants-CUvzYGYX.js.map} +1 -1
- package/gpu-task-timer-Dgkff80h.js +236 -0
- package/gpu-task-timer-Dgkff80h.js.map +1 -0
- package/gpu-timer-CUpqT_hK.js +55 -0
- package/gpu-timer-CUpqT_hK.js.map +1 -0
- package/{gs-picking-pipeline-DYaW_Lg3.js → gs-picking-pipeline-55sM5LzV.js} +2 -2
- package/{gs-picking-pipeline-DYaW_Lg3.js.map → gs-picking-pipeline-55sM5LzV.js.map} +1 -1
- package/{havok-floating-origin-Dr-18Nds.js → havok-floating-origin-5xp32P-C.js} +2 -2
- package/{havok-floating-origin-Dr-18Nds.js.map → havok-floating-origin-5xp32P-C.js.map} +1 -1
- package/{index-CLElg2Bo.js → index-C-tEgwbZ.js} +2712 -865
- package/index-C-tEgwbZ.js.map +1 -0
- package/index.d.ts +486 -6
- package/index.js +473 -444
- package/{input-block-DqEedWF2.js → input-block-DbRYCnet.js} +2 -2
- package/{input-block-DqEedWF2.js.map → input-block-DbRYCnet.js.map} +1 -1
- package/{iridescence-fragment-BHU59-gQ.js → iridescence-fragment-S3Ko1jvC.js} +2 -2
- package/{iridescence-fragment-BHU59-gQ.js.map → iridescence-fragment-S3Ko1jvC.js.map} +1 -1
- package/{light-block-Bv37V8vl.js → light-block-CAqWkucp.js} +2 -2
- package/{light-block-Bv37V8vl.js.map → light-block-CAqWkucp.js.map} +1 -1
- package/{loop-block-qTg8vb99.js → loop-block-ch-biPFY.js} +2 -2
- package/{loop-block-qTg8vb99.js.map → loop-block-ch-biPFY.js.map} +1 -1
- package/{morph-fragment-BRCUr2wQ.js → morph-fragment-D9he3Ksk.js} +2 -2
- package/{morph-fragment-BRCUr2wQ.js.map → morph-fragment-D9he3Ksk.js.map} +1 -1
- package/{multilight-wgsl-DMeppAdZ.js → multilight-wgsl-74aXpcJG.js} +2 -2
- package/{multilight-wgsl-DMeppAdZ.js.map → multilight-wgsl-74aXpcJG.js.map} +1 -1
- package/{node-env-Bc559GmY.js → node-env-B2bjGcMS.js} +2 -2
- package/{node-env-Bc559GmY.js.map → node-env-B2bjGcMS.js.map} +1 -1
- package/{node-geometry-view-COmWsRXK.js → node-geometry-view-CSXlEAhG.js} +3 -3
- package/{node-geometry-view-COmWsRXK.js.map → node-geometry-view-CSXlEAhG.js.map} +1 -1
- package/{node-registry-extra-compat-dWrv7gpS.js → node-registry-extra-compat-BEQH_ksg.js} +2 -2
- package/{node-registry-extra-compat-dWrv7gpS.js.map → node-registry-extra-compat-BEQH_ksg.js.map} +1 -1
- package/{node-registry-extra-math-Bn854sX9.js → node-registry-extra-math-Bm32WBAa.js} +2 -2
- package/{node-registry-extra-math-Bn854sX9.js.map → node-registry-extra-math-Bm32WBAa.js.map} +1 -1
- package/{node-renderable-B5G8WcdH.js → node-renderable-BMHny4tC.js} +2 -2
- package/{node-renderable-B5G8WcdH.js.map → node-renderable-BMHny4tC.js.map} +1 -1
- package/{node-shadow-CVIUlNf0.js → node-shadow-BRiz7CT1.js} +2 -2
- package/{node-shadow-CVIUlNf0.js.map → node-shadow-BRiz7CT1.js.map} +1 -1
- package/{normal-map-fragment-CQSxhjCy.js → normal-map-fragment-sE3TjF4U.js} +2 -2
- package/{normal-map-fragment-CQSxhjCy.js.map → normal-map-fragment-sE3TjF4U.js.map} +1 -1
- package/package.json +3 -3
- package/{parse-camera-pBRT_6i5.js → parse-camera-CmZBS423.js} +2 -2
- package/{parse-camera-pBRT_6i5.js.map → parse-camera-CmZBS423.js.map} +1 -1
- package/{pbr-geometry-view-NiZY_juX.js → pbr-geometry-view-T3vMABM8.js} +3 -3
- package/{pbr-geometry-view-NiZY_juX.js.map → pbr-geometry-view-T3vMABM8.js.map} +1 -1
- package/{pbr-metallic-roughness-block-JBSi-tQN.js → pbr-metallic-roughness-block-DbozMlHU.js} +2 -2
- package/{pbr-metallic-roughness-block-JBSi-tQN.js.map → pbr-metallic-roughness-block-DbozMlHU.js.map} +1 -1
- package/{pbr-metallic-roughness-block-full-Ta9lR2cz.js → pbr-metallic-roughness-block-full-CHC8w-Uv.js} +2 -2
- package/{pbr-metallic-roughness-block-full-Ta9lR2cz.js.map → pbr-metallic-roughness-block-full-CHC8w-Uv.js.map} +1 -1
- package/{pbr-mr-helper-core-BVWNR08D.js → pbr-mr-helper-core-DGRgbRXl.js} +2 -2
- package/{pbr-mr-helper-core-BVWNR08D.js.map → pbr-mr-helper-core-DGRgbRXl.js.map} +1 -1
- package/{pbr-refraction-C9FvFmAp.js → pbr-refraction-CquDP9JO.js} +2 -2
- package/{pbr-refraction-C9FvFmAp.js.map → pbr-refraction-CquDP9JO.js.map} +1 -1
- package/{pbr-renderable-DzUF2QIk.js → pbr-renderable-CaHKHU0g.js} +22 -22
- package/{pbr-renderable-DzUF2QIk.js.map → pbr-renderable-CaHKHU0g.js.map} +1 -1
- package/{pbr-shadow-fragment-CnqnbGYS.js → pbr-shadow-fragment-DmnNe6yz.js} +2 -2
- package/{pbr-shadow-fragment-CnqnbGYS.js.map → pbr-shadow-fragment-DmnNe6yz.js.map} +1 -1
- package/{pbr-tracking-3tU1kqea.js → pbr-tracking-Bo7RTANK.js} +2 -2
- package/{pbr-tracking-3tU1kqea.js.map → pbr-tracking-Bo7RTANK.js.map} +1 -1
- package/{pbr-transmission-ext-BcLjRxfB.js → pbr-transmission-ext-CoGcJBGE.js} +2 -2
- package/{pbr-transmission-ext-BcLjRxfB.js.map → pbr-transmission-ext-CoGcJBGE.js.map} +1 -1
- package/{reflectance-fragment-Dbpgw3Jt.js → reflectance-fragment-CExe6qDY.js} +2 -2
- package/{reflectance-fragment-Dbpgw3Jt.js.map → reflectance-fragment-CExe6qDY.js.map} +1 -1
- package/{rgbd-decode-DoyUquy3.js → rgbd-decode-DkiiiIlt.js} +2 -2
- package/{rgbd-decode-DoyUquy3.js.map → rgbd-decode-DkiiiIlt.js.map} +1 -1
- package/{scene-material-swap-nNUH4nGn.js → scene-material-swap-4qM0tpBK.js} +1 -2
- package/scene-material-swap-4qM0tpBK.js.map +1 -0
- package/{screenshot-readback-D0Sj9qq3.js → screenshot-readback-avr_tYGZ.js} +2 -2
- package/{screenshot-readback-D0Sj9qq3.js.map → screenshot-readback-avr_tYGZ.js.map} +1 -1
- package/{shader-composer-BUD_pSX4.js → shader-composer-CZagsJDS.js} +2 -2
- package/{shader-composer-BUD_pSX4.js.map → shader-composer-CZagsJDS.js.map} +1 -1
- package/{shader-renderable-D7-RyVxa.js → shader-renderable-D5sbgzxt.js} +41 -9
- package/shader-renderable-D5sbgzxt.js.map +1 -0
- package/{shader-thin-instance-DuBotxDO.js → shader-thin-instance-CkQ8rrfH.js} +2 -2
- package/{shader-thin-instance-DuBotxDO.js.map → shader-thin-instance-CkQ8rrfH.js.map} +1 -1
- package/{sheen-fragment-1MkEMcbc.js → sheen-fragment-BEigjpTX.js} +2 -2
- package/{sheen-fragment-1MkEMcbc.js.map → sheen-fragment-BEigjpTX.js.map} +1 -1
- package/{singlelight-directional-wgsl-BsV8G456.js → singlelight-directional-wgsl-Ccsk-ys3.js} +2 -2
- package/{singlelight-directional-wgsl-BsV8G456.js.map → singlelight-directional-wgsl-Ccsk-ys3.js.map} +1 -1
- package/{singlelight-hemispheric-wgsl-Bo0jKlW5.js → singlelight-hemispheric-wgsl-DL-jpc97.js} +2 -2
- package/{singlelight-hemispheric-wgsl-Bo0jKlW5.js.map → singlelight-hemispheric-wgsl-DL-jpc97.js.map} +1 -1
- package/{singlelight-point-wgsl-DV39UP5Y.js → singlelight-point-wgsl-hYmiP6ys.js} +2 -2
- package/{singlelight-point-wgsl-DV39UP5Y.js.map → singlelight-point-wgsl-hYmiP6ys.js.map} +1 -1
- package/{singlelight-spot-wgsl-yg3od6vL.js → singlelight-spot-wgsl-DSjp1p1C.js} +2 -2
- package/{singlelight-spot-wgsl-yg3od6vL.js.map → singlelight-spot-wgsl-DSjp1p1C.js.map} +1 -1
- package/{skeleton-fragment-DdxYG6kv.js → skeleton-fragment-B__bUbPK.js} +2 -2
- package/{skeleton-fragment-DdxYG6kv.js.map → skeleton-fragment-B__bUbPK.js.map} +1 -1
- package/{skybox-renderable-CJD4XmX5.js → skybox-renderable-BH6uUkal.js} +2 -2
- package/{skybox-renderable-CJD4XmX5.js.map → skybox-renderable-BH6uUkal.js.map} +1 -1
- package/{splat-ply-compressed-DHjyiVmI.js → splat-ply-compressed-BGNK6dnh.js} +2 -2
- package/{splat-ply-compressed-DHjyiVmI.js.map → splat-ply-compressed-BGNK6dnh.js.map} +1 -1
- package/{standard-pipeline-XTbHL7MY.js → standard-pipeline-BvFynkwL.js} +3 -3
- package/{standard-pipeline-XTbHL7MY.js.map → standard-pipeline-BvFynkwL.js.map} +1 -1
- package/{standard-renderable-CREWLNHI.js → standard-renderable-1Q3zemys.js} +3 -3
- package/{standard-renderable-CREWLNHI.js.map → standard-renderable-1Q3zemys.js.map} +1 -1
- package/{std-ambient-fragment-Bjx3VFrr.js → std-ambient-fragment-__F1KTEu.js} +2 -2
- package/{std-ambient-fragment-Bjx3VFrr.js.map → std-ambient-fragment-__F1KTEu.js.map} +1 -1
- package/{std-cube-reflection-fragment-y9WWdXUt.js → std-cube-reflection-fragment-DidM0byH.js} +2 -2
- package/{std-cube-reflection-fragment-y9WWdXUt.js.map → std-cube-reflection-fragment-DidM0byH.js.map} +1 -1
- package/{std-emissive-fragment-C8Lnmojh.js → std-emissive-fragment-Bj62X4Np.js} +2 -2
- package/{std-emissive-fragment-C8Lnmojh.js.map → std-emissive-fragment-Bj62X4Np.js.map} +1 -1
- package/{std-lightmap-fragment-DFxGcoA5.js → std-lightmap-fragment-DXvfWvKc.js} +2 -2
- package/{std-lightmap-fragment-DFxGcoA5.js.map → std-lightmap-fragment-DXvfWvKc.js.map} +1 -1
- package/{std-opacity-fragment-EXzFWiSp.js → std-opacity-fragment-BzMMb1K_.js} +2 -2
- package/{std-opacity-fragment-EXzFWiSp.js.map → std-opacity-fragment-BzMMb1K_.js.map} +1 -1
- package/{std-reflection-fragment-BoJORqpG.js → std-reflection-fragment-DC9Kvu1C.js} +2 -2
- package/{std-reflection-fragment-BoJORqpG.js.map → std-reflection-fragment-DC9Kvu1C.js.map} +1 -1
- package/{std-shadow-fragment-Bq-Wc8UJ.js → std-shadow-fragment-BnMHeF1-.js} +2 -2
- package/{std-shadow-fragment-Bq-Wc8UJ.js.map → std-shadow-fragment-BnMHeF1-.js.map} +1 -1
- package/{std-specular-fragment-CM5R5j2g.js → std-specular-fragment-Bio681OG.js} +2 -2
- package/{std-specular-fragment-CM5R5j2g.js.map → std-specular-fragment-Bio681OG.js.map} +1 -1
- package/{std-tracking-Cif_wXeT.js → std-tracking-BTcrry2o.js} +2 -2
- package/{std-tracking-Cif_wXeT.js.map → std-tracking-BTcrry2o.js.map} +1 -1
- package/{subsurface-fragment-BEaAXYXz.js → subsurface-fragment-DpKib445.js} +2 -2
- package/{subsurface-fragment-BEaAXYXz.js.map → subsurface-fragment-DpKib445.js.map} +1 -1
- package/{thin-instance-cull-binding-DWKUt5ZN.js → thin-instance-cull-binding-DwZi7mlE.js} +3 -3
- package/{thin-instance-cull-binding-DWKUt5ZN.js.map → thin-instance-cull-binding-DwZi7mlE.js.map} +1 -1
- package/{thin-instance-gpu-BDdRcNAh.js → thin-instance-gpu-uY2NOv0J.js} +2 -2
- package/{thin-instance-gpu-BDdRcNAh.js.map → thin-instance-gpu-uY2NOv0J.js.map} +1 -1
- package/{tracking-primitives-CglRNTlX.js → tracking-primitives-Ck5bgCuo.js} +2 -2
- package/{tracking-primitives-CglRNTlX.js.map → tracking-primitives-Ck5bgCuo.js.map} +1 -1
- package/{unlit-fragment-kxfZWlnp.js → unlit-fragment-nc6hu3Mw.js} +2 -2
- package/{unlit-fragment-kxfZWlnp.js.map → unlit-fragment-nc6hu3Mw.js.map} +1 -1
- package/gltf-ext-basisu-CDbPclzZ.js.map +0 -1
- package/index-CLElg2Bo.js.map +0 -1
- package/scene-material-swap-nNUH4nGn.js.map +0 -1
- package/shader-renderable-D7-RyVxa.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-reflection-fragment-
|
|
1
|
+
{"version":3,"file":"std-reflection-fragment-DC9Kvu1C.js","sources":["../src/material/standard/fragments/std-reflection-fragment.ts"],"sourcesContent":["/** Standard Reflection Texture Fragment — spherical/planar environment reflection. */\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\n\nconst STAGE_FRAGMENT = 0x2;\n\nconst REFLECTION_HELPERS = `\nfn computeSphericalCoords(worldPos: vec3<f32>, worldNormal: vec3<f32>) -> vec2<f32> {\nlet viewDir = normalize((scene.view * vec4<f32>(worldPos, 1.0)).xyz);\nlet viewNormal = normalize((scene.view * vec4<f32>(worldNormal, 0.0)).xyz);\nvar r = reflect(viewDir, viewNormal);\nr.z = r.z - 1.0;\nlet m = 2.0 * length(r);\nreturn vec2<f32>(r.x / m + 0.5, r.y / m + 0.5);\n}\nfn computePlanarCoords(worldPos: vec3<f32>, worldNormal: vec3<f32>) -> vec2<f32> {\nlet viewDir = worldPos - scene.vEyePosition.xyz;\nlet coords = normalize(reflect(viewDir, worldNormal));\nreturn vec2<f32>(coords.x, 1.0 - coords.y);\n}\n`;\n\nexport function createStdReflectionFragment(): ShaderFragment {\n return {\n _id: \"std-reflection\",\n _bindings: [\n { _name: \"rT\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"rS\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT },\n ],\n _helperFunctions: REFLECTION_HELPERS,\n _fragmentSlots: {\n AD: `{\nvar reflCoords: vec2<f32>;\nif (mat.rCm < 1.5) { reflCoords = computeSphericalCoords(input.vp, normalW); }\nelse { reflCoords = computePlanarCoords(input.vp, normalW); }\nreflectionColor = textureSample(rT, rS, reflCoords).rgb * mat.rLvl;\n}`,\n },\n };\n}\n\nimport type { StandardMaterialProps } from \"../standard-material.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { StdExt } from \"../standard-flags.js\";\nimport { HAS_REFLECTION_TEXTURE } from \"../standard-flags.js\";\n\nexport const stdReflectionExt: StdExt = {\n _id: \"std-reflection\",\n _phase: \"mesh\",\n _feature: HAS_REFLECTION_TEXTURE,\n _frag: createStdReflectionFragment,\n _bind(mat, entries, b) {\n const tex = mat.reflectionTexture!;\n entries.push({ binding: b++, resource: tex.texture.createView() });\n entries.push({ binding: b++, resource: tex.sampler });\n return b;\n },\n _textures(mat: StandardMaterialProps, out: Texture2D[]): void {\n if (mat.reflectionTexture) {\n out.push(mat.reflectionTexture);\n }\n },\n};\n"],"names":[],"mappings":";AAGA,MAAM,iBAAiB;AAEvB,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBpB,SAAS,8BAA8C;AAC1D,SAAO;AAAA,IACH,KAAK;AAAA,IACL,WAAW;AAAA,MACP,EAAE,OAAO,MAAM,OAAO,EAAE,OAAO,WAAW,cAAc,kBAAA,GAAqB,aAAa,eAAA;AAAA,MAC1F,EAAE,OAAO,MAAM,OAAO,EAAE,OAAO,WAAW,cAAc,aAAa,aAAa,eAAA;AAAA,IAAe;AAAA,IAErG,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,MACZ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAMR;AAER;AAOO,MAAM,mBAA2B;AAAA,EACpC,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,MAAM,KAAK,SAAS,GAAG;AACnB,UAAM,MAAM,IAAI;AAChB,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,QAAQ,WAAA,GAAc;AACjE,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,SAAS;AACpD,WAAO;AAAA,EACX;AAAA,EACA,UAAU,KAA4B,KAAwB;AAC1D,QAAI,IAAI,mBAAmB;AACvB,UAAI,KAAK,IAAI,iBAAiB;AAAA,IAClC;AAAA,EACJ;AACJ;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as createShadowFragment } from "./shadow-fragment-core-DHN2G6FI.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ar as getCsmStdReceiverFactory } from "./index-C-tEgwbZ.js";
|
|
3
3
|
function createStdShadowFragment(shadowLights) {
|
|
4
4
|
const csmSlots = shadowLights.filter((sl) => sl.shadowType === "csm");
|
|
5
5
|
if (csmSlots.length > 0) {
|
|
@@ -10,4 +10,4 @@ function createStdShadowFragment(shadowLights) {
|
|
|
10
10
|
export {
|
|
11
11
|
createStdShadowFragment
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=std-shadow-fragment-
|
|
13
|
+
//# sourceMappingURL=std-shadow-fragment-BnMHeF1-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-shadow-fragment-
|
|
1
|
+
{"version":3,"file":"std-shadow-fragment-BnMHeF1-.js","sources":["../src/material/standard/fragments/std-shadow-fragment.ts"],"sourcesContent":["/**\n * Standard Shadow Fragment — Per-Light Shadow Support\n *\n * Thin wrapper around the shared shadow-fragment-core for Standard materials.\n * Only bundled when a scene uses shadow-receiving Standard meshes.\n */\n\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\nimport { createShadowFragment } from \"../../../shader/fragments/shadow-fragment-core.js\";\nimport { getCsmStdReceiverFactory } from \"../../../shadow/csm-receiver-registry.js\";\n\nexport type { ShadowLightSlot } from \"../../../shader/fragments/shadow-fragment-core.js\";\nimport type { ShadowLightSlot } from \"../../../shader/fragments/shadow-fragment-core.js\";\n\n/**\n * Create a per-light shadow fragment for Standard materials.\n * Each shadow-casting light gets its own varying, bindings, and sampling code.\n * The shadow factor for each light is stored in shadowFactors[lightIndex].\n *\n * If any slot is a cascaded-shadow (`\"csm\"`) light, the cascaded receiver factory\n * registered by the CSM generator is used (v1: a scene mixing CSM with ESM/PCF\n * receivers on the same mesh is unsupported). Otherwise the plain ESM/PCF core is used.\n */\nexport function createStdShadowFragment(shadowLights: ShadowLightSlot[]): ShaderFragment {\n const csmSlots = shadowLights.filter((sl) => sl.shadowType === \"csm\");\n if (csmSlots.length > 0) {\n return getCsmStdReceiverFactory()!(csmSlots.map((s) => ({ lightIndex: s.lightIndex })));\n }\n return createShadowFragment(\"std-shadow\", shadowLights);\n}\n"],"names":[],"mappings":";;AAuBO,SAAS,wBAAwB,cAAiD;AACrF,QAAM,WAAW,aAAa,OAAO,CAAC,OAAO,GAAG,eAAe,KAAK;AACpE,MAAI,SAAS,SAAS,GAAG;AACrB,WAAO,yBAAA,EAA4B,SAAS,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,WAAA,EAAa,CAAC;AAAA,EAC1F;AACA,SAAO,qBAAqB,cAAc,YAAY;AAC1D;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ah as HAS_SPECULAR_TEXTURE, ai as SPECULAR_USES_UV2 } from "./index-C-tEgwbZ.js";
|
|
2
2
|
const STAGE_FRAGMENT = 2;
|
|
3
3
|
function createStdSpecularFragment(usesUV2) {
|
|
4
4
|
const uv = usesUV2 ? "input.vv" : "input.vu";
|
|
@@ -34,4 +34,4 @@ export {
|
|
|
34
34
|
createStdSpecularFragment,
|
|
35
35
|
stdSpecularExt
|
|
36
36
|
};
|
|
37
|
-
//# sourceMappingURL=std-specular-fragment-
|
|
37
|
+
//# sourceMappingURL=std-specular-fragment-Bio681OG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-specular-fragment-
|
|
1
|
+
{"version":3,"file":"std-specular-fragment-Bio681OG.js","sources":["../src/material/standard/fragments/std-specular-fragment.ts"],"sourcesContent":["/** Standard Specular Texture Fragment — replaces specular color with texture sample. */\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\nimport type { StandardMaterialProps } from \"../standard-material.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { StdExt } from \"../standard-flags.js\";\nimport { HAS_SPECULAR_TEXTURE, SPECULAR_USES_UV2 } from \"../standard-flags.js\";\n\nconst STAGE_FRAGMENT = 0x2;\n\nexport function createStdSpecularFragment(usesUV2: boolean): ShaderFragment {\n const uv = usesUV2 ? \"input.vv\" : \"input.vu\";\n return {\n _id: \"std-specular\",\n _bindings: [\n { _name: \"sT\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"sS\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT },\n ],\n _fragmentSlots: {\n AT: `specularColor = textureSample(sT, sS, ${uv}).rgb;`,\n },\n };\n}\n\nexport const stdSpecularExt: StdExt = {\n _id: \"std-specular\",\n _phase: \"mesh\",\n _feature: HAS_SPECULAR_TEXTURE,\n _frag: (features) => createStdSpecularFragment((features & SPECULAR_USES_UV2) !== 0),\n _bind(mat, entries, b) {\n const tex = mat.specularTexture!;\n entries.push({ binding: b++, resource: tex.texture.createView() });\n entries.push({ binding: b++, resource: tex.sampler });\n return b;\n },\n _textures(mat: StandardMaterialProps, out: Texture2D[]): void {\n if (mat.specularTexture) {\n out.push(mat.specularTexture);\n }\n },\n};\n"],"names":[],"mappings":";AAOA,MAAM,iBAAiB;AAEhB,SAAS,0BAA0B,SAAkC;AACxE,QAAM,KAAK,UAAU,aAAa;AAClC,SAAO;AAAA,IACH,KAAK;AAAA,IACL,WAAW;AAAA,MACP,EAAE,OAAO,MAAM,OAAO,EAAE,OAAO,WAAW,cAAc,kBAAA,GAAqB,aAAa,eAAA;AAAA,MAC1F,EAAE,OAAO,MAAM,OAAO,EAAE,OAAO,WAAW,cAAc,aAAa,aAAa,eAAA;AAAA,IAAe;AAAA,IAErG,gBAAgB;AAAA,MACZ,IAAI,yCAAyC,EAAE;AAAA,IAAA;AAAA,EACnD;AAER;AAEO,MAAM,iBAAyB;AAAA,EAClC,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO,CAAC,aAAa,2BAA2B,WAAW,uBAAuB,CAAC;AAAA,EACnF,MAAM,KAAK,SAAS,GAAG;AACnB,UAAM,MAAM,IAAI;AAChB,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,QAAQ,WAAA,GAAc;AACjE,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,SAAS;AACpD,WAAO;AAAA,EACX;AAAA,EACA,UAAU,KAA4B,KAAwB;AAC1D,QAAI,IAAI,iBAAiB;AACrB,UAAI,KAAK,IAAI,eAAe;AAAA,IAChC;AAAA,EACJ;AACJ;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as trackScalar, o as observableColor3, a as observableVec2 } from "./tracking-primitives-
|
|
1
|
+
import { t as trackScalar, o as observableColor3, a as observableVec2 } from "./tracking-primitives-Ck5bgCuo.js";
|
|
2
2
|
function installStdTracking(mat) {
|
|
3
3
|
for (const key of ["alpha", "specularPower", "bumpLevel", "ambientTexLevel", "lightmapLevel", "opacityLevel", "alphaCutOff", "reflectionLevel"]) {
|
|
4
4
|
trackScalar(mat, key);
|
|
@@ -12,4 +12,4 @@ function installStdTracking(mat) {
|
|
|
12
12
|
export {
|
|
13
13
|
installStdTracking
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=std-tracking-
|
|
15
|
+
//# sourceMappingURL=std-tracking-BTcrry2o.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-tracking-
|
|
1
|
+
{"version":3,"file":"std-tracking-BTcrry2o.js","sources":["../src/material/tracking/std-tracking.ts"],"sourcesContent":["/** Standard material auto-dirty tracking. Dynamically imported by enableMaterialTracking(). */\n\nimport type { StandardMaterialProps } from \"../standard/standard-material.js\";\nimport { trackScalar, observableColor3, observableVec2 } from \"./tracking-primitives.js\";\n\nexport function installStdTracking(mat: StandardMaterialProps): void {\n for (const key of [\"alpha\", \"specularPower\", \"bumpLevel\", \"ambientTexLevel\", \"lightmapLevel\", \"opacityLevel\", \"alphaCutOff\", \"reflectionLevel\"]) {\n trackScalar(mat, key);\n }\n mat.diffuseColor = observableColor3(mat.diffuseColor[0], mat.diffuseColor[1], mat.diffuseColor[2], mat as any);\n mat.specularColor = observableColor3(mat.specularColor[0], mat.specularColor[1], mat.specularColor[2], mat as any);\n mat.emissiveColor = observableColor3(mat.emissiveColor[0], mat.emissiveColor[1], mat.emissiveColor[2], mat as any);\n mat.ambientColor = observableColor3(mat.ambientColor[0], mat.ambientColor[1], mat.ambientColor[2], mat as any);\n mat.uvScale = observableVec2(mat.uvScale[0], mat.uvScale[1], mat as any);\n}\n"],"names":[],"mappings":";AAKO,SAAS,mBAAmB,KAAkC;AACjE,aAAW,OAAO,CAAC,SAAS,iBAAiB,aAAa,mBAAmB,iBAAiB,gBAAgB,eAAe,iBAAiB,GAAG;AAC7I,gBAAY,KAAK,GAAG;AAAA,EACxB;AACA,MAAI,eAAe,iBAAiB,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,GAAU;AAC7G,MAAI,gBAAgB,iBAAiB,IAAI,cAAc,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,GAAU;AACjH,MAAI,gBAAgB,iBAAiB,IAAI,cAAc,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,GAAU;AACjH,MAAI,eAAe,iBAAiB,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,GAAU;AAC7G,MAAI,UAAU,eAAe,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,GAAU;AAC3E;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a$ as PBR_HAS_THICKNESS_MAP, b0 as PBR_HAS_SUBSURFACE, b1 as PBR2_HAS_THICKNESS_GLTF_CHANNEL } from "./index-C-tEgwbZ.js";
|
|
2
2
|
const SS_HELPERS = `
|
|
3
3
|
fn transmittanceBRDF_Burley(tintColor: vec3<f32>, diffusionDistance: vec3<f32>, thickness: f32) -> vec3<f32> {
|
|
4
4
|
let S = 1.0 / max(vec3<f32>(0.000001), diffusionDistance);
|
|
@@ -155,4 +155,4 @@ export {
|
|
|
155
155
|
pbrExt,
|
|
156
156
|
writeSubsurfaceUBO
|
|
157
157
|
};
|
|
158
|
-
//# sourceMappingURL=subsurface-fragment-
|
|
158
|
+
//# sourceMappingURL=subsurface-fragment-DpKib445.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subsurface-fragment-BEaAXYXz.js","sources":["../src/material/pbr/fragments/subsurface-fragment.ts"],"sourcesContent":["/**\n * Subsurface Fragment\n *\n * Adds translucency — light passing through thin surfaces.\n * Only bundled when a scene uses PbrMaterialProps.subsurface.\n *\n * Math follows BJS PBRSubSurfaceConfiguration:\n * - Burley transmittance BRDF: exp-based approximation\n * - Thickness from texture (.g channel, BJS glTF-style default)\n * - Direct: wrap-around diffuse scaled by transmittance\n * - IBL: irradiance reduced by (1 - intensity), transmittance-weighted contribution added\n */\n\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SubSurfaceProps } from \"../pbr-material.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_SUBSURFACE, PBR_HAS_THICKNESS_MAP, PBR2_HAS_THICKNESS_GLTF_CHANNEL } from \"../pbr-flag-bits.js\";\n\nconst SS_HELPERS = `\nfn transmittanceBRDF_Burley(tintColor: vec3<f32>, diffusionDistance: vec3<f32>, thickness: f32) -> vec3<f32> {\nlet S = 1.0 / max(vec3<f32>(0.000001), diffusionDistance);\nlet temp = exp((-0.333333333 * thickness) * S);\nreturn tintColor * 0.25 * (temp * temp * temp + 3.0 * temp);\n}\nfn computeWrappedDiffuseNdotL(NdotL: f32, w: f32) -> f32 {\nlet t = 1.0 + w;\nlet invt2 = 1.0 / (t * t);\nreturn saturate((NdotL + w) * invt2);\n}\n`;\n\n// SV: declare subsurface scope variables\nconst SS_SCOPE_VARS = `var translucencyDirect = vec3<f32>(0.0);\nvar ssTransmittance = vec3<f32>(0.0);\nvar ssIntensity = 0.0;`;\n\n// AT: sample thickness + compute transmittance.\n// Channel: R by default (matches existing non-glTF path); G when the glTF\n// KHR_materials_volume flag is on (spec mandates G channel).\nfunction makeThicknessBlock(hasThicknessMap: boolean, useGltfChannel: boolean): string {\n const chan = useGltfChannel ? \"g\" : \"r\";\n const texSample = hasThicknessMap ? `let thicknessSample = textureSample(thicknessTexture_, thicknessSampler_, input.uv).${chan};` : `let thicknessSample = 1.0;`;\n return `${texSample}\nlet ssThickness = max(material.subsurfaceParams.y + thicknessSample * material.subsurfaceParams.z, 0.000001);\nlet ssTranslucencyColor = material.subsurfaceParams3.rgb;\nlet ssDiffDist = material.subsurfaceParams2.rgb;\nssIntensity = material.subsurfaceParams.x;\nssTransmittance = transmittanceBRDF_Burley(ssTranslucencyColor, ssDiffDist, ssThickness) * ssIntensity;`;\n}\n\n// AD: direct-light translucency lobe (back-facing only, wrap 0.02, 1/PI diffuse BRDF).\n// BJS also scales the front-facing direct diffuse by (1 - ssIntensity); we cannot easily\n// modify `directDiffuse` at compute time, so compensate via `color -= directDiffuse * ssIntensity`\n// in the AI/NI slot below.\nconst SS_DIRECT = `{\nlet NdotLU = dot(N, L);\nif (NdotLU < 0.0) {\nlet wrapNdotL = computeWrappedDiffuseNdotL(abs(NdotLU), 0.02);\ntranslucencyDirect += (1.0 / PI) * wrapNdotL * ssTransmittance * lightAtten * lightColor * material.directIntensity;\n}\n}`;\n\n// AI: subsurface IBL modification (runs after IBL sets `color`).\n// BJS: finalIrradiance *= (1 - ssI); finalIrradiance += refractionIrradiance;\n// where refractionIrradiance = environmentIrradiance(-N) * transmittance (no albedo by default).\n// AO/occlusion applies to the full finalIrradiance in BJS.\n// Also: scale direct diffuse by (1-ssI) and add translucencyDirect lobe.\nconst SS_IBL_MOD = `{\nlet N_back = -N_env;\nlet envIrrBack = (scene.vSphericalL00.rgb\n + scene.vSphericalL1_1.rgb * N_back.y + scene.vSphericalL10.rgb * N_back.z + scene.vSphericalL11.rgb * N_back.x\n + scene.vSphericalL2_2.rgb * (N_back.y * N_back.x) + scene.vSphericalL2_1.rgb * (N_back.y * N_back.z)\n + scene.vSphericalL20.rgb * (3.0 * N_back.z * N_back.z - 1.0) + scene.vSphericalL21.rgb * (N_back.z * N_back.x)\n + scene.vSphericalL22.rgb * (N_back.x * N_back.x - N_back.y * N_back.y)) * material.environmentIntensity;\nlet refractionIrradiance = envIrrBack * ssTransmittance;\ncolor -= finalIrradiance * ssIntensity;\ncolor += refractionIrradiance * occlusion;\ncolor -= directDiffuse * ssIntensity;\ncolor += translucencyDirect * occlusion;\n}`;\n\n// NI: no-IBL path — just scale direct diffuse and add translucency lobe.\nconst SS_NO_IBL_MOD = `color -= directDiffuse * ssIntensity;\ncolor += translucencyDirect;`;\n\nconst STAGE_FRAGMENT = 0x2;\n\n/**\n * Create a subsurface translucency fragment.\n * @param hasThicknessMap - Whether the material has a thickness texture.\n * @param hasIbl - Whether the scene has IBL.\n * @param useGltfThicknessChannel - Sample the thickness texture's G channel\n * (KHR_materials_volume) instead of R (BJS default).\n */\nexport function createSubsurfaceFragment(hasThicknessMap: boolean, hasIbl: boolean, useGltfThicknessChannel: boolean): ShaderFragment {\n const bindings = hasThicknessMap\n ? [\n { _name: \"thicknessTexture_\", _type: { _kind: \"texture\" as const, _textureType: \"texture_2d<f32>\" as const }, _visibility: STAGE_FRAGMENT },\n { _name: \"thicknessSampler_\", _type: { _kind: \"sampler\" as const, _samplerType: \"sampler\" as const }, _visibility: STAGE_FRAGMENT },\n ]\n : [];\n\n const slots: Partial<Record<string, string>> = {\n SV: SS_SCOPE_VARS,\n AT: makeThicknessBlock(hasThicknessMap, useGltfThicknessChannel),\n AD: SS_DIRECT,\n };\n if (hasIbl) {\n slots.AI = SS_IBL_MOD;\n } else {\n slots.NI = SS_NO_IBL_MOD;\n }\n\n const deps: string[] = [];\n if (hasIbl) {\n deps.push(\"ibl\");\n }\n\n return {\n _id: \"subsurface\",\n _dependencies: deps.length > 0 ? deps : undefined,\n _bindings: bindings.length > 0 ? bindings : undefined,\n _uboFields: [\n { _name: \"subsurfaceParams\", _type: \"vec4<f32>\" as const },\n { _name: \"subsurfaceParams2\", _type: \"vec4<f32>\" as const },\n { _name: \"subsurfaceParams3\", _type: \"vec4<f32>\" as const },\n ],\n _helperFunctions: SS_HELPERS,\n _fragmentSlots: slots,\n };\n}\n\n/** Write subsurface UBO data. Called from pbr-renderable.ts only when subsurface is active. */\nexport function writeSubsurfaceUBO(data: Float32Array, ss: SubSurfaceProps, offsets: ReadonlyMap<string, number>): void {\n const trans = ss.translucency!;\n const thick = ss.thickness;\n\n const off = offsets.get(\"subsurfaceParams\")! / 4;\n data[off] = trans.intensity ?? 1.0;\n const minThick = thick?.min ?? 0;\n const maxThick = thick?.max ?? 1.0;\n data[off + 1] = minThick;\n data[off + 2] = maxThick - minThick;\n\n const off2 = offsets.get(\"subsurfaceParams2\")! / 4;\n const dd = trans.diffusionDistance ?? [1, 1, 1];\n data[off2] = dd[0]!;\n data[off2 + 1] = dd[1]!;\n data[off2 + 2] = dd[2]!;\n\n const off3 = offsets.get(\"subsurfaceParams3\")! / 4;\n const tc = trans.color ?? [1, 1, 1];\n data[off3] = tc[0]!;\n data[off3 + 1] = tc[1]!;\n data[off3 + 2] = tc[2]!;\n}\n\nexport const pbrExt: PbrExt = {\n id: \"subsurface\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as PbrMaterialProps;\n if (!m.subsurface?.translucency) {\n return { f: 0, f2: 0 };\n }\n let f = PBR_HAS_SUBSURFACE;\n let f2 = 0;\n if (m.subsurface.thickness?.texture) {\n f |= PBR_HAS_THICKNESS_MAP;\n }\n if (m.subsurface.thickness?.useGlTFChannel) {\n f2 |= PBR2_HAS_THICKNESS_GLTF_CHANNEL;\n }\n return { f, f2 };\n },\n frag(ctx) {\n if (!(ctx._features & PBR_HAS_SUBSURFACE)) {\n return null;\n }\n return createSubsurfaceFragment((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0, ctx._hasIbl, (ctx._features2 & PBR2_HAS_THICKNESS_GLTF_CHANNEL) !== 0);\n },\n writeUbo(data, mat, offsets) {\n const m = mat as PbrMaterialProps;\n if (m.subsurface?.translucency && offsets.has(\"subsurfaceParams\")) {\n writeSubsurfaceUBO(data, m.subsurface as SubSurfaceProps, offsets);\n }\n },\n bind(ctx, entries, b) {\n if ((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0) {\n const tex = (ctx._material as PbrMaterialProps).subsurface?.thickness?.texture as Texture2D | undefined;\n if (tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, out) {\n const t = (mat as PbrMaterialProps).subsurface?.thickness?.texture;\n if (t) {\n out.push(t);\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subsurface-fragment-DpKib445.js","sources":["../src/material/pbr/fragments/subsurface-fragment.ts"],"sourcesContent":["/**\n * Subsurface Fragment\n *\n * Adds translucency — light passing through thin surfaces.\n * Only bundled when a scene uses PbrMaterialProps.subsurface.\n *\n * Math follows BJS PBRSubSurfaceConfiguration:\n * - Burley transmittance BRDF: exp-based approximation\n * - Thickness from texture (.g channel, BJS glTF-style default)\n * - Direct: wrap-around diffuse scaled by transmittance\n * - IBL: irradiance reduced by (1 - intensity), transmittance-weighted contribution added\n */\n\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SubSurfaceProps } from \"../pbr-material.js\";\nimport type { Texture2D } from \"../../../texture/texture-2d.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_SUBSURFACE, PBR_HAS_THICKNESS_MAP, PBR2_HAS_THICKNESS_GLTF_CHANNEL } from \"../pbr-flag-bits.js\";\n\nconst SS_HELPERS = `\nfn transmittanceBRDF_Burley(tintColor: vec3<f32>, diffusionDistance: vec3<f32>, thickness: f32) -> vec3<f32> {\nlet S = 1.0 / max(vec3<f32>(0.000001), diffusionDistance);\nlet temp = exp((-0.333333333 * thickness) * S);\nreturn tintColor * 0.25 * (temp * temp * temp + 3.0 * temp);\n}\nfn computeWrappedDiffuseNdotL(NdotL: f32, w: f32) -> f32 {\nlet t = 1.0 + w;\nlet invt2 = 1.0 / (t * t);\nreturn saturate((NdotL + w) * invt2);\n}\n`;\n\n// SV: declare subsurface scope variables\nconst SS_SCOPE_VARS = `var translucencyDirect = vec3<f32>(0.0);\nvar ssTransmittance = vec3<f32>(0.0);\nvar ssIntensity = 0.0;`;\n\n// AT: sample thickness + compute transmittance.\n// Channel: R by default (matches existing non-glTF path); G when the glTF\n// KHR_materials_volume flag is on (spec mandates G channel).\nfunction makeThicknessBlock(hasThicknessMap: boolean, useGltfChannel: boolean): string {\n const chan = useGltfChannel ? \"g\" : \"r\";\n const texSample = hasThicknessMap ? `let thicknessSample = textureSample(thicknessTexture_, thicknessSampler_, input.uv).${chan};` : `let thicknessSample = 1.0;`;\n return `${texSample}\nlet ssThickness = max(material.subsurfaceParams.y + thicknessSample * material.subsurfaceParams.z, 0.000001);\nlet ssTranslucencyColor = material.subsurfaceParams3.rgb;\nlet ssDiffDist = material.subsurfaceParams2.rgb;\nssIntensity = material.subsurfaceParams.x;\nssTransmittance = transmittanceBRDF_Burley(ssTranslucencyColor, ssDiffDist, ssThickness) * ssIntensity;`;\n}\n\n// AD: direct-light translucency lobe (back-facing only, wrap 0.02, 1/PI diffuse BRDF).\n// BJS also scales the front-facing direct diffuse by (1 - ssIntensity); we cannot easily\n// modify `directDiffuse` at compute time, so compensate via `color -= directDiffuse * ssIntensity`\n// in the AI/NI slot below.\nconst SS_DIRECT = `{\nlet NdotLU = dot(N, L);\nif (NdotLU < 0.0) {\nlet wrapNdotL = computeWrappedDiffuseNdotL(abs(NdotLU), 0.02);\ntranslucencyDirect += (1.0 / PI) * wrapNdotL * ssTransmittance * lightAtten * lightColor * material.directIntensity;\n}\n}`;\n\n// AI: subsurface IBL modification (runs after IBL sets `color`).\n// BJS: finalIrradiance *= (1 - ssI); finalIrradiance += refractionIrradiance;\n// where refractionIrradiance = environmentIrradiance(-N) * transmittance (no albedo by default).\n// AO/occlusion applies to the full finalIrradiance in BJS.\n// Also: scale direct diffuse by (1-ssI) and add translucencyDirect lobe.\nconst SS_IBL_MOD = `{\nlet N_back = -N_env;\nlet envIrrBack = (scene.vSphericalL00.rgb\n + scene.vSphericalL1_1.rgb * N_back.y + scene.vSphericalL10.rgb * N_back.z + scene.vSphericalL11.rgb * N_back.x\n + scene.vSphericalL2_2.rgb * (N_back.y * N_back.x) + scene.vSphericalL2_1.rgb * (N_back.y * N_back.z)\n + scene.vSphericalL20.rgb * (3.0 * N_back.z * N_back.z - 1.0) + scene.vSphericalL21.rgb * (N_back.z * N_back.x)\n + scene.vSphericalL22.rgb * (N_back.x * N_back.x - N_back.y * N_back.y)) * material.environmentIntensity;\nlet refractionIrradiance = envIrrBack * ssTransmittance;\ncolor -= finalIrradiance * ssIntensity;\ncolor += refractionIrradiance * occlusion;\ncolor -= directDiffuse * ssIntensity;\ncolor += translucencyDirect * occlusion;\n}`;\n\n// NI: no-IBL path — just scale direct diffuse and add translucency lobe.\nconst SS_NO_IBL_MOD = `color -= directDiffuse * ssIntensity;\ncolor += translucencyDirect;`;\n\nconst STAGE_FRAGMENT = 0x2;\n\n/**\n * Create a subsurface translucency fragment.\n * @param hasThicknessMap - Whether the material has a thickness texture.\n * @param hasIbl - Whether the scene has IBL.\n * @param useGltfThicknessChannel - Sample the thickness texture's G channel\n * (KHR_materials_volume) instead of R (BJS default).\n */\nexport function createSubsurfaceFragment(hasThicknessMap: boolean, hasIbl: boolean, useGltfThicknessChannel: boolean): ShaderFragment {\n const bindings = hasThicknessMap\n ? [\n { _name: \"thicknessTexture_\", _type: { _kind: \"texture\" as const, _textureType: \"texture_2d<f32>\" as const }, _visibility: STAGE_FRAGMENT },\n { _name: \"thicknessSampler_\", _type: { _kind: \"sampler\" as const, _samplerType: \"sampler\" as const }, _visibility: STAGE_FRAGMENT },\n ]\n : [];\n\n const slots: Partial<Record<string, string>> = {\n SV: SS_SCOPE_VARS,\n AT: makeThicknessBlock(hasThicknessMap, useGltfThicknessChannel),\n AD: SS_DIRECT,\n };\n if (hasIbl) {\n slots.AI = SS_IBL_MOD;\n } else {\n slots.NI = SS_NO_IBL_MOD;\n }\n\n const deps: string[] = [];\n if (hasIbl) {\n deps.push(\"ibl\");\n }\n\n return {\n _id: \"subsurface\",\n _dependencies: deps.length > 0 ? deps : undefined,\n _bindings: bindings.length > 0 ? bindings : undefined,\n _uboFields: [\n { _name: \"subsurfaceParams\", _type: \"vec4<f32>\" as const },\n { _name: \"subsurfaceParams2\", _type: \"vec4<f32>\" as const },\n { _name: \"subsurfaceParams3\", _type: \"vec4<f32>\" as const },\n ],\n _helperFunctions: SS_HELPERS,\n _fragmentSlots: slots,\n };\n}\n\n/** Write subsurface UBO data. Called from pbr-renderable.ts only when subsurface is active. */\nexport function writeSubsurfaceUBO(data: Float32Array, ss: SubSurfaceProps, offsets: ReadonlyMap<string, number>): void {\n const trans = ss.translucency!;\n const thick = ss.thickness;\n\n const off = offsets.get(\"subsurfaceParams\")! / 4;\n data[off] = trans.intensity ?? 1.0;\n const minThick = thick?.min ?? 0;\n const maxThick = thick?.max ?? 1.0;\n data[off + 1] = minThick;\n data[off + 2] = maxThick - minThick;\n\n const off2 = offsets.get(\"subsurfaceParams2\")! / 4;\n const dd = trans.diffusionDistance ?? [1, 1, 1];\n data[off2] = dd[0]!;\n data[off2 + 1] = dd[1]!;\n data[off2 + 2] = dd[2]!;\n\n const off3 = offsets.get(\"subsurfaceParams3\")! / 4;\n const tc = trans.color ?? [1, 1, 1];\n data[off3] = tc[0]!;\n data[off3 + 1] = tc[1]!;\n data[off3 + 2] = tc[2]!;\n}\n\nexport const pbrExt: PbrExt = {\n id: \"subsurface\",\n phase: \"fragment\",\n detect(mat) {\n const m = mat as PbrMaterialProps;\n if (!m.subsurface?.translucency) {\n return { f: 0, f2: 0 };\n }\n let f = PBR_HAS_SUBSURFACE;\n let f2 = 0;\n if (m.subsurface.thickness?.texture) {\n f |= PBR_HAS_THICKNESS_MAP;\n }\n if (m.subsurface.thickness?.useGlTFChannel) {\n f2 |= PBR2_HAS_THICKNESS_GLTF_CHANNEL;\n }\n return { f, f2 };\n },\n frag(ctx) {\n if (!(ctx._features & PBR_HAS_SUBSURFACE)) {\n return null;\n }\n return createSubsurfaceFragment((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0, ctx._hasIbl, (ctx._features2 & PBR2_HAS_THICKNESS_GLTF_CHANNEL) !== 0);\n },\n writeUbo(data, mat, offsets) {\n const m = mat as PbrMaterialProps;\n if (m.subsurface?.translucency && offsets.has(\"subsurfaceParams\")) {\n writeSubsurfaceUBO(data, m.subsurface as SubSurfaceProps, offsets);\n }\n },\n bind(ctx, entries, b) {\n if ((ctx._features & PBR_HAS_THICKNESS_MAP) !== 0) {\n const tex = (ctx._material as PbrMaterialProps).subsurface?.thickness?.texture as Texture2D | undefined;\n if (tex) {\n entries.push({ binding: b++, resource: tex.view });\n entries.push({ binding: b++, resource: tex.sampler });\n }\n }\n return b;\n },\n textures(mat, out) {\n const t = (mat as PbrMaterialProps).subsurface?.thickness?.texture;\n if (t) {\n out.push(t);\n }\n },\n};\n"],"names":[],"mappings":";AAmBA,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcnB,MAAM,gBAAgB;AAAA;AAAA;AAOtB,SAAS,mBAAmB,iBAA0B,gBAAiC;AACnF,QAAM,OAAO,iBAAiB,MAAM;AACpC,QAAM,YAAY,kBAAkB,uFAAuF,IAAI,MAAM;AACrI,SAAO,GAAG,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAMvB;AAMA,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAalB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAenB,MAAM,gBAAgB;AAAA;AAGtB,MAAM,iBAAiB;AAShB,SAAS,yBAAyB,iBAA0B,QAAiB,yBAAkD;AAClI,QAAM,WAAW,kBACX;AAAA,IACI,EAAE,OAAO,qBAAqB,OAAO,EAAE,OAAO,WAAoB,cAAc,kBAAA,GAA8B,aAAa,eAAA;AAAA,IAC3H,EAAE,OAAO,qBAAqB,OAAO,EAAE,OAAO,WAAoB,cAAc,aAAsB,aAAa,eAAA;AAAA,EAAe,IAEtI,CAAA;AAEN,QAAM,QAAyC;AAAA,IAC3C,IAAI;AAAA,IACJ,IAAI,mBAAmB,iBAAiB,uBAAuB;AAAA,IAC/D,IAAI;AAAA,EAAA;AAER,MAAI,QAAQ;AACR,UAAM,KAAK;AAAA,EACf,OAAO;AACH,UAAM,KAAK;AAAA,EACf;AAEA,QAAM,OAAiB,CAAA;AACvB,MAAI,QAAQ;AACR,SAAK,KAAK,KAAK;AAAA,EACnB;AAEA,SAAO;AAAA,IACH,KAAK;AAAA,IACL,eAAe,KAAK,SAAS,IAAI,OAAO;AAAA,IACxC,WAAW,SAAS,SAAS,IAAI,WAAW;AAAA,IAC5C,YAAY;AAAA,MACR,EAAE,OAAO,oBAAoB,OAAO,YAAA;AAAA,MACpC,EAAE,OAAO,qBAAqB,OAAO,YAAA;AAAA,MACrC,EAAE,OAAO,qBAAqB,OAAO,YAAA;AAAA,IAAqB;AAAA,IAE9D,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,EAAA;AAExB;AAGO,SAAS,mBAAmB,MAAoB,IAAqB,SAA4C;AACpH,QAAM,QAAQ,GAAG;AACjB,QAAM,QAAQ,GAAG;AAEjB,QAAM,MAAM,QAAQ,IAAI,kBAAkB,IAAK;AAC/C,OAAK,GAAG,IAAI,MAAM,aAAa;AAC/B,QAAM,YAAW,+BAAO,QAAO;AAC/B,QAAM,YAAW,+BAAO,QAAO;AAC/B,OAAK,MAAM,CAAC,IAAI;AAChB,OAAK,MAAM,CAAC,IAAI,WAAW;AAE3B,QAAM,OAAO,QAAQ,IAAI,mBAAmB,IAAK;AACjD,QAAM,KAAK,MAAM,qBAAqB,CAAC,GAAG,GAAG,CAAC;AAC9C,OAAK,IAAI,IAAI,GAAG,CAAC;AACjB,OAAK,OAAO,CAAC,IAAI,GAAG,CAAC;AACrB,OAAK,OAAO,CAAC,IAAI,GAAG,CAAC;AAErB,QAAM,OAAO,QAAQ,IAAI,mBAAmB,IAAK;AACjD,QAAM,KAAK,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AAClC,OAAK,IAAI,IAAI,GAAG,CAAC;AACjB,OAAK,OAAO,CAAC,IAAI,GAAG,CAAC;AACrB,OAAK,OAAO,CAAC,IAAI,GAAG,CAAC;AACzB;AAEO,MAAM,SAAiB;AAAA,EAC1B,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,OAAO,KAAK;;AACR,UAAM,IAAI;AACV,QAAI,GAAC,OAAE,eAAF,mBAAc,eAAc;AAC7B,aAAO,EAAE,GAAG,GAAG,IAAI,EAAA;AAAA,IACvB;AACA,QAAI,IAAI;AACR,QAAI,KAAK;AACT,SAAI,OAAE,WAAW,cAAb,mBAAwB,SAAS;AACjC,WAAK;AAAA,IACT;AACA,SAAI,OAAE,WAAW,cAAb,mBAAwB,gBAAgB;AACxC,YAAM;AAAA,IACV;AACA,WAAO,EAAE,GAAG,GAAA;AAAA,EAChB;AAAA,EACA,KAAK,KAAK;AACN,QAAI,EAAE,IAAI,YAAY,qBAAqB;AACvC,aAAO;AAAA,IACX;AACA,WAAO,0BAA0B,IAAI,YAAY,2BAA2B,GAAG,IAAI,UAAU,IAAI,aAAa,qCAAqC,CAAC;AAAA,EACxJ;AAAA,EACA,SAAS,MAAM,KAAK,SAAS;;AACzB,UAAM,IAAI;AACV,UAAI,OAAE,eAAF,mBAAc,iBAAgB,QAAQ,IAAI,kBAAkB,GAAG;AAC/D,yBAAmB,MAAM,EAAE,YAA+B,OAAO;AAAA,IACrE;AAAA,EACJ;AAAA,EACA,KAAK,KAAK,SAAS,GAAG;;AAClB,SAAK,IAAI,YAAY,2BAA2B,GAAG;AAC/C,YAAM,OAAO,eAAI,UAA+B,eAAnC,mBAA+C,cAA/C,mBAA0D;AACvE,UAAI,KAAK;AACL,gBAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,MAAM;AACjD,gBAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,SAAS;AAAA,MACxD;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EACA,SAAS,KAAK,KAAK;;AACf,UAAM,KAAK,eAAyB,eAAzB,mBAAqC,cAArC,mBAAgD;AAC3D,QAAI,GAAG;AACH,UAAI,KAAK,CAAC;AAAA,IACd;AAAA,EACJ;AACJ;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BU,
|
|
2
|
-
import { syncThinInstanceGpuData } from "./thin-instance-gpu-
|
|
1
|
+
import { B as BU, bQ as getViewProjectionMatrix, U as U32, a as F32 } from "./index-C-tEgwbZ.js";
|
|
2
|
+
import { syncThinInstanceGpuData } from "./thin-instance-gpu-uY2NOv0J.js";
|
|
3
3
|
const WORKGROUP_SIZE = 64;
|
|
4
4
|
const PARAM_BYTES = 192;
|
|
5
5
|
const COUNT_U32_OFFSET = 44;
|
|
@@ -307,4 +307,4 @@ function tryBind(renderable, scene, mesh, engine, hasColor, excluded, baseUpdate
|
|
|
307
307
|
export {
|
|
308
308
|
tryBind
|
|
309
309
|
};
|
|
310
|
-
//# sourceMappingURL=thin-instance-cull-binding-
|
|
310
|
+
//# sourceMappingURL=thin-instance-cull-binding-DwZi7mlE.js.map
|
package/{thin-instance-cull-binding-DWKUt5ZN.js.map → thin-instance-cull-binding-DwZi7mlE.js.map}
RENAMED
|
@@ -1 +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
|
+
{"version":3,"file":"thin-instance-cull-binding-DwZi7mlE.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,4 +1,4 @@
|
|
|
1
|
-
import { B as BU, a as F32, p as packMat4IntoF32 } from "./index-
|
|
1
|
+
import { B as BU, a as F32, p as packMat4IntoF32 } from "./index-C-tEgwbZ.js";
|
|
2
2
|
function syncThinInstanceGpuData(engine, ti, hasColor) {
|
|
3
3
|
var _a, _b;
|
|
4
4
|
const device = engine._device;
|
|
@@ -84,4 +84,4 @@ export {
|
|
|
84
84
|
syncThinInstanceBuffers,
|
|
85
85
|
syncThinInstanceGpuData
|
|
86
86
|
};
|
|
87
|
-
//# sourceMappingURL=thin-instance-gpu-
|
|
87
|
+
//# sourceMappingURL=thin-instance-gpu-uY2NOv0J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thin-instance-gpu-
|
|
1
|
+
{"version":3,"file":"thin-instance-gpu-uY2NOv0J.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 {
|
|
1
|
+
import { f as markMaterialUboDirty } from "./index-C-tEgwbZ.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-Ck5bgCuo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking-primitives-
|
|
1
|
+
{"version":3,"file":"tracking-primitives-Ck5bgCuo.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 { b4 as PBR2_HAS_UNLIT } from "./index-C-tEgwbZ.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-nc6hu3Mw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlit-fragment-
|
|
1
|
+
{"version":3,"file":"unlit-fragment-nc6hu3Mw.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;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-ext-basisu-CDbPclzZ.js","sources":["../src/texture/ktx2-loader.ts","../src/loader-gltf/gltf-ext-basisu.ts"],"sourcesContent":["/** KTX2/Basis Universal decoder for glTF KHR_texture_basisu.\n *\n * Kept separate from `basis-loader.ts` so existing `.basis` texture scenes do\n * not pay for KTX2 decoder glue. The CDN decoder is still fetched lazily only\n * after an asset declares KHR_texture_basisu.\n */\n\nimport { U8C, U8 } from \"../engine/typed-arrays.js\";\nimport { TU } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { acquireTexture, getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport type { Texture2D } from \"./texture-2d.js\";\nimport { getCompressedFormat } from \"./compressed-formats.js\";\nimport type { CompressedFormatInfo } from \"./compressed-formats.js\";\n\ninterface Ktx2DecoderCaps {\n astc: boolean;\n bptc: boolean;\n s3tc: boolean;\n pvrtc: boolean;\n etc2: boolean;\n etc1: boolean;\n}\n\ninterface Ktx2DecodedMip {\n width: number;\n height: number;\n data: Uint8Array;\n}\n\ninterface Ktx2DecodedData {\n width: number;\n height: number;\n transcodedFormat: number;\n isInGammaSpace: boolean;\n hasAlpha: boolean;\n transcoderName: string;\n errors?: string;\n mipmaps: Ktx2DecodedMip[];\n}\n\ninterface Ktx2Decoder {\n decode(data: Uint8Array, caps: Ktx2DecoderCaps, options?: { forceRGBA?: boolean }): Promise<Ktx2DecodedData>;\n}\n\ninterface Ktx2DecoderModule {\n KTX2Decoder: new () => Ktx2Decoder;\n MSCTranscoder: { UseFromWorkerThread: boolean };\n WASMMemoryManager: { LoadBinariesFromCurrentThread: boolean };\n}\n\nconst KTX2_DECODER_URL = \"https://cdn.babylonjs.com/babylon.ktx2Decoder.js\";\nlet _ktx2DecoderPromise: Promise<Ktx2Decoder> | null = null;\n\nconst GL_RGBA8 = 0x8058;\nconst GL_R8 = 0x8229;\nconst GL_RG8 = 0x822b;\nconst RGBA_CAPS: Ktx2DecoderCaps = { astc: false, bptc: false, s3tc: false, pvrtc: false, etc2: false, etc1: false };\n\nfunction loadKtx2Decoder(): Promise<Ktx2Decoder> {\n if (_ktx2DecoderPromise) {\n return _ktx2DecoderPromise;\n }\n _ktx2DecoderPromise = new Promise<Ktx2Decoder>((resolve, reject) => {\n const w = globalThis as unknown as { KTX2DECODER?: Ktx2DecoderModule };\n const init = (): void => {\n const mod = w.KTX2DECODER;\n if (!mod) {\n reject(new Error(\"KTX2: decoder global KTX2DECODER not found after script load\"));\n return;\n }\n mod.MSCTranscoder.UseFromWorkerThread = false;\n mod.WASMMemoryManager.LoadBinariesFromCurrentThread = true;\n resolve(new mod.KTX2Decoder());\n };\n if (w.KTX2DECODER) {\n init();\n return;\n }\n const script = document.createElement(\"script\");\n script.src = KTX2_DECODER_URL;\n script.async = true;\n script.onload = init;\n script.onerror = (): void => reject(new Error(`KTX2: failed to load ${script.src}`));\n document.head.appendChild(script);\n });\n _ktx2DecoderPromise.catch(() => {\n _ktx2DecoderPromise = null;\n });\n return _ktx2DecoderPromise;\n}\n\nfunction srgbFormat(format: GPUTextureFormat): GPUTextureFormat {\n switch (format) {\n case \"rgba8unorm\":\n return \"rgba8unorm-srgb\";\n case \"bc1-rgba-unorm\":\n return \"bc1-rgba-unorm-srgb\";\n case \"bc2-rgba-unorm\":\n return \"bc2-rgba-unorm-srgb\";\n case \"bc3-rgba-unorm\":\n return \"bc3-rgba-unorm-srgb\";\n case \"bc7-rgba-unorm\":\n return \"bc7-rgba-unorm-srgb\";\n case \"etc2-rgb8unorm\":\n return \"etc2-rgb8unorm-srgb\";\n case \"etc2-rgb8a1unorm\":\n return \"etc2-rgb8a1unorm-srgb\";\n case \"etc2-rgba8unorm\":\n return \"etc2-rgba8unorm-srgb\";\n case \"astc-4x4-unorm\":\n return \"astc-4x4-unorm-srgb\";\n case \"astc-5x4-unorm\":\n return \"astc-5x4-unorm-srgb\";\n case \"astc-5x5-unorm\":\n return \"astc-5x5-unorm-srgb\";\n case \"astc-6x5-unorm\":\n return \"astc-6x5-unorm-srgb\";\n case \"astc-6x6-unorm\":\n return \"astc-6x6-unorm-srgb\";\n case \"astc-8x5-unorm\":\n return \"astc-8x5-unorm-srgb\";\n case \"astc-8x6-unorm\":\n return \"astc-8x6-unorm-srgb\";\n case \"astc-8x8-unorm\":\n return \"astc-8x8-unorm-srgb\";\n case \"astc-10x5-unorm\":\n return \"astc-10x5-unorm-srgb\";\n case \"astc-10x6-unorm\":\n return \"astc-10x6-unorm-srgb\";\n case \"astc-10x8-unorm\":\n return \"astc-10x8-unorm-srgb\";\n case \"astc-10x10-unorm\":\n return \"astc-10x10-unorm-srgb\";\n case \"astc-12x10-unorm\":\n return \"astc-12x10-unorm-srgb\";\n case \"astc-12x12-unorm\":\n return \"astc-12x12-unorm-srgb\";\n default:\n return format;\n }\n}\n\nfunction uncompressedInfo(glFormat: number): { format: GPUTextureFormat; bytesPerPixel: number } | null {\n switch (glFormat) {\n case GL_RGBA8:\n return { format: \"rgba8unorm\", bytesPerPixel: 4 };\n case GL_R8:\n return { format: \"r8unorm\", bytesPerPixel: 1 };\n case GL_RG8:\n return { format: \"rg8unorm\", bytesPerPixel: 2 };\n default:\n return null;\n }\n}\n\nfunction validateDecoded(decoded: Ktx2DecodedData): Ktx2DecodedMip[] {\n if (decoded.errors) {\n throw new Error(`KTX2: ${decoded.errors}`);\n }\n if (!decoded.mipmaps.length) {\n throw new Error(\"KTX2: decoder produced no mipmaps\");\n }\n for (let i = 0; i < decoded.mipmaps.length; i++) {\n if (!decoded.mipmaps[i]?.data) {\n throw new Error(`KTX2: decoder produced an empty mip ${i}`);\n }\n }\n return decoded.mipmaps;\n}\n\nfunction makeSampler(engine: EngineContext, mipCount: number): GPUSampler {\n return getOrCreateSampler(engine, {\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n minFilter: \"linear\",\n magFilter: \"linear\",\n mipmapFilter: mipCount > 1 ? \"linear\" : \"nearest\",\n maxAnisotropy: mipCount > 1 ? 4 : 1,\n });\n}\n\nfunction uploadCompressed(engine: EngineContext, mips: Ktx2DecodedMip[], format: CompressedFormatInfo, sRGB: boolean): Texture2D {\n if (!engine._device.features.has(format.feature as GPUFeatureName)) {\n throw new Error(`KTX2: device does not support ${format.feature}`);\n }\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(format.gpuFormat) : format.gpuFormat,\n mipLevelCount: mips.length,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const blocksPerRow = Math.ceil(mip.width / format.blockW);\n const rowBytes = blocksPerRow * format.blockBytes;\n // Copy extent must be block-padded (physical) size; tail mips smaller\n // than the block are copied as one full block (see ktx-loader.ts).\n const copyW = blocksPerRow * format.blockW;\n const copyH = Math.ceil(mip.height / format.blockH) * format.blockH;\n engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data as Uint8Array<ArrayBuffer>, { bytesPerRow: rowBytes }, { width: copyW, height: copyH });\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\nfunction uploadUncompressed(engine: EngineContext, mips: Ktx2DecodedMip[], info: { format: GPUTextureFormat; bytesPerPixel: number }, sRGB: boolean): Texture2D {\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(info.format) : info.format,\n mipLevelCount: mips.length,\n usage: TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const expected = mip.width * mip.height * info.bytesPerPixel;\n if (mip.data.length !== expected) {\n throw new Error(`KTX2: uncompressed mip ${level} has ${mip.data.length} bytes, expected ${expected}`);\n }\n engine._device.queue.writeTexture(\n { texture, mipLevel: level },\n mip.data as Uint8Array<ArrayBuffer>,\n { bytesPerRow: mip.width * info.bytesPerPixel },\n { width: mip.width, height: mip.height }\n );\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\n/** Decode a KTX2 texture with the current WebGPU compression caps and upload the\n * decoder-provided full mip chain directly to a Texture2D. */\nexport async function uploadKtx2Texture2D(engine: EngineContext, buffer: ArrayBuffer, sRGB: boolean): Promise<Texture2D> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });\n const mips = validateDecoded(decoded);\n\n const compressed = getCompressedFormat(decoded.transcodedFormat);\n if (compressed) {\n return uploadCompressed(engine, mips, compressed, sRGB);\n }\n\n const uncompressed = uncompressedInfo(decoded.transcodedFormat);\n if (uncompressed) {\n return uploadUncompressed(engine, mips, uncompressed, sRGB);\n }\n\n throw new Error(`KTX2: unsupported transcoded format 0x${decoded.transcodedFormat.toString(16)}`);\n}\n\n/** Decode the first mip level of a KTX2 texture into an ImageBitmap so glTF\n * material extensions can reuse the core image upload path. */\nexport async function decodeKtx2ImageBitmapFromBuffer(buffer: ArrayBuffer): Promise<ImageBitmap> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new U8(buffer), RGBA_CAPS, { forceRGBA: true });\n const mip0 = validateDecoded(decoded)[0]!;\n if (mip0.data.length !== mip0.width * mip0.height * 4) {\n throw new Error(\"KTX2: RGBA decode size does not match image dimensions\");\n }\n const pixels = new U8C(mip0.data.length);\n pixels.set(mip0.data);\n return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));\n}\n","/** KHR_texture_basisu glTF texture-source extension.\n *\n * The extension redirects textureInfos whose glTF texture declares\n * `extensions.KHR_texture_basisu.source` to the referenced KTX2 image and\n * uploads it through the lazily fetched KTX2 decoder. Core glTF\n * material parsing remains extension-agnostic: this module only loads when the\n * asset lists KHR_texture_basisu in `extensionsUsed`.\n */\n\nimport { F32, U32, U8, DV } from \"../engine/typed-arrays.js\";\nimport type { GltfMatExtCtx } from \"./gltf-material.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { DecodedPrimitive } from \"./gltf-feature.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { decodeKtx2ImageBitmapFromBuffer, uploadKtx2Texture2D } from \"../texture/ktx2-loader.js\";\n\nconst NAME = \"KHR_texture_basisu\";\nconst FLOAT = 5126;\n// glTF accessor component types → byte size. Interleaved (strided) vertex attributes can be any of these,\n// not just FLOAT (e.g. a normalized `COLOR_0: UNSIGNED_BYTE`), so the strided reader must handle them all.\nconst COMPONENT_BYTES: Record<number, number> = { 5120: 1, 5121: 1, 5122: 2, 5123: 2, 5125: 4, 5126: 4 };\nconst TYPE_SIZES: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16,\n};\nconst BASISU_MATERIAL_DATA = \"__basisuMaterialData\";\n\ninterface BasisuMaterialData {\n json: any;\n binChunk: DataView;\n baseUrl: string;\n baseColorTexture?: any;\n metallicRoughnessTexture?: any;\n normalTexture?: any;\n occlusionTexture?: any;\n emissiveTexture?: any;\n specularTexture?: any;\n specularColorTexture?: any;\n bitmaps?: Map<number, Promise<ImageBitmap>>;\n textures?: Map<string, Texture2D>;\n}\n\nfunction basisSourceIndex(tex: unknown): number | null {\n const source = (tex as { extensions?: { KHR_texture_basisu?: { source?: unknown } } } | undefined)?.extensions?.KHR_texture_basisu?.source;\n return typeof source === \"number\" ? source : null;\n}\n\nfunction textureIndex(texInfo: unknown): number | null {\n const index = (texInfo as { index?: unknown } | undefined)?.index;\n return typeof index === \"number\" ? index : null;\n}\n\nfunction textureUsesBasisu(json: any, texInfo: unknown): boolean {\n const index = textureIndex(texInfo);\n return index !== null && basisSourceIndex(json.textures?.[index]) !== null;\n}\n\nfunction stripBasisuTexture(json: any, owner: any, slot: keyof BasisuMaterialData, data: BasisuMaterialData): boolean {\n if (!textureUsesBasisu(json, owner?.[slot])) {\n return false;\n }\n data[slot] = owner[slot];\n delete owner[slot];\n return true;\n}\n\nfunction prepareBasisuMaterials(json: any, binChunk: DataView, baseUrl: string): void {\n for (const mat of json.materials ?? []) {\n const data: BasisuMaterialData = { json, binChunk, baseUrl };\n const pbr = mat.pbrMetallicRoughness ?? {};\n let hasBasisu = stripBasisuTexture(json, pbr, \"baseColorTexture\", data);\n hasBasisu = stripBasisuTexture(json, pbr, \"metallicRoughnessTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"normalTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"occlusionTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"emissiveTexture\", data) || hasBasisu;\n const spec = mat.extensions?.KHR_materials_specular;\n if (spec) {\n hasBasisu = stripBasisuTexture(json, spec, \"specularTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, spec, \"specularColorTexture\", data) || hasBasisu;\n }\n if (hasBasisu) {\n Object.defineProperty(mat, BASISU_MATERIAL_DATA, { value: data });\n }\n }\n}\n\nasync function resolveImageBuffer(ctx: BasisuMaterialData, imageIdx: number): Promise<ArrayBuffer> {\n const image = ctx.json.images?.[imageIdx];\n if (!image) {\n throw new Error(`${NAME}: image ${imageIdx} not found`);\n }\n if (image.bufferView !== undefined) {\n const bv = ctx.json.bufferViews?.[image.bufferView];\n if (!bv) {\n throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);\n }\n const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);\n const copy = new U8(bv.byteLength);\n copy.set(new U8(ctx.binChunk.buffer, offset, bv.byteLength));\n return copy.buffer;\n }\n if (image.uri) {\n const url = new URL(image.uri, ctx.baseUrl + \"x\").href;\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${NAME}: failed to load image ${response.status} ${response.statusText}`);\n }\n return response.arrayBuffer();\n }\n throw new Error(`${NAME}: image has neither bufferView nor uri`);\n}\n\nasync function loadBasisuBitmap(data: BasisuMaterialData, texInfo: unknown): Promise<ImageBitmap | null> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return null;\n }\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return null;\n }\n data.bitmaps ??= new Map();\n let bitmap = data.bitmaps.get(index);\n if (!bitmap) {\n bitmap = resolveImageBuffer(data, source).then(decodeKtx2ImageBitmapFromBuffer);\n data.bitmaps.set(index, bitmap);\n }\n return bitmap;\n}\n\nasync function uploadBasisuTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx, texInfo: unknown, sRGB: boolean): Promise<Texture2D | undefined> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return undefined;\n }\n data.textures ??= new Map();\n const key = `${index}:${sRGB ? 1 : 0}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return undefined;\n }\n tex = await uploadKtx2Texture2D(ctx._engine, await resolveImageBuffer(data, source), sRGB);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\nasync function compositeOrm(mr: ImageBitmap, occ: ImageBitmap): Promise<ImageBitmap> {\n const w = mr.width;\n const h = mr.height;\n const c1 = new OffscreenCanvas(w, h);\n const x1 = c1.getContext(\"2d\")!;\n x1.drawImage(mr, 0, 0, w, h);\n const d1 = x1.getImageData(0, 0, w, h);\n const c2 = new OffscreenCanvas(w, h);\n const x2 = c2.getContext(\"2d\")!;\n x2.drawImage(occ, 0, 0, w, h);\n const d2 = x2.getImageData(0, 0, w, h);\n for (let j = 0; j < d1.data.length; j += 4) {\n d1.data[j] = d2.data[j]!;\n }\n x1.putImageData(d1, 0, 0);\n return createImageBitmap(c1);\n}\n\nasync function uploadOrmTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx): Promise<Texture2D | undefined> {\n const mrInfo = data.metallicRoughnessTexture;\n const occInfo = data.occlusionTexture;\n const mrIndex = textureIndex(mrInfo);\n const occIndex = textureIndex(occInfo);\n if (mrIndex === null && occIndex === null) {\n return undefined;\n }\n if (mrIndex === null || occIndex === null || mrIndex === occIndex) {\n return uploadBasisuTexture(data, ctx, mrInfo ?? occInfo, false);\n }\n data.textures ??= new Map();\n const key = `orm:${mrIndex}:${occIndex}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const [mr, occ] = await Promise.all([loadBasisuBitmap(data, mrInfo), loadBasisuBitmap(data, occInfo)]);\n if (!mr || !occ) {\n return undefined;\n }\n tex = ctx._uploadImage(await compositeOrm(mr, occ), false);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\n// Read one interleaved attribute component, decoding its glTF component type to a float. NORMALIZED integer\n// attributes (the `normalized` accessor flag) map to [0,1] (unsigned) or [-1,1] (signed); non-normalized ones\n// pass through as their integer value. DataView handles unaligned little-endian reads, so any stride is fine.\nfunction readComponent(view: DataView, offset: number, componentType: number, normalized: boolean): number {\n switch (componentType) {\n case FLOAT:\n return view.getFloat32(offset, true);\n case 5125: {\n const v = view.getUint32(offset, true);\n return normalized ? v / 4294967295 : v;\n }\n case 5123: {\n const v = view.getUint16(offset, true);\n return normalized ? v / 65535 : v;\n }\n case 5122: {\n const v = view.getInt16(offset, true);\n return normalized ? Math.max(v / 32767, -1) : v;\n }\n case 5121: {\n const v = view.getUint8(offset);\n return normalized ? v / 255 : v;\n }\n case 5120: {\n const v = view.getInt8(offset);\n return normalized ? Math.max(v / 127, -1) : v;\n }\n default:\n throw new Error(`${NAME}: strided accessor uses unsupported component type: ${componentType}`);\n }\n}\n\nfunction readStridedFloat(json: any, binChunk: DataView, accessorIdx: number): Float32Array {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n const componentType = accessor.componentType;\n const compBytes = COMPONENT_BYTES[componentType];\n if (!compBytes) {\n throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${componentType}`);\n }\n const componentCount = TYPE_SIZES[accessor.type] ?? 1;\n const elementBytes = componentCount * compBytes;\n const byteStride = bufferView.byteStride ?? elementBytes;\n if (byteStride < elementBytes) {\n throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);\n }\n const normalized = accessor.normalized === true;\n const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const view = new DV(binChunk.buffer);\n const out = new F32(accessor.count * componentCount);\n for (let i = 0, o = 0; i < accessor.count; i++) {\n const src = baseOffset + i * byteStride;\n for (let c = 0; c < componentCount; c++, o++) {\n out[o] = readComponent(view, src + c * compBytes, componentType, normalized);\n }\n }\n return out;\n}\n\nconst ext: GltfFeature = {\n id: NAME,\n async preMesh(json, binChunk, baseUrl) {\n const gltf = json as any;\n prepareBasisuMaterials(gltf, binChunk, baseUrl);\n const decoded = new Map<unknown, DecodedPrimitive>();\n for (const mesh of gltf.meshes ?? []) {\n for (const primitive of mesh.primitives ?? []) {\n const attrs = primitive.attributes ?? {};\n const strided = Object.keys(attrs).some((name) => gltf.bufferViews?.[gltf.accessors?.[attrs[name]]?.bufferView]?.byteStride !== undefined);\n if (!strided) {\n continue;\n }\n const attributes = new Map<string, Float32Array>();\n for (const name of Object.keys(attrs)) {\n const accessorIdx = attrs[name];\n const accessor = gltf.accessors[accessorIdx];\n if (gltf.bufferViews?.[accessor.bufferView]?.byteStride !== undefined) {\n attributes.set(name, readStridedFloat(gltf, binChunk, accessorIdx));\n }\n }\n const posAcc = gltf.accessors[attrs.POSITION];\n const idx =\n primitive.indices === undefined ? new U32(0) : new U32(resolveAccessor(gltf, binChunk, primitive.indices)._data as Uint16Array | Uint32Array | Uint8Array);\n decoded.set(primitive, {\n _attributes: attributes,\n _indices: idx,\n _vertexCount: posAcc.count,\n _indexCount: idx.length,\n });\n }\n }\n return decoded;\n },\n async applyMaterial(mat, ctx) {\n const data = mat._rawMatDef?.[BASISU_MATERIAL_DATA] as BasisuMaterialData | undefined;\n if (!data) {\n return null;\n }\n const [baseColorTexture, ormTexture, normalTexture, emissiveTexture, specularTexture, specularColorTexture] = await Promise.all([\n uploadBasisuTexture(data, ctx, data.baseColorTexture, true),\n uploadOrmTexture(data, ctx),\n uploadBasisuTexture(data, ctx, data.normalTexture, false),\n uploadBasisuTexture(data, ctx, data.emissiveTexture, true),\n uploadBasisuTexture(data, ctx, data.specularTexture, false),\n uploadBasisuTexture(data, ctx, data.specularColorTexture, true),\n ]);\n const out: Partial<PbrMaterialProps> = {\n ...(baseColorTexture ? { baseColorTexture } : undefined),\n ...(ormTexture\n ? {\n ormTexture,\n ...(data.metallicRoughnessTexture ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(data.occlusionTexture ? { occlusionStrength: 1.0, occlusionTexCoord: data.occlusionTexture.texCoord ?? 0 } : undefined),\n }\n : undefined),\n ...(normalTexture ? { normalTexture, normalTextureScale: data.normalTexture?.scale ?? 1 } : undefined),\n ...(emissiveTexture ? { emissiveTexture } : undefined),\n ...(specularTexture ? { metallicReflectanceTexture: specularTexture, useOnlyMetallicFromMetallicReflectanceTexture: true } : undefined),\n ...(specularColorTexture ? { reflectanceTexture: specularColorTexture } : undefined),\n };\n if (!out.baseColorTexture && !out.ormTexture && !out.normalTexture && !out.emissiveTexture && !out.metallicReflectanceTexture && !out.reflectanceTexture) {\n return null;\n }\n return out;\n },\n};\n\nexport default ext;\n"],"names":["_b","_a"],"mappings":"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"}
|