@babylonjs/lite 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{_mat4-storage-f64-WeexU-hd.js → _mat4-storage-f64-BqqOLkos.js} +2 -2
- package/{_mat4-storage-f64-WeexU-hd.js.map → _mat4-storage-f64-BqqOLkos.js.map} +1 -1
- package/{alpha-test-fragment-x2mnjLgC.js → alpha-test-fragment-D8oeUpvv.js} +2 -2
- package/{alpha-test-fragment-x2mnjLgC.js.map → alpha-test-fragment-D8oeUpvv.js.map} +1 -1
- package/{background-dds-skybox-BpcDr-9c.js → background-dds-skybox-Cv92mmdC.js} +3 -4
- package/{background-dds-skybox-BpcDr-9c.js.map → background-dds-skybox-Cv92mmdC.js.map} +1 -1
- package/{background-ground-Bm6gjWqx.js → background-ground-ClcWiDuF.js} +2 -3
- package/{background-ground-Bm6gjWqx.js.map → background-ground-ClcWiDuF.js.map} +1 -1
- package/{background-hdr-skybox-CSFo8RX6.js → background-hdr-skybox-MfAwLhVx.js} +3 -3
- package/{background-hdr-skybox-CSFo8RX6.js.map → background-hdr-skybox-MfAwLhVx.js.map} +1 -1
- package/{background-solid-skybox-DOOBeDIz.js → background-solid-skybox-CkmGuOn5.js} +2 -3
- package/{background-solid-skybox-DOOBeDIz.js.map → background-solid-skybox-CkmGuOn5.js.map} +1 -1
- package/{billboard-renderable-IJfCpeDS.js → billboard-renderable-CmIfD7IP.js} +2 -2
- package/{billboard-renderable-IJfCpeDS.js.map → billboard-renderable-CmIfD7IP.js.map} +1 -1
- package/{clamp-block-BD_t8I89.js → clamp-block-Bupvx5sX.js} +2 -2
- package/{clamp-block-BD_t8I89.js.map → clamp-block-Bupvx5sX.js.map} +1 -1
- package/{clearcoat-fragment-Dj7vGX2u.js → clearcoat-fragment-wfkXOHHZ.js} +2 -2
- package/{clearcoat-fragment-Dj7vGX2u.js.map → clearcoat-fragment-wfkXOHHZ.js.map} +1 -1
- package/{create-skeleton-s0hjrC3A.js → create-skeleton-41NqPV9u.js} +2 -2
- package/{create-skeleton-s0hjrC3A.js.map → create-skeleton-41NqPV9u.js.map} +1 -1
- package/{cubemap-skybox-material-8lzbgi7K.js → cubemap-skybox-material-BWGdKMLi.js} +2 -2
- package/{cubemap-skybox-material-8lzbgi7K.js.map → cubemap-skybox-material-BWGdKMLi.js.map} +1 -1
- package/{curve-block-Ditr4R7V.js → curve-block-CeLMJE2N.js} +2 -2
- package/{curve-block-Ditr4R7V.js.map → curve-block-CeLMJE2N.js.map} +1 -1
- package/{emissive-fragment-BOAezkfk.js → emissive-fragment-CDJhX8ad.js} +2 -2
- package/{emissive-fragment-BOAezkfk.js.map → emissive-fragment-CDJhX8ad.js.map} +1 -1
- package/{esm-shadow-view-JCPaOOi7.js → esm-shadow-view-CcX1jdrL.js} +2 -2
- package/{esm-shadow-view-JCPaOOi7.js.map → esm-shadow-view-CcX1jdrL.js.map} +1 -1
- package/{esm-shadow-view-DRpyRAfa.js → esm-shadow-view-Cf2PwVNs.js} +2 -2
- package/{esm-shadow-view-DRpyRAfa.js.map → esm-shadow-view-Cf2PwVNs.js.map} +1 -1
- package/{esm-shadow-view-DmIORQGZ.js → esm-shadow-view-KyVyZnKZ.js} +2 -2
- package/{esm-shadow-view-DmIORQGZ.js.map → esm-shadow-view-KyVyZnKZ.js.map} +1 -1
- package/{gaussian-splatting-pipeline-sh-B30Mu56i.js → gaussian-splatting-pipeline-sh-lM48JDca.js} +2 -2
- package/{gaussian-splatting-pipeline-sh-B30Mu56i.js.map → gaussian-splatting-pipeline-sh-lM48JDca.js.map} +1 -1
- package/{geometry-texture-output-DURiaJ_n.js → geometry-texture-output-DSeH_3G_.js} +2 -2
- package/{geometry-texture-output-DURiaJ_n.js.map → geometry-texture-output-DSeH_3G_.js.map} +1 -1
- package/{geometry-view-DRrscyWU.js → geometry-view-L27hzPQF.js} +3 -4
- package/{geometry-view-DRrscyWU.js.map → geometry-view-L27hzPQF.js.map} +1 -1
- package/{gltf-animation-BjnXkop6.js → gltf-animation-Db8PwXmY.js} +6 -5
- package/gltf-animation-Db8PwXmY.js.map +1 -0
- package/{gltf-ext-basisu-DtzVV1Xx.js → gltf-ext-basisu-BARpgeiU.js} +2 -2
- package/{gltf-ext-basisu-DtzVV1Xx.js.map → gltf-ext-basisu-BARpgeiU.js.map} +1 -1
- package/{gltf-ext-node-visibility-BhX0DmiP.js → gltf-ext-node-visibility-Cv7HyWR_.js} +2 -2
- package/{gltf-ext-node-visibility-BhX0DmiP.js.map → gltf-ext-node-visibility-Cv7HyWR_.js.map} +1 -1
- package/{gltf-ext-quantization-DaymajCR.js → gltf-ext-quantization-DIYKR7_3.js} +2 -2
- package/{gltf-ext-quantization-DaymajCR.js.map → gltf-ext-quantization-DIYKR7_3.js.map} +1 -1
- package/{gltf-ext-uv-transform-DFmNJ8kA.js → gltf-ext-uv-transform-qU-LScDy.js} +2 -2
- package/{gltf-ext-uv-transform-DFmNJ8kA.js.map → gltf-ext-uv-transform-qU-LScDy.js.map} +1 -1
- package/gltf-feature-animation-pointer-nDf6dGpL.js +161 -0
- package/gltf-feature-animation-pointer-nDf6dGpL.js.map +1 -0
- package/{gltf-feature-animations-v0S_yb4T.js → gltf-feature-animations-Dr9AsgIN.js} +3 -3
- package/{gltf-feature-animations-v0S_yb4T.js.map → gltf-feature-animations-Dr9AsgIN.js.map} +1 -1
- package/gltf-feature-draco-CRgxNaK1.js +33 -0
- package/gltf-feature-draco-CRgxNaK1.js.map +1 -0
- package/{gltf-feature-gpu-instancing-BoeSm6Tn.js → gltf-feature-gpu-instancing-QfJNFW1R.js} +2 -2
- package/{gltf-feature-gpu-instancing-BoeSm6Tn.js.map → gltf-feature-gpu-instancing-QfJNFW1R.js.map} +1 -1
- package/{gltf-feature-lights-punctual-BCTwgyi_.js → gltf-feature-lights-punctual-B3xbCshn.js} +5 -5
- package/{gltf-feature-lights-punctual-BCTwgyi_.js.map → gltf-feature-lights-punctual-B3xbCshn.js.map} +1 -1
- package/{gltf-feature-meshopt-DItMkOMt.js → gltf-feature-meshopt-DBvtC2n2.js} +2 -34
- package/gltf-feature-meshopt-DBvtC2n2.js.map +1 -0
- package/{gltf-feature-morph-Cv0mEYIq.js → gltf-feature-morph-DE63vfIE.js} +3 -3
- package/{gltf-feature-morph-Cv0mEYIq.js.map → gltf-feature-morph-DE63vfIE.js.map} +1 -1
- package/{gltf-feature-registry-wNbt6UC-.js → gltf-feature-registry-DfOiNmhR.js} +15 -15
- package/{gltf-feature-registry-wNbt6UC-.js.map → gltf-feature-registry-DfOiNmhR.js.map} +1 -1
- package/{gltf-feature-skeleton-Deh2UBAn.js → gltf-feature-skeleton-IHj-DuKx.js} +12 -3
- package/gltf-feature-skeleton-IHj-DuKx.js.map +1 -0
- package/{gltf-feature-variants-DGSdFNJq.js → gltf-feature-variants-C-eyBru5.js} +2 -2
- package/{gltf-feature-variants-DGSdFNJq.js.map → gltf-feature-variants-C-eyBru5.js.map} +1 -1
- package/{gltf-glb-parser-DSQWsT4r.js → gltf-glb-parser-DXMAJA8e.js} +2 -2
- package/{gltf-glb-parser-DSQWsT4r.js.map → gltf-glb-parser-DXMAJA8e.js.map} +1 -1
- package/{gltf-interleave-OBqmlu-h.js → gltf-interleave-BdKrRH3j.js} +4 -4
- package/gltf-interleave-BdKrRH3j.js.map +1 -0
- package/{gltf-pbr-builder-ext-3imk8Tev.js → gltf-pbr-builder-ext-DJ8Jm7jo.js} +2 -2
- package/{gltf-pbr-builder-ext-3imk8Tev.js.map → gltf-pbr-builder-ext-DJ8Jm7jo.js.map} +1 -1
- package/{gltf-variants-Dyr54wwg.js → gltf-variants-C0HetOre.js} +4 -4
- package/{gltf-variants-Dyr54wwg.js.map → gltf-variants-C0HetOre.js.map} +1 -1
- package/{gpu-task-timer-DVBNZfq5.js → gpu-task-timer-C-3sLTxO.js} +2 -2
- package/{gpu-task-timer-DVBNZfq5.js.map → gpu-task-timer-C-3sLTxO.js.map} +1 -1
- package/{gs-picking-pipeline-CERN-Trj.js → gs-picking-pipeline-DlogO8fI.js} +2 -2
- package/{gs-picking-pipeline-CERN-Trj.js.map → gs-picking-pipeline-DlogO8fI.js.map} +1 -1
- package/{havok-floating-origin-VVdJRUYc.js → havok-floating-origin-CQ7yE-XD.js} +2 -2
- package/{havok-floating-origin-VVdJRUYc.js.map → havok-floating-origin-CQ7yE-XD.js.map} +1 -1
- package/{index-BgY3QEzL.js → index-C2sM8ERH.js} +2697 -932
- package/index-C2sM8ERH.js.map +1 -0
- package/index.d.ts +443 -12
- package/index.js +525 -507
- package/{input-block-DjdlndCL.js → input-block-DfFVJB-8.js} +2 -2
- package/{input-block-DjdlndCL.js.map → input-block-DfFVJB-8.js.map} +1 -1
- package/{iridescence-fragment-kfsCs8lN.js → iridescence-fragment-CQwzyZ3W.js} +2 -2
- package/{iridescence-fragment-kfsCs8lN.js.map → iridescence-fragment-CQwzyZ3W.js.map} +1 -1
- package/{light-block-qjCrz3de.js → light-block-othUHIHC.js} +2 -2
- package/{light-block-qjCrz3de.js.map → light-block-othUHIHC.js.map} +1 -1
- package/{loop-block-C8vkQ2bz.js → loop-block-DgHyTx97.js} +2 -2
- package/{loop-block-C8vkQ2bz.js.map → loop-block-DgHyTx97.js.map} +1 -1
- package/{morph-fragment-NpZYyIIU.js → morph-fragment-D_rgysrc.js} +2 -2
- package/{morph-fragment-NpZYyIIU.js.map → morph-fragment-D_rgysrc.js.map} +1 -1
- package/{multilight-wgsl-I5SncF0q.js → multilight-wgsl-DRmyM3cC.js} +2 -2
- package/{multilight-wgsl-I5SncF0q.js.map → multilight-wgsl-DRmyM3cC.js.map} +1 -1
- package/{node-env-D7Aee08u.js → node-env-B-Ca2DL0.js} +2 -2
- package/{node-env-D7Aee08u.js.map → node-env-B-Ca2DL0.js.map} +1 -1
- package/{node-geometry-view-DfKXWNfV.js → node-geometry-view-BJDB-lrf.js} +3 -3
- package/{node-geometry-view-DfKXWNfV.js.map → node-geometry-view-BJDB-lrf.js.map} +1 -1
- package/{node-registry-extra-compat-CDLeBR1P.js → node-registry-extra-compat-SwS962Ax.js} +2 -2
- package/{node-registry-extra-compat-CDLeBR1P.js.map → node-registry-extra-compat-SwS962Ax.js.map} +1 -1
- package/{node-registry-extra-math-BA8_l4lB.js → node-registry-extra-math-Bsj4UAE5.js} +2 -2
- package/{node-registry-extra-math-BA8_l4lB.js.map → node-registry-extra-math-Bsj4UAE5.js.map} +1 -1
- package/{node-renderable-EwLLnaL1.js → node-renderable-BOIc3hM1.js} +2 -2
- package/{node-renderable-EwLLnaL1.js.map → node-renderable-BOIc3hM1.js.map} +1 -1
- package/{node-shadow-CeTmT6g4.js → node-shadow-DE--Q2V1.js} +2 -2
- package/{node-shadow-CeTmT6g4.js.map → node-shadow-DE--Q2V1.js.map} +1 -1
- package/{normal-map-fragment-BHImLyM-.js → normal-map-fragment-Cjm-v9uq.js} +2 -3
- package/{normal-map-fragment-BHImLyM-.js.map → normal-map-fragment-Cjm-v9uq.js.map} +1 -1
- package/package.json +3 -3
- package/{parse-camera-5IGdctAS.js → parse-camera-uQ8oKgeH.js} +2 -2
- package/{parse-camera-5IGdctAS.js.map → parse-camera-uQ8oKgeH.js.map} +1 -1
- package/{pbr-fog-wgsl-BqdCid6r.js → pbr-fog-wgsl-B5LrMToX.js} +2 -2
- package/{pbr-fog-wgsl-BqdCid6r.js.map → pbr-fog-wgsl-B5LrMToX.js.map} +1 -1
- package/{pbr-geometry-view-Dthf9Aut.js → pbr-geometry-view-BI52zgUI.js} +9 -11
- package/pbr-geometry-view-BI52zgUI.js.map +1 -0
- package/{pbr-metallic-roughness-block-g7wjzwN_.js → pbr-metallic-roughness-block-C7s1jL4q.js} +2 -2
- package/{pbr-metallic-roughness-block-g7wjzwN_.js.map → pbr-metallic-roughness-block-C7s1jL4q.js.map} +1 -1
- package/{pbr-metallic-roughness-block-full-DD6zI_Lx.js → pbr-metallic-roughness-block-full-BuhhVBFO.js} +2 -2
- package/{pbr-metallic-roughness-block-full-DD6zI_Lx.js.map → pbr-metallic-roughness-block-full-BuhhVBFO.js.map} +1 -1
- package/{pbr-mr-helper-core-CWROQ7OA.js → pbr-mr-helper-core-XeyKg-g6.js} +2 -2
- package/{pbr-mr-helper-core-CWROQ7OA.js.map → pbr-mr-helper-core-XeyKg-g6.js.map} +1 -1
- package/{pbr-refraction-Dxsm_gii.js → pbr-refraction-Bxz4GDeh.js} +2 -2
- package/{pbr-refraction-Dxsm_gii.js.map → pbr-refraction-Bxz4GDeh.js.map} +1 -1
- package/{pbr-renderable-CuKWalEM.js → pbr-renderable-B0elfRlX.js} +41 -189
- package/pbr-renderable-B0elfRlX.js.map +1 -0
- package/{pbr-shadow-fragment-waeIBQUq.js → pbr-shadow-fragment-QHbgqVlc.js} +2 -2
- package/{pbr-shadow-fragment-waeIBQUq.js.map → pbr-shadow-fragment-QHbgqVlc.js.map} +1 -1
- package/{pbr-tracking-CdeqbBrh.js → pbr-tracking-BWWSjls_.js} +2 -2
- package/{pbr-tracking-CdeqbBrh.js.map → pbr-tracking-BWWSjls_.js.map} +1 -1
- package/{pbr-transmission-ext-BNiXngZc.js → pbr-transmission-ext-DiEBLim-.js} +2 -2
- package/{pbr-transmission-ext-BNiXngZc.js.map → pbr-transmission-ext-DiEBLim-.js.map} +1 -1
- package/{reflectance-fragment-BQFZ_pgy.js → reflectance-fragment-wBk8UtBP.js} +2 -2
- package/{reflectance-fragment-BQFZ_pgy.js.map → reflectance-fragment-wBk8UtBP.js.map} +1 -1
- package/{rgbd-decode-duTlXMWd.js → rgbd-decode-CAQ7XSwl.js} +2 -2
- package/{rgbd-decode-duTlXMWd.js.map → rgbd-decode-CAQ7XSwl.js.map} +1 -1
- package/{screenshot-readback-DnxR4rhp.js → screenshot-readback-NxsFpnE4.js} +2 -2
- package/{screenshot-readback-DnxR4rhp.js.map → screenshot-readback-NxsFpnE4.js.map} +1 -1
- package/{shader-renderable-DVMVD6zP.js → shader-renderable-CUlJSove.js} +4 -196
- package/shader-renderable-CUlJSove.js.map +1 -0
- package/{shader-thin-instance-CsDo3ULk.js → shader-thin-instance-BjIbuYdv.js} +2 -2
- package/{shader-thin-instance-CsDo3ULk.js.map → shader-thin-instance-BjIbuYdv.js.map} +1 -1
- package/{sheen-fragment-B_Jd7wrr.js → sheen-fragment-ef8myYaq.js} +2 -2
- package/{sheen-fragment-B_Jd7wrr.js.map → sheen-fragment-ef8myYaq.js.map} +1 -1
- package/{singlelight-directional-wgsl-Bw84txva.js → singlelight-directional-wgsl-BvFBA1MO.js} +2 -2
- package/{singlelight-directional-wgsl-Bw84txva.js.map → singlelight-directional-wgsl-BvFBA1MO.js.map} +1 -1
- package/{singlelight-hemispheric-wgsl-DjxhgI8r.js → singlelight-hemispheric-wgsl-BEsGCqSN.js} +2 -2
- package/{singlelight-hemispheric-wgsl-DjxhgI8r.js.map → singlelight-hemispheric-wgsl-BEsGCqSN.js.map} +1 -1
- package/{singlelight-point-wgsl-iA1aRkXA.js → singlelight-point-wgsl-CvMr18Zf.js} +2 -2
- package/{singlelight-point-wgsl-iA1aRkXA.js.map → singlelight-point-wgsl-CvMr18Zf.js.map} +1 -1
- package/{singlelight-spot-wgsl-MDdTdstF.js → singlelight-spot-wgsl-jYIr13wU.js} +2 -2
- package/{singlelight-spot-wgsl-MDdTdstF.js.map → singlelight-spot-wgsl-jYIr13wU.js.map} +1 -1
- package/{skeleton-fragment-COdHWFcK.js → skeleton-fragment-B9M_ddNC.js} +2 -2
- package/{skeleton-fragment-COdHWFcK.js.map → skeleton-fragment-B9M_ddNC.js.map} +1 -1
- package/{skybox-renderable-DJYkfw32.js → skybox-renderable-lbMC32aI.js} +2 -3
- package/{skybox-renderable-DJYkfw32.js.map → skybox-renderable-lbMC32aI.js.map} +1 -1
- package/{splat-ply-compressed-SxMlsKNK.js → splat-ply-compressed-B_w2N_V7.js} +2 -2
- package/{splat-ply-compressed-SxMlsKNK.js.map → splat-ply-compressed-B_w2N_V7.js.map} +1 -1
- package/{standard-renderable-BAc-i-ig.js → standard-renderable-AYZ-Pdcm.js} +3 -4
- package/standard-renderable-AYZ-Pdcm.js.map +1 -0
- package/{std-ambient-fragment-P8dHZ4An.js → std-ambient-fragment-BXl-88sn.js} +2 -2
- package/{std-ambient-fragment-P8dHZ4An.js.map → std-ambient-fragment-BXl-88sn.js.map} +1 -1
- package/{std-cube-reflection-fragment-CF03MuQt.js → std-cube-reflection-fragment-Dn34WuMa.js} +2 -2
- package/{std-cube-reflection-fragment-CF03MuQt.js.map → std-cube-reflection-fragment-Dn34WuMa.js.map} +1 -1
- package/{std-emissive-fragment-P8yJGclx.js → std-emissive-fragment-CK7TwRAt.js} +2 -2
- package/{std-emissive-fragment-P8yJGclx.js.map → std-emissive-fragment-CK7TwRAt.js.map} +1 -1
- package/{std-lightmap-fragment-CymEG79z.js → std-lightmap-fragment-BSeS8K-4.js} +2 -2
- package/{std-lightmap-fragment-CymEG79z.js.map → std-lightmap-fragment-BSeS8K-4.js.map} +1 -1
- package/{std-opacity-fragment-DLa1zV06.js → std-opacity-fragment-DnLaWH9w.js} +2 -2
- package/{std-opacity-fragment-DLa1zV06.js.map → std-opacity-fragment-DnLaWH9w.js.map} +1 -1
- package/{std-reflection-fragment-BLySsYos.js → std-reflection-fragment-BToYPemd.js} +2 -2
- package/{std-reflection-fragment-BLySsYos.js.map → std-reflection-fragment-BToYPemd.js.map} +1 -1
- package/{std-shadow-fragment-C_q27Mdi.js → std-shadow-fragment-9b0rFY7F.js} +2 -2
- package/{std-shadow-fragment-C_q27Mdi.js.map → std-shadow-fragment-9b0rFY7F.js.map} +1 -1
- package/{std-specular-fragment-CaBXyAWY.js → std-specular-fragment-OBO-zxGh.js} +2 -2
- package/{std-specular-fragment-CaBXyAWY.js.map → std-specular-fragment-OBO-zxGh.js.map} +1 -1
- package/{std-tracking-Bw61Dv98.js → std-tracking-4SHTntWt.js} +2 -2
- package/{std-tracking-Bw61Dv98.js.map → std-tracking-4SHTntWt.js.map} +1 -1
- package/{subsurface-fragment-BNQoG9gr.js → subsurface-fragment-D7QRWN_d.js} +2 -2
- package/{subsurface-fragment-BNQoG9gr.js.map → subsurface-fragment-D7QRWN_d.js.map} +1 -1
- package/{thin-instance-cull-binding-BNC5JiGw.js → thin-instance-cull-binding-D-p2Yxfg.js} +3 -3
- package/{thin-instance-cull-binding-BNC5JiGw.js.map → thin-instance-cull-binding-D-p2Yxfg.js.map} +1 -1
- package/{thin-instance-gpu-C1DGstap.js → thin-instance-gpu-QETC_NyQ.js} +2 -2
- package/{thin-instance-gpu-C1DGstap.js.map → thin-instance-gpu-QETC_NyQ.js.map} +1 -1
- package/{tracking-primitives-CMBWLxGr.js → tracking-primitives-CqIIi7Ej.js} +2 -2
- package/{tracking-primitives-CMBWLxGr.js.map → tracking-primitives-CqIIi7Ej.js.map} +1 -1
- package/{unlit-fragment-BsHrS9XX.js → unlit-fragment-DPWDQLxo.js} +2 -2
- package/{unlit-fragment-BsHrS9XX.js.map → unlit-fragment-DPWDQLxo.js.map} +1 -1
- package/gltf-animation-BjnXkop6.js.map +0 -1
- package/gltf-feature-animation-pointer-C40tqOhL.js +0 -88
- package/gltf-feature-animation-pointer-C40tqOhL.js.map +0 -1
- package/gltf-feature-draco-CljWrsna.js +0 -125
- package/gltf-feature-draco-CljWrsna.js.map +0 -1
- package/gltf-feature-meshopt-DItMkOMt.js.map +0 -1
- package/gltf-feature-skeleton-Deh2UBAn.js.map +0 -1
- package/gltf-interleave-OBqmlu-h.js.map +0 -1
- package/index-BgY3QEzL.js.map +0 -1
- package/pbr-geometry-view-Dthf9Aut.js.map +0 -1
- package/pbr-renderable-CuKWalEM.js.map +0 -1
- package/shader-composer-CBy2i8nU.js +0 -293
- package/shader-composer-CBy2i8nU.js.map +0 -1
- package/shader-renderable-DVMVD6zP.js.map +0 -1
- package/standard-pipeline-DXFOUqU_.js +0 -391
- package/standard-pipeline-DXFOUqU_.js.map +0 -1
- package/standard-renderable-BAc-i-ig.js.map +0 -1
- package/wgsl-helpers-D8sl1VVA.js +0 -48
- package/wgsl-helpers-D8sl1VVA.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as resolveAccessor } from "./index-
|
|
1
|
+
import { br as _boneBuilder, r as resolveAccessor } from "./index-C2sM8ERH.js";
|
|
2
2
|
function resolveAttr(name, primitive, decoded, json, binChunk) {
|
|
3
3
|
var _a;
|
|
4
4
|
if (decoded && decoded._attributes.has(name)) {
|
|
@@ -24,13 +24,22 @@ const feature = {
|
|
|
24
24
|
}
|
|
25
25
|
const joints1 = resolveAttr("JOINTS_1", primitive, decoded, json, binChunk);
|
|
26
26
|
const weights1 = resolveAttr("WEIGHTS_1", primitive, decoded, json, binChunk);
|
|
27
|
-
const [{ extractSkin, computeBoneTextureData }, { createSkeleton }] = await Promise.all([import("./gltf-animation-
|
|
27
|
+
const [{ extractSkin, computeBoneTextureData }, { createSkeleton }] = await Promise.all([import("./gltf-animation-Db8PwXmY.js"), import("./create-skeleton-41NqPV9u.js")]);
|
|
28
28
|
const skin = extractSkin(json, binChunk, node.skin, meshData._worldMatrix, parentMap, worldMatrixCache);
|
|
29
29
|
const boneData = computeBoneTextureData(skin);
|
|
30
30
|
mesh.skeleton = createSkeleton(ctx._engine, joints, weights, skin.jointNodes.length, boneData, joints1, weights1);
|
|
31
|
+
if (_boneBuilder && !ctx._boneOverrides) {
|
|
32
|
+
ctx._boneOverrides = /* @__PURE__ */ new Map();
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async applyAsset(meshes, _root, ctx) {
|
|
36
|
+
if (!_boneBuilder || !ctx._boneOverrides) {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
return _boneBuilder(ctx, meshes, ctx._boneOverrides);
|
|
31
40
|
}
|
|
32
41
|
};
|
|
33
42
|
export {
|
|
34
43
|
feature as default
|
|
35
44
|
};
|
|
36
|
-
//# sourceMappingURL=gltf-feature-skeleton-
|
|
45
|
+
//# sourceMappingURL=gltf-feature-skeleton-IHj-DuKx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-feature-skeleton-IHj-DuKx.js","sources":["../src/loader-gltf/gltf-feature-skeleton.ts"],"sourcesContent":["/** Skeletal animation feature. Extracts joints/weights/skin on demand so the\n * core loader doesn't carry any skinning-related code for non-skinned assets. */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { _boneBuilder } from \"../skeleton/bone-control-hooks.js\";\n\n/** Resolve a vertex attribute by name, preferring any pre-decoded\n * (e.g. Draco) data over the raw accessor. */\nfunction resolveAttr(name: string, primitive: any, decoded: any, json: any, binChunk: DataView): ArrayBufferView | null {\n if (decoded && decoded._attributes.has(name)) {\n return decoded._attributes.get(name)!;\n }\n const idx = primitive.attributes?.[name];\n return idx !== undefined ? (resolveAccessor(json, binChunk, idx)._data as ArrayBufferView) : null;\n}\n\nconst feature: GltfFeature = {\n id: \"_skeleton\",\n async applyMesh(meshData, mesh, ctx) {\n const { _json: json, _binChunk: binChunk, _parentMap: parentMap, _worldMatrixCache: worldMatrixCache } = ctx;\n const node = json.nodes[meshData._nodeIndex];\n if (node.skin === undefined || !json.skins) {\n return;\n }\n const primitive = meshData._primitive;\n const decoded = meshData._decoded;\n const joints = resolveAttr(\"JOINTS_0\", primitive, decoded, json, binChunk) as Uint16Array | Uint8Array | null;\n const weights = resolveAttr(\"WEIGHTS_0\", primitive, decoded, json, binChunk) as Float32Array | null;\n if (!joints || !weights) {\n return;\n }\n const joints1 = resolveAttr(\"JOINTS_1\", primitive, decoded, json, binChunk) as Uint16Array | Uint8Array | null;\n const weights1 = resolveAttr(\"WEIGHTS_1\", primitive, decoded, json, binChunk) as Float32Array | null;\n\n const [{ extractSkin, computeBoneTextureData }, { createSkeleton }] = await Promise.all([import(\"./gltf-animation.js\"), import(\"../skeleton/create-skeleton.js\")]);\n const skin = extractSkin(json, binChunk, node.skin, meshData._worldMatrix, parentMap, worldMatrixCache);\n const boneData = computeBoneTextureData(skin);\n mesh.skeleton = createSkeleton(ctx._engine, joints, weights, skin.jointNodes.length, boneData, joints1, weights1);\n\n // When bone control is enabled, lazily create the asset-wide override map\n // here (per-mesh hook runs before any per-asset hook) so the animation feature\n // and the bone-control builder share the same map race-free.\n if (_boneBuilder && !ctx._boneOverrides) {\n ctx._boneOverrides = new Map();\n }\n },\n async applyAsset(meshes, _root, ctx) {\n // Bone control is opt-in: with the builder hook absent (default), no public\n // skeleton handles are built and `container.skeletons` stays undefined — the\n // whole bone-control implementation tree-shakes away.\n if (!_boneBuilder || !ctx._boneOverrides) {\n return {};\n }\n return _boneBuilder(ctx, meshes, ctx._boneOverrides);\n },\n};\nexport default feature;\n"],"names":[],"mappings":";AASA,SAAS,YAAY,MAAc,WAAgB,SAAc,MAAW,UAA4C;;AACpH,MAAI,WAAW,QAAQ,YAAY,IAAI,IAAI,GAAG;AAC1C,WAAO,QAAQ,YAAY,IAAI,IAAI;AAAA,EACvC;AACA,QAAM,OAAM,eAAU,eAAV,mBAAuB;AACnC,SAAO,QAAQ,SAAa,gBAAgB,MAAM,UAAU,GAAG,EAAE,QAA4B;AACjG;AAEA,MAAM,UAAuB;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM,UAAU,UAAU,MAAM,KAAK;AACjC,UAAM,EAAE,OAAO,MAAM,WAAW,UAAU,YAAY,WAAW,mBAAmB,iBAAA,IAAqB;AACzG,UAAM,OAAO,KAAK,MAAM,SAAS,UAAU;AAC3C,QAAI,KAAK,SAAS,UAAa,CAAC,KAAK,OAAO;AACxC;AAAA,IACJ;AACA,UAAM,YAAY,SAAS;AAC3B,UAAM,UAAU,SAAS;AACzB,UAAM,SAAS,YAAY,YAAY,WAAW,SAAS,MAAM,QAAQ;AACzE,UAAM,UAAU,YAAY,aAAa,WAAW,SAAS,MAAM,QAAQ;AAC3E,QAAI,CAAC,UAAU,CAAC,SAAS;AACrB;AAAA,IACJ;AACA,UAAM,UAAU,YAAY,YAAY,WAAW,SAAS,MAAM,QAAQ;AAC1E,UAAM,WAAW,YAAY,aAAa,WAAW,SAAS,MAAM,QAAQ;AAE5E,UAAM,CAAC,EAAE,aAAa,0BAA0B,EAAE,gBAAgB,IAAI,MAAM,QAAQ,IAAI,CAAC,OAAO,8BAAqB,GAAG,OAAO,+BAAgC,CAAC,CAAC;AACjK,UAAM,OAAO,YAAY,MAAM,UAAU,KAAK,MAAM,SAAS,cAAc,WAAW,gBAAgB;AACtG,UAAM,WAAW,uBAAuB,IAAI;AAC5C,SAAK,WAAW,eAAe,IAAI,SAAS,QAAQ,SAAS,KAAK,WAAW,QAAQ,UAAU,SAAS,QAAQ;AAKhH,QAAI,gBAAgB,CAAC,IAAI,gBAAgB;AACrC,UAAI,qCAAqB,IAAA;AAAA,IAC7B;AAAA,EACJ;AAAA,EACA,MAAM,WAAW,QAAQ,OAAO,KAAK;AAIjC,QAAI,CAAC,gBAAgB,CAAC,IAAI,gBAAgB;AACtC,aAAO,CAAA;AAAA,IACX;AACA,WAAO,aAAa,KAAK,QAAQ,IAAI,cAAc;AAAA,EACvD;AACJ;"}
|
|
@@ -6,7 +6,7 @@ const feature = {
|
|
|
6
6
|
if (!(variantNames == null ? void 0 : variantNames.length)) {
|
|
7
7
|
return {};
|
|
8
8
|
}
|
|
9
|
-
const { loadVariantMaterials } = await import("./gltf-variants-
|
|
9
|
+
const { loadVariantMaterials } = await import("./gltf-variants-C0HetOre.js");
|
|
10
10
|
const materialVariants = await loadVariantMaterials(ctx._json, ctx._binChunk, ctx._baseUrl, variantNames, meshes, ctx._engine, ctx._matExts, ctx._wrapTex);
|
|
11
11
|
return { materialVariants };
|
|
12
12
|
}
|
|
@@ -14,4 +14,4 @@ const feature = {
|
|
|
14
14
|
export {
|
|
15
15
|
feature as default
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=gltf-feature-variants-
|
|
17
|
+
//# sourceMappingURL=gltf-feature-variants-C-eyBru5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-feature-variants-
|
|
1
|
+
{"version":3,"file":"gltf-feature-variants-C-eyBru5.js","sources":["../src/loader-gltf/gltf-feature-variants.ts"],"sourcesContent":["/** KHR_materials_variants feature.\n * Triggered when the root extension carries variant definitions. Per-asset\n * hook builds variant material data shared with the material-ext driver. */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\n\nconst feature: GltfFeature = {\n id: \"KHR_materials_variants\",\n async applyAsset(meshes, _root, ctx) {\n const variantNames: string[] | undefined = ctx._json.extensions?.KHR_materials_variants?.variants?.map((v: { name: string }) => v.name);\n if (!variantNames?.length) {\n return {};\n }\n const { loadVariantMaterials } = await import(\"./gltf-variants.js\");\n const materialVariants = await loadVariantMaterials(ctx._json, ctx._binChunk, ctx._baseUrl, variantNames, meshes, ctx._engine, ctx._matExts, ctx._wrapTex);\n return { materialVariants };\n },\n};\nexport default feature;\n"],"names":[],"mappings":"AAMA,MAAM,UAAuB;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM,WAAW,QAAQ,OAAO,KAAK;AAFzC;AAGQ,UAAM,gBAAqC,qBAAI,MAAM,eAAV,mBAAsB,2BAAtB,mBAA8C,aAA9C,mBAAwD,IAAI,CAAC,MAAwB,EAAE;AAClI,QAAI,EAAC,6CAAc,SAAQ;AACvB,aAAO,CAAA;AAAA,IACX;AACA,UAAM,EAAE,qBAAA,IAAyB,MAAM,OAAO,6BAAoB;AAClE,UAAM,mBAAmB,MAAM,qBAAqB,IAAI,OAAO,IAAI,WAAW,IAAI,UAAU,cAAc,QAAQ,IAAI,SAAS,IAAI,UAAU,IAAI,QAAQ;AACzJ,WAAO,EAAE,iBAAA;AAAA,EACb;AACJ;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as DV, e as U8 } from "./index-
|
|
1
|
+
import { D as DV, e as U8 } from "./index-C2sM8ERH.js";
|
|
2
2
|
function parseGlbContainer(buffer) {
|
|
3
3
|
const view = new DV(buffer);
|
|
4
4
|
const magic = view.getUint32(0, true);
|
|
@@ -25,4 +25,4 @@ function parseGlbContainer(buffer) {
|
|
|
25
25
|
export {
|
|
26
26
|
parseGlbContainer
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=gltf-glb-parser-
|
|
28
|
+
//# sourceMappingURL=gltf-glb-parser-DXMAJA8e.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-glb-parser-
|
|
1
|
+
{"version":3,"file":"gltf-glb-parser-DXMAJA8e.js","sources":["../src/loader-gltf/gltf-glb-parser.ts"],"sourcesContent":["import { U8, DV } from \"../engine/typed-arrays.js\";\n/** GLB binary container parsing. Kept separate so .gltf-only scenes do not ship it. */\n\nexport function parseGlbContainer(buffer: ArrayBuffer): { json: any; binChunk: DataView } {\n const view = new DV(buffer);\n\n // Header (12 bytes)\n const magic = view.getUint32(0, true);\n if (magic !== 0x46546c67) {\n throw new Error(\"Not a valid GLB file\");\n }\n // const version = view.getUint32(4, true);\n // const totalLength = view.getUint32(8, true);\n\n // JSON chunk\n let offset = 12;\n const jsonLength = view.getUint32(offset, true);\n const jsonType = view.getUint32(offset + 4, true);\n if (jsonType !== 0x4e4f534a) {\n throw new Error(\"First GLB chunk is not JSON\");\n }\n const jsonStr = new TextDecoder().decode(new U8(buffer, offset + 8, jsonLength));\n const json = JSON.parse(jsonStr);\n offset += 8 + jsonLength;\n\n // BIN chunk\n const binLength = view.getUint32(offset, true);\n const binType = view.getUint32(offset + 4, true);\n if (binType !== 0x004e4942) {\n throw new Error(\"Second GLB chunk is not BIN\");\n }\n const binChunk = new DV(buffer, offset + 8, binLength);\n\n return { json, binChunk };\n}\n"],"names":[],"mappings":";AAGO,SAAS,kBAAkB,QAAwD;AACtF,QAAM,OAAO,IAAI,GAAG,MAAM;AAG1B,QAAM,QAAQ,KAAK,UAAU,GAAG,IAAI;AACpC,MAAI,UAAU,YAAY;AACtB,UAAM,IAAI,MAAM,sBAAsB;AAAA,EAC1C;AAKA,MAAI,SAAS;AACb,QAAM,aAAa,KAAK,UAAU,QAAQ,IAAI;AAC9C,QAAM,WAAW,KAAK,UAAU,SAAS,GAAG,IAAI;AAChD,MAAI,aAAa,YAAY;AACzB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EACjD;AACA,QAAM,UAAU,IAAI,YAAA,EAAc,OAAO,IAAI,GAAG,QAAQ,SAAS,GAAG,UAAU,CAAC;AAC/E,QAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,YAAU,IAAI;AAGd,QAAM,YAAY,KAAK,UAAU,QAAQ,IAAI;AAC7C,QAAM,UAAU,KAAK,UAAU,SAAS,GAAG,IAAI;AAC/C,MAAI,YAAY,SAAY;AACxB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EACjD;AACA,QAAM,WAAW,IAAI,GAAG,QAAQ,SAAS,GAAG,SAAS;AAErD,SAAO,EAAE,MAAM,SAAA;AACnB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as TYPE_SIZES, h as computeAabb, i as initMeshTransform, U as U32, a as F32, r as resolveAccessor, e as U8, j as U16, D as DV, k as createMappedBuffer, B as BU } from "./index-
|
|
1
|
+
import { g as TYPE_SIZES, h as computeAabb, i as initMeshTransform, U as U32, a as F32, r as resolveAccessor, e as U8, j as U16, D as DV, k as createMappedBuffer, B as BU } from "./index-C2sM8ERH.js";
|
|
2
2
|
const FLOAT = 5126;
|
|
3
3
|
const UNSIGNED_SHORT = 5123;
|
|
4
4
|
const UNSIGNED_INT = 5125;
|
|
@@ -120,7 +120,6 @@ function buildInterleavedPartial(json, binChunk, primitive, worldMatrix, nodeIdx
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
function buildInterleavedGpu(engine, m) {
|
|
123
|
-
var _a, _b, _c, _d;
|
|
124
123
|
const vbsrc = m._vb;
|
|
125
124
|
const shared = /* @__PURE__ */ new Map();
|
|
126
125
|
const vbuf = (a, tight) => {
|
|
@@ -133,6 +132,7 @@ function buildInterleavedGpu(engine, m) {
|
|
|
133
132
|
}
|
|
134
133
|
return b;
|
|
135
134
|
};
|
|
135
|
+
const k = (a) => `${(a == null ? void 0 : a._stride) ?? 0},${(a == null ? void 0 : a._offset) ?? 0}`;
|
|
136
136
|
return {
|
|
137
137
|
positionBuffer: vbuf(vbsrc._p, m._positions),
|
|
138
138
|
normalBuffer: vbuf(vbsrc._n, m._normals),
|
|
@@ -144,7 +144,7 @@ function buildInterleavedGpu(engine, m) {
|
|
|
144
144
|
indexCount: m._indexCount,
|
|
145
145
|
indexFormat: m._indices instanceof U32 ? "uint32" : "uint16",
|
|
146
146
|
_vbLayout: vbsrc,
|
|
147
|
-
_vbKey: `vb${(
|
|
147
|
+
_vbKey: `vb${k(vbsrc._p)}.${k(vbsrc._n)}.${k(vbsrc._t)}.${k(vbsrc._u)}`
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
function buildInterleavedMesh(engine, m, index, material) {
|
|
@@ -244,4 +244,4 @@ export {
|
|
|
244
244
|
computeAabbStrided,
|
|
245
245
|
installLazyCpu
|
|
246
246
|
};
|
|
247
|
-
//# sourceMappingURL=gltf-interleave-
|
|
247
|
+
//# sourceMappingURL=gltf-interleave-BdKrRH3j.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gltf-interleave-BdKrRH3j.js","sources":["../src/loader-gltf/gltf-interleave.ts"],"sourcesContent":["/**\n * Interleaved (strided) glTF vertex-buffer support — dynamically imported.\n *\n * The engine renders interleaved attributes genuinely: the raw strided\n * bufferView slice is uploaded ONCE as a shared GPU buffer, bound to each\n * attribute slot at byte offset 0, with the per-attribute byte offset encoded in\n * the pipeline vertex layout (`attributes[].offset`) and `arrayStride` set to the\n * bufferView byteStride. This mirrors stock Babylon.js's WebGPU vertex state and\n * avoids a non-zero `setVertexBuffer` bind offset, which corrupts vertex fetch on\n * some AMD (Renoir) / Dawn paths. The loader never rewrites the asset.\n *\n * This whole module is loaded via `await import()` only when an asset actually\n * contains an interleaved bufferView, so non-interleaved scenes pay ZERO bundle\n * cost. The tight CPU copy of position/normal/uv (for AABB, picking, CSG, …) is\n * de-strided LAZILY — only on first CPU read via `installLazyCpu` — so scenes\n * that only render never materialize it.\n */\n\nimport { F32, U32, U16, U8, DV } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport type { Aabb } from \"../math/aabb.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Mesh, MeshGPU } from \"../mesh/mesh.js\";\nimport { initMeshTransform } from \"../mesh/mesh.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport { createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport { resolveAccessor, TYPE_SIZES } from \"./gltf-parser.js\";\nimport type { GltfMeshData } from \"./load-gltf.js\";\n\nconst FLOAT = 5126;\nconst UNSIGNED_SHORT = 5123;\nconst UNSIGNED_INT = 5125;\nconst UNSIGNED_BYTE = 5121;\n\nconst COMP_BYTES: Record<number, number> = { [UNSIGNED_BYTE]: 1, [UNSIGNED_SHORT]: 2, [UNSIGNED_INT]: 4, [FLOAT]: 4 };\n\nfunction createSequentialIndices(vertexCount: number): Uint16Array | Uint32Array {\n const indices = vertexCount > 0xffff ? new U32(vertexCount) : new U16(vertexCount);\n for (let i = 0; i < vertexCount; i++) {\n indices[i] = i;\n }\n return indices;\n}\n\n/** Interleave descriptor for one attribute sourced from a strided bufferView.\n * The raw slice is shared across attributes of the same bufferView; the\n * pipeline uses `_stride` as arrayStride and binds at `_offset`. */\nexport interface AccessorInterleave {\n /** @internal glTF bufferView index — shared-buffer key (same view → one GPU buffer). */\n _bufferView: number;\n /** @internal Interleave byte stride (bufferView.byteStride) → pipeline arrayStride. */\n _stride: number;\n /** @internal Attribute byte offset within the bufferView → pipeline vertex layout\n * `attributes[].offset` (the shared buffer is bound at offset 0). */\n _offset: number;\n /** @internal glTF component type (FLOAT, UNSIGNED_SHORT, …). */\n _componentType: number;\n /** @internal Components per vertex. */\n _componentCount: number;\n /** @internal Vertex count. */\n _count: number;\n /** @internal Raw bufferView bytes (shared across attributes). Retained after GPU upload\n * so the CPU copy can be de-strided lazily on demand. */\n _slice?: Uint8Array;\n}\n\n/** Per-attribute interleave sources for a primitive (keys mirror MeshVbLayout). */\nexport interface GltfVb {\n /** @internal */\n _p?: AccessorInterleave;\n /** @internal */\n _n?: AccessorInterleave;\n /** @internal */\n _t?: AccessorInterleave;\n /** @internal */\n _u?: AccessorInterleave;\n /** @internal */\n _u2?: AccessorInterleave;\n /** @internal */\n _c?: AccessorInterleave;\n}\n\n/** True if accessor `idx`'s bufferView is interleaved (byteStride present and\n * larger than the attribute's tightly-packed element size). */\nexport function accessorIsStrided(json: any, idx: number): boolean {\n const a = json.accessors[idx];\n const bv = json.bufferViews[a.bufferView];\n const stride: number | undefined = bv.byteStride;\n if (stride === undefined) {\n return false;\n }\n const elemBytes = (TYPE_SIZES[a.type] ?? 1) * (COMP_BYTES[a.componentType] ?? 4);\n return stride !== elemBytes;\n}\n\n/** Resolve a strided accessor into an {@link AccessorInterleave} descriptor. */\nfunction resolveStrided(json: any, binChunk: DataView, accessorIdx: number): AccessorInterleave {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n const ab = binChunk.buffer as ArrayBuffer;\n return {\n _bufferView: accessor.bufferView,\n _stride: bufferView.byteStride,\n _offset: accessor.byteOffset ?? 0,\n _componentType: accessor.componentType,\n _componentCount: TYPE_SIZES[accessor.type] ?? 1,\n _count: accessor.count,\n _slice: new U8(ab, binChunk.byteOffset + (bufferView.byteOffset ?? 0), bufferView.byteLength),\n };\n}\n\n/** De-stride an interleaved attribute into a tight Float32Array, reading raw\n * component values (no normalization) so the result matches what a tight\n * accessor view would have produced. */\nfunction destrideToTight(il: AccessorInterleave): Float32Array {\n const dv = new DV(il._slice!.buffer, il._slice!.byteOffset, il._slice!.byteLength);\n const cb = COMP_BYTES[il._componentType] ?? 4;\n const ct = il._componentType;\n const cc = il._componentCount;\n const out = new F32(il._count * cc);\n for (let v = 0; v < il._count; v++) {\n const rowBase = il._offset + v * il._stride;\n for (let c = 0; c < cc; c++) {\n const off = rowBase + c * cb;\n out[v * cc + c] =\n ct === FLOAT ? dv.getFloat32(off, true) : ct === UNSIGNED_SHORT ? dv.getUint16(off, true) : ct === UNSIGNED_INT ? dv.getUint32(off, true) : dv.getUint8(off);\n }\n }\n return out;\n}\n\n/** Build a mesh-data partial for a primitive, but ONLY if it actually sources\n * ≥1 attribute from an interleaved (strided) bufferView. Returns `undefined`\n * for fully-tight primitives so the caller falls back to its tight path.\n *\n * Strided POSITION/NORMAL/TEXCOORD_0 attributes keep their raw slice in `_vb`\n * (for genuine GPU interleaving) and leave the tight CPU field `null` — the\n * de-strided copy is materialized lazily on first CPU read (see\n * {@link installLazyCpu}). Strided TANGENT/TEXCOORD_1/COLOR are eagerly\n * de-strided (they feed device-lost recovery), but no current asset interleaves\n * them. Tight attributes resolve exactly like the core loader. */\nexport function buildInterleavedPartial(json: any, binChunk: DataView, primitive: any, worldMatrix: Mat4, nodeIdx: number): Omit<GltfMeshData, \"_material\"> | undefined {\n const attrs = primitive.attributes;\n\n // Per-primitive gate: bail (→ tight path) unless a vertex attribute is strided.\n let anyStrided = false;\n for (const name in attrs) {\n if (accessorIsStrided(json, attrs[name])) {\n anyStrided = true;\n break;\n }\n }\n if (!anyStrided) {\n return undefined;\n }\n\n const vb: GltfVb = {};\n let vertexCount = 0;\n\n // Resolve one attribute. Returns the interleave descriptor (when the source is\n // strided) and/or a tight CPU array. `eager` de-strides strided sources up-front\n // (TANGENT/UV2/COLOR feed device-lost recovery); lazy ones leave `_tight` null and\n // are de-strided on demand. The caller assigns `vb.<attr>` with a STATIC property\n // name (never a computed `vb[key]`) — a computed write would stay an unmangled\n // literal while every reader uses the mangled static name, corrupting the object\n // across the dynamic-import chunk boundary.\n const resolveOne = (name: string, eager: boolean): { _tight: Float32Array | null; _il?: AccessorInterleave; _count: number } => {\n const idx = attrs[name];\n if (idx === undefined) {\n return { _tight: null, _count: 0 };\n }\n if (accessorIsStrided(json, idx)) {\n const il = resolveStrided(json, binChunk, idx);\n return { _tight: eager ? destrideToTight(il) : null, _il: il, _count: il._count };\n }\n const av = resolveAccessor(json, binChunk, idx);\n return { _tight: av._data as Float32Array, _count: av._count };\n };\n\n const pos = resolveOne(\"POSITION\", false);\n vb._p = pos._il;\n vertexCount = pos._count;\n const nrm = resolveOne(\"NORMAL\", false);\n vb._n = nrm._il;\n const uv = resolveOne(\"TEXCOORD_0\", false);\n vb._u = uv._il;\n const tan = resolveOne(\"TANGENT\", true);\n vb._t = tan._il;\n const uv2 = resolveOne(\"TEXCOORD_1\", true);\n vb._u2 = uv2._il;\n const col = resolveOne(\"COLOR_0\", true);\n vb._c = col._il;\n\n const positions = pos._tight;\n let normals = nrm._tight;\n let uvs = uv._tight;\n const tangents = tan._tight;\n const uv2s = uv2._tight;\n const colors = col._tight;\n\n // Absent (not merely strided) NORMAL/UV need a tight zero-filled buffer so the\n // GPU has a bindable vertex buffer — matches the core loader's tight path.\n if (!normals && !vb._n) {\n normals = new F32(vertexCount * 3);\n }\n if (!uvs && !vb._u) {\n uvs = new F32(vertexCount * 2);\n }\n\n const idxData = primitive.indices !== undefined ? resolveAccessor(json, binChunk, primitive.indices) : null;\n const indices = idxData\n ? idxData._data instanceof U32\n ? new U32(idxData._data)\n : idxData._data instanceof U8\n ? Uint16Array.from(idxData._data)\n : new U16(idxData._data.buffer, idxData._data.byteOffset, idxData._count)\n : createSequentialIndices(vertexCount);\n\n return {\n _positions: positions,\n _normals: normals,\n _tangents: tangents,\n _uvs: uvs,\n _uv2s: uv2s,\n _colors: colors,\n _indices: indices,\n _vertexCount: vertexCount,\n _indexCount: indices.length,\n _worldMatrix: worldMatrix,\n _vb: vb,\n _nodeIndex: nodeIdx,\n _primitive: primitive,\n };\n}\n\n/** Build the GPU geometry for an interleaved mesh: one shared buffer per\n * bufferView for strided attributes (bound at offset 0; the per-attribute byte\n * offset goes into the pipeline vertex layout, matching stock Babylon.js), tight\n * attributes get their own buffer — byte-identical to non-interleaved meshes.\n * The raw `_slice` is intentionally retained on `_vb` so the CPU copy can be\n * de-strided lazily later (see {@link installLazyCpu}). */\nfunction buildInterleavedGpu(engine: EngineContext, m: GltfMeshData): MeshGPU {\n const vbsrc = m._vb!;\n const shared = new Map<number, GPUBuffer>();\n const vbuf = (a: AccessorInterleave | undefined, tight: Float32Array | null): GPUBuffer | null => {\n if (!a) {\n return tight ? createMappedBuffer(engine, tight, BU.VERTEX) : null;\n }\n let b = shared.get(a._bufferView);\n if (!b) {\n shared.set(a._bufferView, (b = createMappedBuffer(engine, a._slice!, BU.VERTEX)));\n }\n return b;\n };\n // Cache key encodes both stride AND byte offset per attribute: the offsets are\n // now baked into the pipeline vertex layout (attributes[].offset), so two meshes\n // with identical strides but different offsets need distinct pipelines.\n const k = (a: AccessorInterleave | undefined) => `${a?._stride ?? 0},${a?._offset ?? 0}`;\n return {\n positionBuffer: vbuf(vbsrc._p, m._positions)!,\n normalBuffer: vbuf(vbsrc._n, m._normals)!,\n tangentBuffer: m._tangents ? vbuf(vbsrc._t, m._tangents) : null,\n uvBuffer: vbuf(vbsrc._u, m._uvs)!,\n uv2Buffer: m._uv2s ? vbuf(vbsrc._u2, m._uv2s) : null,\n colorBuffer: m._colors ? vbuf(vbsrc._c, m._colors) : null,\n indexBuffer: createMappedBuffer(engine, m._indices, BU.INDEX),\n indexCount: m._indexCount,\n indexFormat: (m._indices instanceof U32 ? \"uint32\" : \"uint16\") as GPUIndexFormat,\n _vbLayout: vbsrc,\n _vbKey: `vb${k(vbsrc._p)}.${k(vbsrc._n)}.${k(vbsrc._t)}.${k(vbsrc._u)}`,\n };\n}\n\n/** Build a complete engine mesh from interleaved glTF mesh-data. Owns ALL\n * interleave-specific work (GPU upload, AABB fold, lazy CPU install, device-lost\n * retention) so the core loader's tight path stays byte-identical to the\n * non-interleaved engine — keeping interleave bytes out of every glTF scene that\n * doesn't use it. */\nexport function buildInterleavedMesh(engine: EngineContext, m: GltfMeshData, index: number, material: PbrMaterialProps): Mesh {\n const gpu = buildInterleavedGpu(engine, m);\n\n // AABB: fold strided positions straight from the slice; tight positions normally.\n const [boundMin, boundMax] = m._vb!._p ? computeAabbStrided(m._vb!._p, m._worldMatrix) : computeAabb(m._positions!, m._worldMatrix);\n\n const mesh = {\n name: `gltf_mesh_${index}`,\n material,\n receiveShadows: false,\n boundMin,\n boundMax,\n skeleton: null,\n morphTargets: null,\n _gpu: gpu,\n } as unknown as Mesh;\n initMeshTransform(mesh);\n\n // Lazy CPU geometry: the de-strided tight copy is built only on first read.\n installLazyCpu(mesh, m);\n mesh._cpuIndices = m._indices instanceof U32 ? m._indices : new U32(m._indices);\n engine._dlr?.m(mesh, m._uv2s, m._tangents, m._colors, m._indices, gpu.indexFormat);\n\n return mesh as Mesh;\n}\n\n/** Fold an AABB directly over an interleaved (strided) FLOAT vec3 position\n * source — no tight copy is materialized. Mirrors {@link computeAabb}'s\n * world-transform handling. All current interleaved assets use FLOAT positions. */\nexport function computeAabbStrided(il: AccessorInterleave, world?: Mat4): Aabb {\n const dv = new DV(il._slice!.buffer, il._slice!.byteOffset, il._slice!.byteLength);\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n for (let v = 0; v < il._count; v++) {\n const base = il._offset + v * il._stride;\n const lx = dv.getFloat32(base, true);\n const ly = dv.getFloat32(base + 4, true);\n const lz = dv.getFloat32(base + 8, true);\n let x = lx,\n y = ly,\n z = lz;\n if (world) {\n x = world[0]! * lx + world[4]! * ly + world[8]! * lz + world[12]!;\n y = world[1]! * lx + world[5]! * ly + world[9]! * lz + world[13]!;\n z = world[2]! * lx + world[6]! * ly + world[10]! * lz + world[14]!;\n }\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 return [\n [minX, minY, minZ],\n [maxX, maxY, maxZ],\n ];\n}\n\n/** Install lazy CPU-geometry accessors on an interleaved mesh. Each of\n * `_cpuPositions/_cpuNormals/_cpuUvs` that comes from a strided source is\n * defined as a getter that de-strides a tight copy on first access and caches\n * it; tight attributes are assigned directly. A mesh that is never picked /\n * CSG'd / navigated never materializes the de-strided arrays.\n *\n * The property names are written as STATIC literals (not a computed key) so the\n * minifier mangles them identically to the static reads in the picking /\n * device-lost code — a computed `defineProperty(mesh, key)` would leave the name\n * an unmangled literal and mismatch those reads across the chunk boundary. */\nexport function installLazyCpu(mesh: any, m: GltfMeshData): void {\n const vb = m._vb!;\n if (vb._p) {\n Object.defineProperty(mesh, \"_cpuPositions\", lazyCpuDesc(vb._p));\n } else if (m._positions) {\n mesh._cpuPositions = m._positions;\n }\n if (vb._n) {\n Object.defineProperty(mesh, \"_cpuNormals\", lazyCpuDesc(vb._n));\n } else if (m._normals) {\n mesh._cpuNormals = m._normals;\n }\n if (vb._u) {\n Object.defineProperty(mesh, \"_cpuUvs\", lazyCpuDesc(vb._u));\n } else if (m._uvs) {\n mesh._cpuUvs = m._uvs;\n }\n}\n\n/** Build a caching lazy-getter descriptor that de-strides `il` on first read. */\nfunction lazyCpuDesc(il: AccessorInterleave): PropertyDescriptor {\n let cached: Float32Array | undefined;\n return {\n configurable: true,\n enumerable: true,\n get(): Float32Array {\n return (cached ??= destrideToTight(il));\n },\n set(v: Float32Array): void {\n cached = v;\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as pbrGroupBuilder, u as uploadTex, e as U8, q as linearToSrgbByte, s as cloneTexture2D } from "./index-C2sM8ERH.js";
|
|
2
2
|
function wrapTexCoord(tex, texInfo) {
|
|
3
3
|
var _a, _b;
|
|
4
4
|
if (!texInfo) {
|
|
@@ -82,4 +82,4 @@ export {
|
|
|
82
82
|
assemblePbrPropsExt,
|
|
83
83
|
buildDefaultPbrTexturesExt
|
|
84
84
|
};
|
|
85
|
-
//# sourceMappingURL=gltf-pbr-builder-ext-
|
|
85
|
+
//# sourceMappingURL=gltf-pbr-builder-ext-DJ8Jm7jo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-pbr-builder-ext-3imk8Tev.js","sources":["../src/loader-gltf/gltf-pbr-builder-ext.ts"],"sourcesContent":["/** Lazy-loaded slow path for PBR material assembly.\n * Only pulled into bundles whose glTF uses features that require per-texture\n * wrapping (e.g. KHR_texture_transform) or occlusion on UV2 (texCoord=1 with\n * no shared MR image). Scene1 (BoomBox) and any vanilla-PBR glTF skip this\n * module entirely. */\n\nimport { U8 } from \"../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { cloneTexture2D } from \"../texture/texture-2d.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport { pbrGroupBuilder } from \"../material/pbr/pbr-material.js\";\nimport type { GltfMaterialData } from \"./gltf-material.js\";\nimport { linearToSrgbByte } from \"../math/color.js\";\nimport type { TextureWrapFn, GenerateMipmapsFn } from \"./gltf-pbr-builder.js\";\nimport { uploadTex } from \"./gltf-pbr-builder.js\";\n\nexport interface PbrTexturesExt {\n baseColorTexture: Texture2D;\n ormTexture: Texture2D;\n normalTexture: Texture2D | undefined;\n emissiveTexture: Texture2D | undefined;\n occlusionTexture: Texture2D | undefined;\n}\n\n/** Stamp `_texCoord=1` on a clone when textureInfo selects UV1 and the\n * wrapTex layer didn't already set it (i.e. scene has no KHR_texture_transform). */\nfunction wrapTexCoord(tex: Texture2D, texInfo: unknown): Texture2D {\n if (!texInfo) {\n return tex;\n }\n if ((tex as { _texCoord?: 0 | 1 })._texCoord === 1) {\n return tex;\n }\n const ti = texInfo as { texCoord?: number; extensions?: { KHR_texture_transform?: { texCoord?: number } } };\n const tc = ti.extensions?.KHR_texture_transform?.texCoord ?? ti.texCoord;\n return tc === 1 ? cloneTexture2D(tex, { _texCoord: 1 }) : tex;\n}\n\n/** Build textures with wrapTex + occlusionOnUv2 support. Mirrors master's\n * default texture building but honors per-textureInfo wrapping so\n * KHR_texture_transform can attach per-texture UV state. */\nexport function buildDefaultPbrTexturesExt(\n engine: EngineContext,\n mat: GltfMaterialData,\n sampler: GPUSampler,\n generateMipmaps: GenerateMipmapsFn,\n getCachedTex: (bitmap: ImageBitmap, srgb: boolean) => Texture2D,\n wrapTex: TextureWrapFn\n): PbrTexturesExt {\n const wrap: TextureWrapFn = (tex, ti) => wrapTexCoord(wrapTex(tex, ti), ti);\n const raw = mat._rawMatDef ?? {};\n const pbr = raw.pbrMetallicRoughness ?? {};\n const baseColorTexture = mat._baseColorImage\n ? wrap(getCachedTex(mat._baseColorImage, true), pbr.baseColorTexture)\n : (() => {\n const f = mat._baseColorFactor;\n return uploadTex(\n engine,\n null,\n true,\n sampler,\n generateMipmaps,\n new U8([linearToSrgbByte(f[0]), linearToSrgbByte(f[1]), linearToSrgbByte(f[2]), Math.round(Math.max(0, Math.min(1, f[3])) * 255)])\n );\n })();\n const normalTexture = mat._normalImage ? wrap(getCachedTex(mat._normalImage, false), raw.normalTexture) : undefined;\n const emissiveTexture = mat._emissiveImage ? wrap(getCachedTex(mat._emissiveImage, true), raw.emissiveTexture) : undefined;\n\n const occlusionOnUv2 = mat._occlusionTexCoord !== 0 && mat._occlusionImage && !mat._metallicRoughnessImage;\n let occlusionTexture: Texture2D | undefined;\n const single = mat._metallicRoughnessImage ?? (occlusionOnUv2 ? null : mat._occlusionImage);\n let ormTexture: Texture2D;\n if (occlusionOnUv2) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new U8([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n occlusionTexture = wrap(getCachedTex(mat._occlusionImage!, false), raw.occlusionTexture);\n } else if (single && (!mat._metallicRoughnessImage || !mat._occlusionImage || mat._metallicRoughnessImage === mat._occlusionImage)) {\n const ormTi = mat._metallicRoughnessImage ? pbr.metallicRoughnessTexture : raw.occlusionTexture;\n ormTexture = wrap(getCachedTex(single, false), ormTi);\n } else if (!single) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new U8([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n } else {\n ormTexture = wrap(getCachedTex(mat._metallicRoughnessImage!, false), pbr.metallicRoughnessTexture);\n }\n return { baseColorTexture, ormTexture, normalTexture, emissiveTexture, occlusionTexture };\n}\n\n/** Slow-path assembly: adds occlusionTexCoord and occlusionTexture props. */\nexport function assemblePbrPropsExt(mat: GltfMaterialData, tex: PbrTexturesExt, extLayers: Partial<PbrMaterialProps> | undefined): PbrMaterialProps {\n const ef = mat._emissiveFactor;\n const defaultFactor = (ef[0] === 1 && ef[1] === 1 && ef[2] === 1) || (ef[0] === 0 && ef[1] === 0 && ef[2] === 0);\n // Precompute UV-transform presence so the renderer doesn't scan 5 textures\n // per mesh. Any wrapped texture with `_hasTx=true` (set by gltf-ext-uv-transform)\n // flips this once at build time; omitted entirely on fast path.\n const hasAnyUvTx =\n !!(tex.baseColorTexture as { _hasTx?: true })._hasTx ||\n !!(tex.normalTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.ormTexture as { _hasTx?: true })._hasTx ||\n !!(tex.emissiveTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.occlusionTexture as { _hasTx?: true } | undefined)?._hasTx;\n return {\n baseColorTexture: tex.baseColorTexture,\n normalTexture: tex.normalTexture,\n ormTexture: tex.ormTexture,\n emissiveTexture: tex.emissiveTexture,\n ...(mat._baseColorImage && !isDefaultBaseColorFactor(mat._baseColorFactor) ? { baseColorFactor: mat._baseColorFactor } : undefined),\n doubleSided: mat._doubleSided,\n occlusionStrength: mat._occlusionImage ? 1.0 : 0,\n ...(mat._occlusionTexCoord ? { occlusionTexCoord: mat._occlusionTexCoord } : undefined),\n ...(tex.occlusionTexture ? { occlusionTexture: tex.occlusionTexture } : undefined),\n ...(mat._normalScale !== 1 ? { normalTextureScale: mat._normalScale } : undefined),\n ...(mat._metallicRoughnessImage ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(!defaultFactor ? { emissiveColor: [ef[0], ef[1], ef[2]] as [number, number, number] } : undefined),\n enableSpecularAA: true,\n ...(mat._alphaMode === \"BLEND\" ? { alphaBlend: true, alpha: mat._baseColorFactor[3] } : undefined),\n ...(mat._alphaMode === \"MASK\" ? { alpha: mat._baseColorFactor[3], alphaCutOff: mat._alphaCutoff } : undefined),\n ...(hasAnyUvTx ? { _hasUvTx: true } : undefined),\n ...(mat._rawMatDef?.name ? { name: mat._rawMatDef.name as string } : undefined),\n ...extLayers,\n _buildGroup: pbrGroupBuilder,\n _uboVersion: 0,\n } as PbrMaterialProps;\n}\n\nfunction isDefaultBaseColorFactor(f: readonly number[]): boolean {\n return f[0] === 1 && f[1] === 1 && f[2] === 1 && f[3] === 1;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gltf-pbr-builder-ext-DJ8Jm7jo.js","sources":["../src/loader-gltf/gltf-pbr-builder-ext.ts"],"sourcesContent":["/** Lazy-loaded slow path for PBR material assembly.\n * Only pulled into bundles whose glTF uses features that require per-texture\n * wrapping (e.g. KHR_texture_transform) or occlusion on UV2 (texCoord=1 with\n * no shared MR image). Scene1 (BoomBox) and any vanilla-PBR glTF skip this\n * module entirely. */\n\nimport { U8 } from \"../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { cloneTexture2D } from \"../texture/texture-2d.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport { pbrGroupBuilder } from \"../material/pbr/pbr-material.js\";\nimport type { GltfMaterialData } from \"./gltf-material.js\";\nimport { linearToSrgbByte } from \"../math/color.js\";\nimport type { TextureWrapFn, GenerateMipmapsFn } from \"./gltf-pbr-builder.js\";\nimport { uploadTex } from \"./gltf-pbr-builder.js\";\n\nexport interface PbrTexturesExt {\n baseColorTexture: Texture2D;\n ormTexture: Texture2D;\n normalTexture: Texture2D | undefined;\n emissiveTexture: Texture2D | undefined;\n occlusionTexture: Texture2D | undefined;\n}\n\n/** Stamp `_texCoord=1` on a clone when textureInfo selects UV1 and the\n * wrapTex layer didn't already set it (i.e. scene has no KHR_texture_transform). */\nfunction wrapTexCoord(tex: Texture2D, texInfo: unknown): Texture2D {\n if (!texInfo) {\n return tex;\n }\n if ((tex as { _texCoord?: 0 | 1 })._texCoord === 1) {\n return tex;\n }\n const ti = texInfo as { texCoord?: number; extensions?: { KHR_texture_transform?: { texCoord?: number } } };\n const tc = ti.extensions?.KHR_texture_transform?.texCoord ?? ti.texCoord;\n return tc === 1 ? cloneTexture2D(tex, { _texCoord: 1 }) : tex;\n}\n\n/** Build textures with wrapTex + occlusionOnUv2 support. Mirrors master's\n * default texture building but honors per-textureInfo wrapping so\n * KHR_texture_transform can attach per-texture UV state. */\nexport function buildDefaultPbrTexturesExt(\n engine: EngineContext,\n mat: GltfMaterialData,\n sampler: GPUSampler,\n generateMipmaps: GenerateMipmapsFn,\n getCachedTex: (bitmap: ImageBitmap, srgb: boolean) => Texture2D,\n wrapTex: TextureWrapFn\n): PbrTexturesExt {\n const wrap: TextureWrapFn = (tex, ti) => wrapTexCoord(wrapTex(tex, ti), ti);\n const raw = mat._rawMatDef ?? {};\n const pbr = raw.pbrMetallicRoughness ?? {};\n const baseColorTexture = mat._baseColorImage\n ? wrap(getCachedTex(mat._baseColorImage, true), pbr.baseColorTexture)\n : (() => {\n const f = mat._baseColorFactor;\n return uploadTex(\n engine,\n null,\n true,\n sampler,\n generateMipmaps,\n new U8([linearToSrgbByte(f[0]), linearToSrgbByte(f[1]), linearToSrgbByte(f[2]), Math.round(Math.max(0, Math.min(1, f[3])) * 255)])\n );\n })();\n const normalTexture = mat._normalImage ? wrap(getCachedTex(mat._normalImage, false), raw.normalTexture) : undefined;\n const emissiveTexture = mat._emissiveImage ? wrap(getCachedTex(mat._emissiveImage, true), raw.emissiveTexture) : undefined;\n\n const occlusionOnUv2 = mat._occlusionTexCoord !== 0 && mat._occlusionImage && !mat._metallicRoughnessImage;\n let occlusionTexture: Texture2D | undefined;\n const single = mat._metallicRoughnessImage ?? (occlusionOnUv2 ? null : mat._occlusionImage);\n let ormTexture: Texture2D;\n if (occlusionOnUv2) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new U8([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n occlusionTexture = wrap(getCachedTex(mat._occlusionImage!, false), raw.occlusionTexture);\n } else if (single && (!mat._metallicRoughnessImage || !mat._occlusionImage || mat._metallicRoughnessImage === mat._occlusionImage)) {\n const ormTi = mat._metallicRoughnessImage ? pbr.metallicRoughnessTexture : raw.occlusionTexture;\n ormTexture = wrap(getCachedTex(single, false), ormTi);\n } else if (!single) {\n const clamp = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 255);\n ormTexture = uploadTex(engine, null, false, sampler, generateMipmaps, new U8([255, clamp(mat._roughnessFactor), clamp(mat._metallicFactor), 255]));\n } else {\n ormTexture = wrap(getCachedTex(mat._metallicRoughnessImage!, false), pbr.metallicRoughnessTexture);\n }\n return { baseColorTexture, ormTexture, normalTexture, emissiveTexture, occlusionTexture };\n}\n\n/** Slow-path assembly: adds occlusionTexCoord and occlusionTexture props. */\nexport function assemblePbrPropsExt(mat: GltfMaterialData, tex: PbrTexturesExt, extLayers: Partial<PbrMaterialProps> | undefined): PbrMaterialProps {\n const ef = mat._emissiveFactor;\n const defaultFactor = (ef[0] === 1 && ef[1] === 1 && ef[2] === 1) || (ef[0] === 0 && ef[1] === 0 && ef[2] === 0);\n // Precompute UV-transform presence so the renderer doesn't scan 5 textures\n // per mesh. Any wrapped texture with `_hasTx=true` (set by gltf-ext-uv-transform)\n // flips this once at build time; omitted entirely on fast path.\n const hasAnyUvTx =\n !!(tex.baseColorTexture as { _hasTx?: true })._hasTx ||\n !!(tex.normalTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.ormTexture as { _hasTx?: true })._hasTx ||\n !!(tex.emissiveTexture as { _hasTx?: true } | undefined)?._hasTx ||\n !!(tex.occlusionTexture as { _hasTx?: true } | undefined)?._hasTx;\n return {\n baseColorTexture: tex.baseColorTexture,\n normalTexture: tex.normalTexture,\n ormTexture: tex.ormTexture,\n emissiveTexture: tex.emissiveTexture,\n ...(mat._baseColorImage && !isDefaultBaseColorFactor(mat._baseColorFactor) ? { baseColorFactor: mat._baseColorFactor } : undefined),\n doubleSided: mat._doubleSided,\n occlusionStrength: mat._occlusionImage ? 1.0 : 0,\n ...(mat._occlusionTexCoord ? { occlusionTexCoord: mat._occlusionTexCoord } : undefined),\n ...(tex.occlusionTexture ? { occlusionTexture: tex.occlusionTexture } : undefined),\n ...(mat._normalScale !== 1 ? { normalTextureScale: mat._normalScale } : undefined),\n ...(mat._metallicRoughnessImage ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(!defaultFactor ? { emissiveColor: [ef[0], ef[1], ef[2]] as [number, number, number] } : undefined),\n enableSpecularAA: true,\n ...(mat._alphaMode === \"BLEND\" ? { alphaBlend: true, alpha: mat._baseColorFactor[3] } : undefined),\n ...(mat._alphaMode === \"MASK\" ? { alpha: mat._baseColorFactor[3], alphaCutOff: mat._alphaCutoff } : undefined),\n ...(hasAnyUvTx ? { _hasUvTx: true } : undefined),\n ...(mat._rawMatDef?.name ? { name: mat._rawMatDef.name as string } : undefined),\n ...extLayers,\n _buildGroup: pbrGroupBuilder,\n _uboVersion: 0,\n } as PbrMaterialProps;\n}\n\nfunction isDefaultBaseColorFactor(f: readonly number[]): boolean {\n return f[0] === 1 && f[1] === 1 && f[2] === 1 && f[3] === 1;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildDefaultPbrTexturesExt, assemblePbrPropsExt } from "./gltf-pbr-builder-ext-
|
|
1
|
+
import { bK as identityTexWrap, bL as getOrCreateSampler, bM as assembleMaterial, bN as runMatExts, u as uploadTex, bO as makeImageFetcher } from "./index-C2sM8ERH.js";
|
|
2
|
+
import { buildDefaultPbrTexturesExt, assemblePbrPropsExt } from "./gltf-pbr-builder-ext-DJ8Jm7jo.js";
|
|
3
3
|
async function loadVariantMaterials(json, binChunk, baseUrl, variantNames, meshes, engine, exts, wrapTex = identityTexWrap) {
|
|
4
4
|
var _a;
|
|
5
|
-
const generateMipmaps = (await import("./index-
|
|
5
|
+
const generateMipmaps = (await import("./index-C2sM8ERH.js").then((n) => n.kA)).generateMipmaps;
|
|
6
6
|
const sampler = getOrCreateSampler(engine, {
|
|
7
7
|
magFilter: "linear",
|
|
8
8
|
minFilter: "linear",
|
|
@@ -85,4 +85,4 @@ async function loadVariantMaterials(json, binChunk, baseUrl, variantNames, meshe
|
|
|
85
85
|
export {
|
|
86
86
|
loadVariantMaterials
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=gltf-variants-
|
|
88
|
+
//# sourceMappingURL=gltf-variants-C0HetOre.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-variants-
|
|
1
|
+
{"version":3,"file":"gltf-variants-C0HetOre.js","sources":["../src/loader-gltf/gltf-variants.ts"],"sourcesContent":["/**\n * KHR_materials_variants — glTF parsing + GPU upload for variant materials.\n *\n * Dynamically imported by load-gltf.ts ONLY when the extension is present.\n * This keeps variant code fully tree-shaken from bundles that don't use it.\n */\n\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { GltfMaterialData, GltfMatExtCtx } from \"./gltf-material.js\";\nimport { assembleMaterial, makeImageFetcher } from \"./gltf-material.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { MaterialVariantData, VariantMeshEntry } from \"./material-variants.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport { runMatExts, uploadTex, type GenerateMipmapsFn, type TextureWrapFn, identityTexWrap } from \"./gltf-pbr-builder.js\";\nimport { buildDefaultPbrTexturesExt, assemblePbrPropsExt } from \"./gltf-pbr-builder-ext.js\";\n\n/**\n * Self-contained variant material loader.\n * Parses variant mappings from glTF JSON primitives, assembles + uploads variant materials,\n * and builds MaterialVariantData. Called only when KHR_materials_variants is present.\n */\nexport async function loadVariantMaterials(\n json: any,\n binChunk: DataView,\n baseUrl: string,\n variantNames: string[],\n meshes: Mesh[],\n engine: EngineContext,\n exts: GltfFeature[],\n wrapTex: TextureWrapFn = identityTexWrap\n): Promise<MaterialVariantData> {\n const generateMipmaps: GenerateMipmapsFn = (await import(\"../texture/generate-mipmaps.js\")).generateMipmaps;\n\n const sampler = getOrCreateSampler(engine, {\n magFilter: \"linear\",\n minFilter: \"linear\",\n mipmapFilter: \"linear\",\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n maxAnisotropy: 4,\n });\n\n const matCache = new Map<number, Promise<GltfMaterialData>>();\n const imageCache = new Map<number, Promise<ImageBitmap>>();\n const fetchImg = makeImageFetcher(json, binChunk, baseUrl, imageCache);\n const getCachedTex = (bitmap: ImageBitmap, srgb: boolean) => uploadTex(engine, bitmap, srgb, sampler, generateMipmaps);\n const extCtx: GltfMatExtCtx = {\n _engine: engine,\n async _texture(texInfo, sRGB) {\n if (!texInfo) {\n return undefined;\n }\n const img = await fetchImg(texInfo);\n return img ? wrapTex(uploadTex(engine, img, sRGB, sampler, generateMipmaps), texInfo) : undefined;\n },\n _uploadImage(bitmap, sRGB) {\n return uploadTex(engine, bitmap, sRGB, sampler, generateMipmaps);\n },\n };\n const getMat = (matIdx: number): Promise<GltfMaterialData> => {\n let p = matCache.get(matIdx);\n if (!p) {\n p = assembleMaterial(json, binChunk, matIdx, baseUrl, imageCache);\n matCache.set(matIdx, p);\n }\n return p;\n };\n\n const pbrCache = new Map<GltfMaterialData, Promise<PbrMaterialProps>>();\n const getPbr = (gltfMat: GltfMaterialData): Promise<PbrMaterialProps> => {\n let p = pbrCache.get(gltfMat);\n if (!p) {\n p = (async () => {\n const tex = buildDefaultPbrTexturesExt(engine, gltfMat, sampler, generateMipmaps, getCachedTex, wrapTex);\n const layers = await runMatExts(gltfMat, exts, extCtx);\n return assemblePbrPropsExt(gltfMat, tex, layers);\n })();\n pbrCache.set(gltfMat, p);\n }\n return p;\n };\n\n const originals: VariantMeshEntry[] = [];\n const variants: Record<string, VariantMeshEntry[]> = {};\n for (const name of variantNames) {\n variants[name] = [];\n }\n\n let meshIdx = 0;\n for (let nodeIdx = 0; nodeIdx < json.nodes.length; nodeIdx++) {\n const node = json.nodes[nodeIdx];\n if (node.mesh === undefined) {\n continue;\n }\n const gltfMesh = json.meshes[node.mesh];\n for (const primitive of gltfMesh.primitives) {\n const mesh = meshes[meshIdx]!;\n const variantExt = primitive.extensions?.KHR_materials_variants;\n if (variantExt?.mappings) {\n originals.push({ mesh, material: mesh.material });\n for (const mapping of variantExt.mappings as { material: number; variants: number[] }[]) {\n const gltfMat = await getMat(mapping.material);\n const pbrMat = await getPbr(gltfMat);\n for (const vi of mapping.variants) {\n const name = variantNames[vi];\n if (name) {\n variants[name]!.push({ mesh, material: pbrMat });\n }\n }\n }\n }\n meshIdx++;\n }\n }\n\n return { names: variantNames, variants, originals };\n}\n"],"names":[],"mappings":";;AAuBA,eAAsB,qBAClB,MACA,UACA,SACA,cACA,QACA,QACA,MACA,UAAyB,iBACG;;AAC5B,QAAM,mBAAsC,MAAM,OAAO,qBAAgC,EAAA,KAAA,OAAA,EAAA,EAAA,GAAG;AAE5F,QAAM,UAAU,mBAAmB,QAAQ;AAAA,IACvC,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,EAAA,CAClB;AAED,QAAM,+BAAe,IAAA;AACrB,QAAM,iCAAiB,IAAA;AACvB,QAAM,WAAW,iBAAiB,MAAM,UAAU,SAAS,UAAU;AACrE,QAAM,eAAe,CAAC,QAAqB,SAAkB,UAAU,QAAQ,QAAQ,MAAM,SAAS,eAAe;AACrH,QAAM,SAAwB;AAAA,IAC1B,SAAS;AAAA,IACT,MAAM,SAAS,SAAS,MAAM;AAC1B,UAAI,CAAC,SAAS;AACV,eAAO;AAAA,MACX;AACA,YAAM,MAAM,MAAM,SAAS,OAAO;AAClC,aAAO,MAAM,QAAQ,UAAU,QAAQ,KAAK,MAAM,SAAS,eAAe,GAAG,OAAO,IAAI;AAAA,IAC5F;AAAA,IACA,aAAa,QAAQ,MAAM;AACvB,aAAO,UAAU,QAAQ,QAAQ,MAAM,SAAS,eAAe;AAAA,IACnE;AAAA,EAAA;AAEJ,QAAM,SAAS,CAAC,WAA8C;AAC1D,QAAI,IAAI,SAAS,IAAI,MAAM;AAC3B,QAAI,CAAC,GAAG;AACJ,UAAI,iBAAiB,MAAM,UAAU,QAAQ,SAAS,UAAU;AAChE,eAAS,IAAI,QAAQ,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACX;AAEA,QAAM,+BAAe,IAAA;AACrB,QAAM,SAAS,CAAC,YAAyD;AACrE,QAAI,IAAI,SAAS,IAAI,OAAO;AAC5B,QAAI,CAAC,GAAG;AACJ,WAAK,YAAY;AACb,cAAM,MAAM,2BAA2B,QAAQ,SAAS,SAAS,iBAAiB,cAAc,OAAO;AACvG,cAAM,SAAS,MAAM,WAAW,SAAS,MAAM,MAAM;AACrD,eAAO,oBAAoB,SAAS,KAAK,MAAM;AAAA,MACnD,GAAA;AACA,eAAS,IAAI,SAAS,CAAC;AAAA,IAC3B;AACA,WAAO;AAAA,EACX;AAEA,QAAM,YAAgC,CAAA;AACtC,QAAM,WAA+C,CAAA;AACrD,aAAW,QAAQ,cAAc;AAC7B,aAAS,IAAI,IAAI,CAAA;AAAA,EACrB;AAEA,MAAI,UAAU;AACd,WAAS,UAAU,GAAG,UAAU,KAAK,MAAM,QAAQ,WAAW;AAC1D,UAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,QAAI,KAAK,SAAS,QAAW;AACzB;AAAA,IACJ;AACA,UAAM,WAAW,KAAK,OAAO,KAAK,IAAI;AACtC,eAAW,aAAa,SAAS,YAAY;AACzC,YAAM,OAAO,OAAO,OAAO;AAC3B,YAAM,cAAa,eAAU,eAAV,mBAAsB;AACzC,UAAI,yCAAY,UAAU;AACtB,kBAAU,KAAK,EAAE,MAAM,UAAU,KAAK,UAAU;AAChD,mBAAW,WAAW,WAAW,UAAwD;AACrF,gBAAM,UAAU,MAAM,OAAO,QAAQ,QAAQ;AAC7C,gBAAM,SAAS,MAAM,OAAO,OAAO;AACnC,qBAAW,MAAM,QAAQ,UAAU;AAC/B,kBAAM,OAAO,aAAa,EAAE;AAC5B,gBAAI,MAAM;AACN,uBAAS,IAAI,EAAG,KAAK,EAAE,MAAM,UAAU,QAAQ;AAAA,YACnD;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AACA;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,EAAE,OAAO,cAAc,UAAU,UAAA;AAC5C;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as makeTimingSnapshot } from "./index-
|
|
1
|
+
import { m as makeTimingSnapshot } from "./index-C2sM8ERH.js";
|
|
2
2
|
const INITIAL_TASK_CAPACITY = 64;
|
|
3
3
|
const MAX_IN_FLIGHT_READBACKS = 3;
|
|
4
4
|
function createGpuTaskTimer(device) {
|
|
@@ -233,4 +233,4 @@ export {
|
|
|
233
233
|
createGpuTaskTimer,
|
|
234
234
|
installGpuTaskTimer
|
|
235
235
|
};
|
|
236
|
-
//# sourceMappingURL=gpu-task-timer-
|
|
236
|
+
//# sourceMappingURL=gpu-task-timer-C-3sLTxO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gpu-task-timer-DVBNZfq5.js","sources":["../src/engine/gpu-task-timer.ts"],"sourcesContent":["import type { EngineContext, RenderingContext } from \"./engine.js\";\nimport type { FrameGraph } from \"../frame-graph/frame-graph.js\";\nimport type { Task } from \"../frame-graph/task.js\";\nimport type { SurfaceContext } from \"./surface.js\";\nimport { makeTimingSnapshot, type RenderTaskGpuTiming, type RenderTaskGpuTimings } from \"./gpu-task-timing.js\";\n\nconst INITIAL_TASK_CAPACITY = 64;\nconst MAX_IN_FLIGHT_READBACKS = 3;\n\ninterface TaskTimingRecord {\n readonly index: number;\n readonly name: string;\n readonly beginQueryIndex: number;\n readonly endQueryIndex: number;\n}\n\ninterface PendingTaskTimingReadback {\n readonly buffer: GPUBuffer;\n readonly byteLength: number;\n readonly frameIndex: number;\n readonly records: readonly TaskTimingRecord[];\n readonly droppedTaskCount: number;\n readonly publish: (snapshot: RenderTaskGpuTimings) => void;\n}\n\ninterface WrappedFrameGraph {\n readonly graph: FrameGraph;\n readonly execute: () => number;\n}\n\ninterface PatchedContextList {\n readonly list: RenderingContext[];\n readonly push: (...items: RenderingContext[]) => number;\n}\n\ninterface PatchedSurfaceList {\n readonly list: SurfaceContext[];\n readonly push: (...items: SurfaceContext[]) => number;\n}\n\n/** @internal GPU resources/state for opt-in per-frame-graph-task timestamp queries. */\nexport interface GpuTaskTimer {\n readonly device: GPUDevice;\n readonly querySet: GPUQuerySet;\n readonly resolveBuffer: GPUBuffer;\n readonly readbackPool: GPUBuffer[];\n readonly records: TaskTimingRecord[];\n readonly wrappedGraphs: WrappedFrameGraph[];\n readonly patchedContextLists: PatchedContextList[];\n readonly patchedSurfaceLists: PatchedSurfaceList[];\n readonly taskCapacity: number;\n currentEncoder: GPUCommandEncoder | null;\n frameIndex: number;\n droppedTaskCount: number;\n inFlight: number;\n skipFrame: boolean;\n}\n\n/** Create the per-task GPU timer, or null when timestamp queries are unsupported. */\nexport function createGpuTaskTimer(device: GPUDevice): GpuTaskTimer | null {\n if (!device.features.has(\"timestamp-query\")) {\n return null;\n }\n const queryCount = INITIAL_TASK_CAPACITY * 2;\n return {\n device,\n querySet: device.createQuerySet({ type: \"timestamp\", count: queryCount }),\n resolveBuffer: device.createBuffer({\n size: queryCount * 8,\n usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,\n }),\n readbackPool: [],\n records: [],\n wrappedGraphs: [],\n patchedContextLists: [],\n patchedSurfaceLists: [],\n taskCapacity: INITIAL_TASK_CAPACITY,\n currentEncoder: null,\n frameIndex: 0,\n droppedTaskCount: 0,\n inFlight: 0,\n skipFrame: false,\n };\n}\n\n/** Install timed frame-graph execute wrappers on all contexts currently registered with the engine. */\nexport function installGpuTaskTimer(timer: GpuTaskTimer, engine: EngineContext, publish: (snapshot: RenderTaskGpuTimings) => void): () => void {\n patchSurfaceList(timer, engine._surfaces);\n for (const surface of engine.surfaces) {\n patchSurface(timer, surface);\n }\n const previousResolve = engine._gpuTimerResolve;\n const resolveTaskTiming = () => finishTaskTimingFrame(timer, publish);\n const resolveBoth = () => {\n previousResolve?.();\n resolveTaskTiming();\n };\n engine._gpuTaskTimerResolve = resolveTaskTiming;\n engine._gpuTimerResolve = resolveBoth;\n return () => restoreWrappedFrameGraphs(timer, engine, previousResolve, resolveTaskTiming, resolveBoth);\n}\n\nfunction patchSurfaceList(timer: GpuTaskTimer, list: SurfaceContext[]): void {\n for (const patched of timer.patchedSurfaceLists) {\n if (patched.list === list) {\n return;\n }\n }\n const push = list.push;\n list.push = (...items: SurfaceContext[]) => {\n const length = push.apply(list, items);\n for (const surface of items) {\n patchSurface(timer, surface);\n }\n return length;\n };\n timer.patchedSurfaceLists.push({ list, push });\n}\n\nfunction patchSurface(timer: GpuTaskTimer, surface: SurfaceContext): void {\n const contexts = surface._renderingContexts;\n patchContextList(timer, contexts);\n for (const context of contexts) {\n const graph = getFrameGraphFromContext(context);\n if (graph) {\n wrapFrameGraph(timer, graph);\n }\n }\n}\n\nfunction patchContextList(timer: GpuTaskTimer, list: RenderingContext[]): void {\n for (const patched of timer.patchedContextLists) {\n if (patched.list === list) {\n return;\n }\n }\n const push = list.push;\n list.push = (...items: RenderingContext[]) => {\n const length = push.apply(list, items);\n for (const context of items) {\n const graph = getFrameGraphFromContext(context);\n if (graph) {\n wrapFrameGraph(timer, graph);\n }\n }\n return length;\n };\n timer.patchedContextLists.push({ list, push });\n}\n\nfunction wrapFrameGraph(timer: GpuTaskTimer, graph: FrameGraph): void {\n for (const wrapped of timer.wrappedGraphs) {\n if (wrapped.graph === graph) {\n return;\n }\n }\n const original = graph.execute;\n const timed = () => executeTimedFrameGraph(timer, graph);\n graph.execute = timed;\n timer.wrappedGraphs.push({ graph, execute: original });\n}\n\nfunction restoreWrappedFrameGraphs(\n timer: GpuTaskTimer,\n engine: EngineContext,\n previousResolve: (() => void) | undefined,\n resolveTaskTiming: () => void,\n resolveBoth: () => void\n): void {\n for (const patched of timer.patchedSurfaceLists) {\n patched.list.push = patched.push;\n }\n timer.patchedSurfaceLists.length = 0;\n for (const patched of timer.patchedContextLists) {\n patched.list.push = patched.push;\n }\n timer.patchedContextLists.length = 0;\n for (const wrapped of timer.wrappedGraphs) {\n wrapped.graph.execute = wrapped.execute;\n }\n timer.wrappedGraphs.length = 0;\n timer.currentEncoder = null;\n if (engine._gpuTaskTimerResolve === resolveTaskTiming) {\n engine._gpuTaskTimerResolve = undefined;\n }\n if (engine._gpuTimerResolve === resolveBoth) {\n engine._gpuTimerResolve = previousResolve;\n } else if (engine._gpuTimerResolve === resolveTaskTiming) {\n engine._gpuTimerResolve = undefined;\n }\n}\n\nfunction getFrameGraphFromContext(context: RenderingContext): FrameGraph | null {\n const owner = context as RenderingContext & { _frameGraph?: unknown; frameGraph?: unknown };\n const graph = owner._frameGraph ?? owner.frameGraph;\n return isFrameGraph(graph) ? graph : null;\n}\n\nfunction isFrameGraph(value: unknown): value is FrameGraph {\n return typeof value === \"object\" && value !== null && \"_tasks\" in value && \"execute\" in value;\n}\n\nfunction executeTimedFrameGraph(timer: GpuTaskTimer, graph: FrameGraph): number {\n let drawCalls = 0;\n for (const task of graph._tasks) {\n drawCalls += gpuTaskTimerExecute(timer, task);\n }\n return drawCalls;\n}\n\n/** Execute one frame-graph task bracketed by timestamp writes. */\nfunction gpuTaskTimerExecute(timer: GpuTaskTimer, task: Task): number {\n const encoder = task.engine._currentEncoder;\n if (timer.currentEncoder !== encoder) {\n beginTaskTimingFrame(timer, encoder);\n }\n if (timer.skipFrame) {\n return executeTask(task);\n }\n\n const measuredCount = timer.records.length;\n const taskIndex = measuredCount + timer.droppedTaskCount;\n if (measuredCount >= timer.taskCapacity) {\n timer.droppedTaskCount++;\n return executeTask(task);\n }\n const beginQueryIndex = measuredCount * 2;\n const endQueryIndex = beginQueryIndex + 1;\n encoder.beginComputePass({ timestampWrites: { querySet: timer.querySet, beginningOfPassWriteIndex: beginQueryIndex } }).end();\n const drawCalls = executeTask(task);\n encoder.beginComputePass({ timestampWrites: { querySet: timer.querySet, endOfPassWriteIndex: endQueryIndex } }).end();\n timer.records.push({ index: taskIndex, name: task.name, beginQueryIndex, endQueryIndex });\n return drawCalls;\n}\n\nfunction executeTask(task: Task): number {\n if (task.execute) {\n return task.execute();\n }\n let drawCalls = 0;\n for (const pass of task._passes) {\n drawCalls += pass._execute();\n }\n return drawCalls;\n}\n\nfunction beginTaskTimingFrame(timer: GpuTaskTimer, encoder: GPUCommandEncoder): void {\n timer.currentEncoder = encoder;\n timer.records.length = 0;\n timer.droppedTaskCount = 0;\n timer.skipFrame = timer.inFlight > MAX_IN_FLIGHT_READBACKS;\n}\n\n/** Resolve this frame's task timestamps after renderFrame has submitted the command buffer. */\nfunction finishTaskTimingFrame(timer: GpuTaskTimer, publish: (snapshot: RenderTaskGpuTimings) => void): void {\n timer.frameIndex++;\n const taskCount = timer.records.length;\n if (timer.skipFrame || taskCount === 0 || timer.inFlight > MAX_IN_FLIGHT_READBACKS) {\n return;\n }\n\n const queryCount = taskCount * 2;\n const byteLength = queryCount * 8;\n const readback = timer.readbackPool.pop() ?? createReadbackBuffer(timer);\n const encoder = timer.device.createCommandEncoder({ label: \"gpu-task-timing-resolve\" });\n encoder.resolveQuerySet(timer.querySet, 0, queryCount, timer.resolveBuffer, 0);\n encoder.copyBufferToBuffer(timer.resolveBuffer, 0, readback, 0, byteLength);\n timer.device.queue.submit([encoder.finish()]);\n timer.inFlight++;\n void finishTaskTimingReadback(timer, {\n buffer: readback,\n byteLength,\n frameIndex: timer.frameIndex,\n records: timer.records.slice(),\n droppedTaskCount: timer.droppedTaskCount,\n publish,\n });\n}\n\nfunction createReadbackBuffer(timer: GpuTaskTimer): GPUBuffer {\n return timer.device.createBuffer({\n size: timer.taskCapacity * 16,\n usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,\n });\n}\n\nasync function finishTaskTimingReadback(timer: GpuTaskTimer, pending: PendingTaskTimingReadback): Promise<void> {\n const buffer = pending.buffer;\n try {\n // Let the resolve/copy submit leave the JavaScript stack before mapping.\n await Promise.resolve();\n await buffer.mapAsync(GPUMapMode.READ, 0, pending.byteLength);\n const raw = new BigUint64Array(buffer.getMappedRange(0, pending.byteLength));\n const tasks: RenderTaskGpuTiming[] = [];\n for (const record of pending.records) {\n const begin = raw[record.beginQueryIndex]!;\n const end = raw[record.endQueryIndex]!;\n if (end >= begin) {\n tasks.push({ index: record.index, name: record.name, durationMs: Number(end - begin) / 1e6 });\n }\n }\n buffer.unmap();\n timer.readbackPool.push(buffer);\n timer.inFlight--;\n pending.publish(makeTimingSnapshot(\"available\", true, true, pending.frameIndex, tasks, pending.droppedTaskCount));\n } catch (error) {\n timer.inFlight--;\n buffer.destroy();\n pending.publish(makeTimingSnapshot(\"error\", true, true, pending.frameIndex, [], pending.droppedTaskCount, readbackErrorMessage(error)));\n }\n}\n\nfunction readbackErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"names":[],"mappings":";AAMA,MAAM,wBAAwB;AAC9B,MAAM,0BAA0B;AAoDzB,SAAS,mBAAmB,QAAwC;AACvE,MAAI,CAAC,OAAO,SAAS,IAAI,iBAAiB,GAAG;AACzC,WAAO;AAAA,EACX;AACA,QAAM,aAAa,wBAAwB;AAC3C,SAAO;AAAA,IACH;AAAA,IACA,UAAU,OAAO,eAAe,EAAE,MAAM,aAAa,OAAO,YAAY;AAAA,IACxE,eAAe,OAAO,aAAa;AAAA,MAC/B,MAAM,aAAa;AAAA,MACnB,OAAO,eAAe,gBAAgB,eAAe;AAAA,IAAA,CACxD;AAAA,IACD,cAAc,CAAA;AAAA,IACd,SAAS,CAAA;AAAA,IACT,eAAe,CAAA;AAAA,IACf,qBAAqB,CAAA;AAAA,IACrB,qBAAqB,CAAA;AAAA,IACrB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAEnB;AAGO,SAAS,oBAAoB,OAAqB,QAAuB,SAA+D;AAC3I,mBAAiB,OAAO,OAAO,SAAS;AACxC,aAAW,WAAW,OAAO,UAAU;AACnC,iBAAa,OAAO,OAAO;AAAA,EAC/B;AACA,QAAM,kBAAkB,OAAO;AAC/B,QAAM,oBAAoB,MAAM,sBAAsB,OAAO,OAAO;AACpE,QAAM,cAAc,MAAM;AACtB;AACA,sBAAA;AAAA,EACJ;AACA,SAAO,uBAAuB;AAC9B,SAAO,mBAAmB;AAC1B,SAAO,MAAM,0BAA0B,OAAO,QAAQ,iBAAiB,mBAAmB,WAAW;AACzG;AAEA,SAAS,iBAAiB,OAAqB,MAA8B;AACzE,aAAW,WAAW,MAAM,qBAAqB;AAC7C,QAAI,QAAQ,SAAS,MAAM;AACvB;AAAA,IACJ;AAAA,EACJ;AACA,QAAM,OAAO,KAAK;AAClB,OAAK,OAAO,IAAI,UAA4B;AACxC,UAAM,SAAS,KAAK,MAAM,MAAM,KAAK;AACrC,eAAW,WAAW,OAAO;AACzB,mBAAa,OAAO,OAAO;AAAA,IAC/B;AACA,WAAO;AAAA,EACX;AACA,QAAM,oBAAoB,KAAK,EAAE,MAAM,MAAM;AACjD;AAEA,SAAS,aAAa,OAAqB,SAA+B;AACtE,QAAM,WAAW,QAAQ;AACzB,mBAAiB,OAAO,QAAQ;AAChC,aAAW,WAAW,UAAU;AAC5B,UAAM,QAAQ,yBAAyB,OAAO;AAC9C,QAAI,OAAO;AACP,qBAAe,OAAO,KAAK;AAAA,IAC/B;AAAA,EACJ;AACJ;AAEA,SAAS,iBAAiB,OAAqB,MAAgC;AAC3E,aAAW,WAAW,MAAM,qBAAqB;AAC7C,QAAI,QAAQ,SAAS,MAAM;AACvB;AAAA,IACJ;AAAA,EACJ;AACA,QAAM,OAAO,KAAK;AAClB,OAAK,OAAO,IAAI,UAA8B;AAC1C,UAAM,SAAS,KAAK,MAAM,MAAM,KAAK;AACrC,eAAW,WAAW,OAAO;AACzB,YAAM,QAAQ,yBAAyB,OAAO;AAC9C,UAAI,OAAO;AACP,uBAAe,OAAO,KAAK;AAAA,MAC/B;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AACA,QAAM,oBAAoB,KAAK,EAAE,MAAM,MAAM;AACjD;AAEA,SAAS,eAAe,OAAqB,OAAyB;AAClE,aAAW,WAAW,MAAM,eAAe;AACvC,QAAI,QAAQ,UAAU,OAAO;AACzB;AAAA,IACJ;AAAA,EACJ;AACA,QAAM,WAAW,MAAM;AACvB,QAAM,QAAQ,MAAM,uBAAuB,OAAO,KAAK;AACvD,QAAM,UAAU;AAChB,QAAM,cAAc,KAAK,EAAE,OAAO,SAAS,UAAU;AACzD;AAEA,SAAS,0BACL,OACA,QACA,iBACA,mBACA,aACI;AACJ,aAAW,WAAW,MAAM,qBAAqB;AAC7C,YAAQ,KAAK,OAAO,QAAQ;AAAA,EAChC;AACA,QAAM,oBAAoB,SAAS;AACnC,aAAW,WAAW,MAAM,qBAAqB;AAC7C,YAAQ,KAAK,OAAO,QAAQ;AAAA,EAChC;AACA,QAAM,oBAAoB,SAAS;AACnC,aAAW,WAAW,MAAM,eAAe;AACvC,YAAQ,MAAM,UAAU,QAAQ;AAAA,EACpC;AACA,QAAM,cAAc,SAAS;AAC7B,QAAM,iBAAiB;AACvB,MAAI,OAAO,yBAAyB,mBAAmB;AACnD,WAAO,uBAAuB;AAAA,EAClC;AACA,MAAI,OAAO,qBAAqB,aAAa;AACzC,WAAO,mBAAmB;AAAA,EAC9B,WAAW,OAAO,qBAAqB,mBAAmB;AACtD,WAAO,mBAAmB;AAAA,EAC9B;AACJ;AAEA,SAAS,yBAAyB,SAA8C;AAC5E,QAAM,QAAQ;AACd,QAAM,QAAQ,MAAM,eAAe,MAAM;AACzC,SAAO,aAAa,KAAK,IAAI,QAAQ;AACzC;AAEA,SAAS,aAAa,OAAqC;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,SAAS,aAAa;AAC5F;AAEA,SAAS,uBAAuB,OAAqB,OAA2B;AAC5E,MAAI,YAAY;AAChB,aAAW,QAAQ,MAAM,QAAQ;AAC7B,iBAAa,oBAAoB,OAAO,IAAI;AAAA,EAChD;AACA,SAAO;AACX;AAGA,SAAS,oBAAoB,OAAqB,MAAoB;AAClE,QAAM,UAAU,KAAK,OAAO;AAC5B,MAAI,MAAM,mBAAmB,SAAS;AAClC,yBAAqB,OAAO,OAAO;AAAA,EACvC;AACA,MAAI,MAAM,WAAW;AACjB,WAAO,YAAY,IAAI;AAAA,EAC3B;AAEA,QAAM,gBAAgB,MAAM,QAAQ;AACpC,QAAM,YAAY,gBAAgB,MAAM;AACxC,MAAI,iBAAiB,MAAM,cAAc;AACrC,UAAM;AACN,WAAO,YAAY,IAAI;AAAA,EAC3B;AACA,QAAM,kBAAkB,gBAAgB;AACxC,QAAM,gBAAgB,kBAAkB;AACxC,UAAQ,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,MAAM,UAAU,2BAA2B,kBAAgB,CAAG,EAAE,IAAA;AACxH,QAAM,YAAY,YAAY,IAAI;AAClC,UAAQ,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,MAAM,UAAU,qBAAqB,gBAAc,CAAG,EAAE,IAAA;AAChH,QAAM,QAAQ,KAAK,EAAE,OAAO,WAAW,MAAM,KAAK,MAAM,iBAAiB,cAAA,CAAe;AACxF,SAAO;AACX;AAEA,SAAS,YAAY,MAAoB;AACrC,MAAI,KAAK,SAAS;AACd,WAAO,KAAK,QAAA;AAAA,EAChB;AACA,MAAI,YAAY;AAChB,aAAW,QAAQ,KAAK,SAAS;AAC7B,iBAAa,KAAK,SAAA;AAAA,EACtB;AACA,SAAO;AACX;AAEA,SAAS,qBAAqB,OAAqB,SAAkC;AACjF,QAAM,iBAAiB;AACvB,QAAM,QAAQ,SAAS;AACvB,QAAM,mBAAmB;AACzB,QAAM,YAAY,MAAM,WAAW;AACvC;AAGA,SAAS,sBAAsB,OAAqB,SAAyD;AACzG,QAAM;AACN,QAAM,YAAY,MAAM,QAAQ;AAChC,MAAI,MAAM,aAAa,cAAc,KAAK,MAAM,WAAW,yBAAyB;AAChF;AAAA,EACJ;AAEA,QAAM,aAAa,YAAY;AAC/B,QAAM,aAAa,aAAa;AAChC,QAAM,WAAW,MAAM,aAAa,IAAA,KAAS,qBAAqB,KAAK;AACvE,QAAM,UAAU,MAAM,OAAO,qBAAqB,EAAE,OAAO,2BAA2B;AACtF,UAAQ,gBAAgB,MAAM,UAAU,GAAG,YAAY,MAAM,eAAe,CAAC;AAC7E,UAAQ,mBAAmB,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU;AAC1E,QAAM,OAAO,MAAM,OAAO,CAAC,QAAQ,OAAA,CAAQ,CAAC;AAC5C,QAAM;AACN,OAAK,yBAAyB,OAAO;AAAA,IACjC,QAAQ;AAAA,IACR;AAAA,IACA,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,QAAQ,MAAA;AAAA,IACvB,kBAAkB,MAAM;AAAA,IACxB;AAAA,EAAA,CACH;AACL;AAEA,SAAS,qBAAqB,OAAgC;AAC1D,SAAO,MAAM,OAAO,aAAa;AAAA,IAC7B,MAAM,MAAM,eAAe;AAAA,IAC3B,OAAO,eAAe,WAAW,eAAe;AAAA,EAAA,CACnD;AACL;AAEA,eAAe,yBAAyB,OAAqB,SAAmD;AAC5G,QAAM,SAAS,QAAQ;AACvB,MAAI;AAEA,UAAM,QAAQ,QAAA;AACd,UAAM,OAAO,SAAS,WAAW,MAAM,GAAG,QAAQ,UAAU;AAC5D,UAAM,MAAM,IAAI,eAAe,OAAO,eAAe,GAAG,QAAQ,UAAU,CAAC;AAC3E,UAAM,QAA+B,CAAA;AACrC,eAAW,UAAU,QAAQ,SAAS;AAClC,YAAM,QAAQ,IAAI,OAAO,eAAe;AACxC,YAAM,MAAM,IAAI,OAAO,aAAa;AACpC,UAAI,OAAO,OAAO;AACd,cAAM,KAAK,EAAE,OAAO,OAAO,OAAO,MAAM,OAAO,MAAM,YAAY,OAAO,MAAM,KAAK,IAAI,KAAK;AAAA,MAChG;AAAA,IACJ;AACA,WAAO,MAAA;AACP,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAM;AACN,YAAQ,QAAQ,mBAAmB,aAAa,MAAM,MAAM,QAAQ,YAAY,OAAO,QAAQ,gBAAgB,CAAC;AAAA,EACpH,SAAS,OAAO;AACZ,UAAM;AACN,WAAO,QAAA;AACP,YAAQ,QAAQ,mBAAmB,SAAS,MAAM,MAAM,QAAQ,YAAY,CAAA,GAAI,QAAQ,kBAAkB,qBAAqB,KAAK,CAAC,CAAC;AAAA,EAC1I;AACJ;AAEA,SAAS,qBAAqB,OAAwB;AAClD,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAChE;"}
|
|
1
|
+
{"version":3,"file":"gpu-task-timer-C-3sLTxO.js","sources":["../src/engine/gpu-task-timer.ts"],"sourcesContent":["import type { EngineContext, RenderingContext } from \"./engine.js\";\nimport type { FrameGraph } from \"../frame-graph/frame-graph.js\";\nimport type { Task } from \"../frame-graph/task.js\";\nimport type { SurfaceContext } from \"./surface.js\";\nimport { makeTimingSnapshot, type RenderTaskGpuTiming, type RenderTaskGpuTimings } from \"./gpu-task-timing.js\";\n\nconst INITIAL_TASK_CAPACITY = 64;\nconst MAX_IN_FLIGHT_READBACKS = 3;\n\ninterface TaskTimingRecord {\n readonly index: number;\n readonly name: string;\n readonly beginQueryIndex: number;\n readonly endQueryIndex: number;\n}\n\ninterface PendingTaskTimingReadback {\n readonly buffer: GPUBuffer;\n readonly byteLength: number;\n readonly frameIndex: number;\n readonly records: readonly TaskTimingRecord[];\n readonly droppedTaskCount: number;\n readonly publish: (snapshot: RenderTaskGpuTimings) => void;\n}\n\ninterface WrappedFrameGraph {\n readonly graph: FrameGraph;\n readonly execute: () => number;\n}\n\ninterface PatchedContextList {\n readonly list: RenderingContext[];\n readonly push: (...items: RenderingContext[]) => number;\n}\n\ninterface PatchedSurfaceList {\n readonly list: SurfaceContext[];\n readonly push: (...items: SurfaceContext[]) => number;\n}\n\n/** @internal GPU resources/state for opt-in per-frame-graph-task timestamp queries. */\nexport interface GpuTaskTimer {\n readonly device: GPUDevice;\n readonly querySet: GPUQuerySet;\n readonly resolveBuffer: GPUBuffer;\n readonly readbackPool: GPUBuffer[];\n readonly records: TaskTimingRecord[];\n readonly wrappedGraphs: WrappedFrameGraph[];\n readonly patchedContextLists: PatchedContextList[];\n readonly patchedSurfaceLists: PatchedSurfaceList[];\n readonly taskCapacity: number;\n currentEncoder: GPUCommandEncoder | null;\n frameIndex: number;\n droppedTaskCount: number;\n inFlight: number;\n skipFrame: boolean;\n}\n\n/** Create the per-task GPU timer, or null when timestamp queries are unsupported. */\nexport function createGpuTaskTimer(device: GPUDevice): GpuTaskTimer | null {\n if (!device.features.has(\"timestamp-query\")) {\n return null;\n }\n const queryCount = INITIAL_TASK_CAPACITY * 2;\n return {\n device,\n querySet: device.createQuerySet({ type: \"timestamp\", count: queryCount }),\n resolveBuffer: device.createBuffer({\n size: queryCount * 8,\n usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,\n }),\n readbackPool: [],\n records: [],\n wrappedGraphs: [],\n patchedContextLists: [],\n patchedSurfaceLists: [],\n taskCapacity: INITIAL_TASK_CAPACITY,\n currentEncoder: null,\n frameIndex: 0,\n droppedTaskCount: 0,\n inFlight: 0,\n skipFrame: false,\n };\n}\n\n/** Install timed frame-graph execute wrappers on all contexts currently registered with the engine. */\nexport function installGpuTaskTimer(timer: GpuTaskTimer, engine: EngineContext, publish: (snapshot: RenderTaskGpuTimings) => void): () => void {\n patchSurfaceList(timer, engine._surfaces);\n for (const surface of engine.surfaces) {\n patchSurface(timer, surface);\n }\n const previousResolve = engine._gpuTimerResolve;\n const resolveTaskTiming = () => finishTaskTimingFrame(timer, publish);\n const resolveBoth = () => {\n previousResolve?.();\n resolveTaskTiming();\n };\n engine._gpuTaskTimerResolve = resolveTaskTiming;\n engine._gpuTimerResolve = resolveBoth;\n return () => restoreWrappedFrameGraphs(timer, engine, previousResolve, resolveTaskTiming, resolveBoth);\n}\n\nfunction patchSurfaceList(timer: GpuTaskTimer, list: SurfaceContext[]): void {\n for (const patched of timer.patchedSurfaceLists) {\n if (patched.list === list) {\n return;\n }\n }\n const push = list.push;\n list.push = (...items: SurfaceContext[]) => {\n const length = push.apply(list, items);\n for (const surface of items) {\n patchSurface(timer, surface);\n }\n return length;\n };\n timer.patchedSurfaceLists.push({ list, push });\n}\n\nfunction patchSurface(timer: GpuTaskTimer, surface: SurfaceContext): void {\n const contexts = surface._renderingContexts;\n patchContextList(timer, contexts);\n for (const context of contexts) {\n const graph = getFrameGraphFromContext(context);\n if (graph) {\n wrapFrameGraph(timer, graph);\n }\n }\n}\n\nfunction patchContextList(timer: GpuTaskTimer, list: RenderingContext[]): void {\n for (const patched of timer.patchedContextLists) {\n if (patched.list === list) {\n return;\n }\n }\n const push = list.push;\n list.push = (...items: RenderingContext[]) => {\n const length = push.apply(list, items);\n for (const context of items) {\n const graph = getFrameGraphFromContext(context);\n if (graph) {\n wrapFrameGraph(timer, graph);\n }\n }\n return length;\n };\n timer.patchedContextLists.push({ list, push });\n}\n\nfunction wrapFrameGraph(timer: GpuTaskTimer, graph: FrameGraph): void {\n for (const wrapped of timer.wrappedGraphs) {\n if (wrapped.graph === graph) {\n return;\n }\n }\n const original = graph.execute;\n const timed = () => executeTimedFrameGraph(timer, graph);\n graph.execute = timed;\n timer.wrappedGraphs.push({ graph, execute: original });\n}\n\nfunction restoreWrappedFrameGraphs(\n timer: GpuTaskTimer,\n engine: EngineContext,\n previousResolve: (() => void) | undefined,\n resolveTaskTiming: () => void,\n resolveBoth: () => void\n): void {\n for (const patched of timer.patchedSurfaceLists) {\n patched.list.push = patched.push;\n }\n timer.patchedSurfaceLists.length = 0;\n for (const patched of timer.patchedContextLists) {\n patched.list.push = patched.push;\n }\n timer.patchedContextLists.length = 0;\n for (const wrapped of timer.wrappedGraphs) {\n wrapped.graph.execute = wrapped.execute;\n }\n timer.wrappedGraphs.length = 0;\n timer.currentEncoder = null;\n if (engine._gpuTaskTimerResolve === resolveTaskTiming) {\n engine._gpuTaskTimerResolve = undefined;\n }\n if (engine._gpuTimerResolve === resolveBoth) {\n engine._gpuTimerResolve = previousResolve;\n } else if (engine._gpuTimerResolve === resolveTaskTiming) {\n engine._gpuTimerResolve = undefined;\n }\n}\n\nfunction getFrameGraphFromContext(context: RenderingContext): FrameGraph | null {\n const owner = context as RenderingContext & { _frameGraph?: unknown; frameGraph?: unknown };\n const graph = owner._frameGraph ?? owner.frameGraph;\n return isFrameGraph(graph) ? graph : null;\n}\n\nfunction isFrameGraph(value: unknown): value is FrameGraph {\n return typeof value === \"object\" && value !== null && \"_tasks\" in value && \"execute\" in value;\n}\n\nfunction executeTimedFrameGraph(timer: GpuTaskTimer, graph: FrameGraph): number {\n let drawCalls = 0;\n for (const task of graph._tasks) {\n drawCalls += gpuTaskTimerExecute(timer, task);\n }\n return drawCalls;\n}\n\n/** Execute one frame-graph task bracketed by timestamp writes. */\nfunction gpuTaskTimerExecute(timer: GpuTaskTimer, task: Task): number {\n const encoder = task.engine._currentEncoder;\n if (timer.currentEncoder !== encoder) {\n beginTaskTimingFrame(timer, encoder);\n }\n if (timer.skipFrame) {\n return executeTask(task);\n }\n\n const measuredCount = timer.records.length;\n const taskIndex = measuredCount + timer.droppedTaskCount;\n if (measuredCount >= timer.taskCapacity) {\n timer.droppedTaskCount++;\n return executeTask(task);\n }\n const beginQueryIndex = measuredCount * 2;\n const endQueryIndex = beginQueryIndex + 1;\n encoder.beginComputePass({ timestampWrites: { querySet: timer.querySet, beginningOfPassWriteIndex: beginQueryIndex } }).end();\n const drawCalls = executeTask(task);\n encoder.beginComputePass({ timestampWrites: { querySet: timer.querySet, endOfPassWriteIndex: endQueryIndex } }).end();\n timer.records.push({ index: taskIndex, name: task.name, beginQueryIndex, endQueryIndex });\n return drawCalls;\n}\n\nfunction executeTask(task: Task): number {\n if (task.execute) {\n return task.execute();\n }\n let drawCalls = 0;\n for (const pass of task._passes) {\n drawCalls += pass._execute();\n }\n return drawCalls;\n}\n\nfunction beginTaskTimingFrame(timer: GpuTaskTimer, encoder: GPUCommandEncoder): void {\n timer.currentEncoder = encoder;\n timer.records.length = 0;\n timer.droppedTaskCount = 0;\n timer.skipFrame = timer.inFlight > MAX_IN_FLIGHT_READBACKS;\n}\n\n/** Resolve this frame's task timestamps after renderFrame has submitted the command buffer. */\nfunction finishTaskTimingFrame(timer: GpuTaskTimer, publish: (snapshot: RenderTaskGpuTimings) => void): void {\n timer.frameIndex++;\n const taskCount = timer.records.length;\n if (timer.skipFrame || taskCount === 0 || timer.inFlight > MAX_IN_FLIGHT_READBACKS) {\n return;\n }\n\n const queryCount = taskCount * 2;\n const byteLength = queryCount * 8;\n const readback = timer.readbackPool.pop() ?? createReadbackBuffer(timer);\n const encoder = timer.device.createCommandEncoder({ label: \"gpu-task-timing-resolve\" });\n encoder.resolveQuerySet(timer.querySet, 0, queryCount, timer.resolveBuffer, 0);\n encoder.copyBufferToBuffer(timer.resolveBuffer, 0, readback, 0, byteLength);\n timer.device.queue.submit([encoder.finish()]);\n timer.inFlight++;\n void finishTaskTimingReadback(timer, {\n buffer: readback,\n byteLength,\n frameIndex: timer.frameIndex,\n records: timer.records.slice(),\n droppedTaskCount: timer.droppedTaskCount,\n publish,\n });\n}\n\nfunction createReadbackBuffer(timer: GpuTaskTimer): GPUBuffer {\n return timer.device.createBuffer({\n size: timer.taskCapacity * 16,\n usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,\n });\n}\n\nasync function finishTaskTimingReadback(timer: GpuTaskTimer, pending: PendingTaskTimingReadback): Promise<void> {\n const buffer = pending.buffer;\n try {\n // Let the resolve/copy submit leave the JavaScript stack before mapping.\n await Promise.resolve();\n await buffer.mapAsync(GPUMapMode.READ, 0, pending.byteLength);\n const raw = new BigUint64Array(buffer.getMappedRange(0, pending.byteLength));\n const tasks: RenderTaskGpuTiming[] = [];\n for (const record of pending.records) {\n const begin = raw[record.beginQueryIndex]!;\n const end = raw[record.endQueryIndex]!;\n if (end >= begin) {\n tasks.push({ index: record.index, name: record.name, durationMs: Number(end - begin) / 1e6 });\n }\n }\n buffer.unmap();\n timer.readbackPool.push(buffer);\n timer.inFlight--;\n pending.publish(makeTimingSnapshot(\"available\", true, true, pending.frameIndex, tasks, pending.droppedTaskCount));\n } catch (error) {\n timer.inFlight--;\n buffer.destroy();\n pending.publish(makeTimingSnapshot(\"error\", true, true, pending.frameIndex, [], pending.droppedTaskCount, readbackErrorMessage(error)));\n }\n}\n\nfunction readbackErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BU, a as F32,
|
|
1
|
+
import { B as BU, a as F32, E as getRenderTargetSize, H as getViewMatrix, I as getProjectionMatrix, V as encodeIdToColor, S as SS, W as getPickingSceneBGL, A as applyGsFragments, X as gsGpuPickingFragment } from "./index-C2sM8ERH.js";
|
|
2
2
|
let _cache = null;
|
|
3
3
|
function buildPickingWgsl() {
|
|
4
4
|
const wgsl = (
|
|
@@ -277,4 +277,4 @@ export {
|
|
|
277
277
|
drawGsForPicking,
|
|
278
278
|
gsPickWritePickMatrixAndBind
|
|
279
279
|
};
|
|
280
|
-
//# sourceMappingURL=gs-picking-pipeline-
|
|
280
|
+
//# sourceMappingURL=gs-picking-pipeline-DlogO8fI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gs-picking-pipeline-CERN-Trj.js","sources":["../src/picking/gs-picking-pipeline.ts"],"sourcesContent":["/** GS GPU-picking pipeline — dynamic-imported by `gpu-picker.ts` when a scene\n * contains a Gaussian-Splatting mesh.\n *\n * The pipeline is a variant of the base Gaussian-splatting render pipeline\n * (`gaussian-splatting.wgsl`) with three modifications, applied via string\n * substitution + the `applyGsFragments` plugin system so the base shader stays\n * untouched:\n *\n * 1. A scene UBO at `@group(0) @binding(0)` carries a `pickMatrix`\n * (column-major 4x4) that zooms NDC onto the pick pixel — same maths as\n * `computePickVP` in `gpu-picker.ts`, but applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read a pick id + NDC z from the 1×1 render target.\n * 3. `gsGpuPickingFragment` is applied (via `applyGsFragments`) to inject the\n * per-mesh `pickingColor` UBO at `@group(2) @binding(0)` and override the\n * fragment color with the encoded pick id. This mirrors BJS\n * `GaussianSplattingGpuPickingMaterialPlugin`'s `getCustomCode`/`bindForSubMesh`\n * split.\n *\n * The pipeline has no blending and `depthWriteEnabled = true`, so the\n * closest-splat wins at each pick pixel (matching BJS GPU picker behaviour). */\n\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport { BU, SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { GaussianSplattingMesh } from \"../mesh/GaussianSplatting/gaussian-splatting-mesh.js\";\nimport { applyGsFragments } from \"../mesh/GaussianSplatting/gaussian-splatting-pipeline.js\";\nimport { gsGpuPickingFragment, encodeIdToColor } from \"../mesh/GaussianSplatting/gs-gpu-picking-fragment.js\";\nimport { getPickingSceneBGL } from \"./picking-pipeline.js\";\nimport { getRenderTargetSize } from \"../engine/engine.js\";\nimport { getViewMatrix, getProjectionMatrix } from \"../camera/camera.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\n\ninterface GsPickingCache {\n device: GPUDevice;\n pipeline: GPURenderPipeline;\n meshBGL: GPUBindGroupLayout;\n pickingBGL: GPUBindGroupLayout;\n /** Shared \"pick scene\" UBO holding the 4x4 pickMatrix (set per pick). */\n pickMatrixUbo: GPUBuffer;\n /** Bind group exposing `pickMatrixUbo` at group(0) binding(0). */\n sceneBG: GPUBindGroup;\n}\n\nlet _cache: GsPickingCache | null = null;\n\n/** Build the GS picking WGSL as a self-contained template literal.\n *\n * This is a variant of the base GS shader (`gaussian-splatting.wgsl`) with two\n * modifications baked in directly (rather than string-patched at runtime), so\n * it survives identifier-mangling minification in production bundles:\n *\n * 1. The final `out.pos` is pre-multiplied by `gsPickScene.pickMatrix` (a 4×4\n * UBO at `@group(0) @binding(0)`) — applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read pick id + NDC z from the 1×1 render target.\n *\n * The fragment keeps the `/* GS_FRAGMENT_* *\\/` slot markers so\n * `gsGpuPickingFragment` is still spliced in via `applyGsFragments` to\n * override `finalColor` with the encoded pick id. Template-literal WGSL\n * goes through `minifyTemplateWgsl` (preserves block comments) in the\n * bundle pipeline, so the slot markers survive minification.\n */\nfunction buildPickingWgsl(): string {\n const wgsl = /* wgsl */ `\nstruct GsPickScene { pickMatrix: mat4x4<f32> };\n@group(0) @binding(0) var<uniform> gsPickScene: GsPickScene;\n\nstruct U {\n world: mat4x4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n viewport: vec2<f32>,\n focal: vec2<f32>,\n dataSize: vec2<f32>,\n alpha: f32,\n _pad: f32,\n};\n@group(1) @binding(0) var<uniform> u: U;\n@group(1) @binding(1) var samp: sampler;\n@group(1) @binding(2) var centersTex: texture_2d<f32>;\n@group(1) @binding(3) var covATex: texture_2d<f32>;\n@group(1) @binding(4) var covBTex: texture_2d<f32>;\n@group(1) @binding(5) var colorsTex: texture_2d<f32>;\n\nstruct VOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) vColor: vec4<f32>,\n @location(1) vPos: vec2<f32>,\n};\n\nfn dataUv(idx: f32) -> vec2<f32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);\n}\n\n@vertex\nfn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {\n var out: VOut;\n let uv = dataUv(splatIndex);\n let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;\n let color = textureSampleLevel(colorsTex, samp, uv, 0.0);\n let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;\n let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;\n\n let worldPos = u.world * vec4<f32>(center, 1.0);\n let modelView = u.view * u.world;\n let camspace = u.view * worldPos;\n let pos2d = u.projection * camspace;\n\n let bounds = 1.2 * pos2d.w;\n if (pos2d.z < 0.0\n || pos2d.x < -bounds || pos2d.x > bounds\n || pos2d.y < -bounds || pos2d.y > bounds) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let Vrk = mat3x3<f32>(\n vec3<f32>(covA.x, covA.y, covA.z),\n vec3<f32>(covA.y, covB.x, covB.y),\n vec3<f32>(covA.z, covB.y, covB.z));\n\n let invZ = 1.0 / camspace.z;\n let invZ2 = invZ * invZ;\n let J = mat3x3<f32>(\n vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),\n vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),\n vec3<f32>(0.0, 0.0, 0.0));\n\n let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);\n let T = transpose(mv3) * J;\n var cov2d = transpose(T) * Vrk * T;\n\n let kernelSize: f32 = 0.3;\n cov2d[0][0] += kernelSize;\n cov2d[1][1] += kernelSize;\n\n let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;\n let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;\n let radius = length(vec2<f32>(dxy, cov2d[0][1]));\n let epsilon: f32 = 0.0001;\n let lambda1 = mid + radius + epsilon;\n let lambda2 = mid - radius + epsilon;\n if (lambda2 < 0.0) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));\n let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;\n let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);\n\n let vCenter = pos2d.xy;\n out.pos = gsPickScene.pickMatrix * vec4<f32>(\n vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,\n pos2d.z, pos2d.w);\n out.vColor = vec4<f32>(color.rgb, color.a * u.alpha);\n out.vPos = corner;\n return out;\n}\n\n/*GS_FRAGMENT_DEFINITIONS*/\nstruct FsOut { @location(0) color: vec4<f32>, @location(1) depth: vec4<f32> };\n@fragment\nfn fs(in: VOut) -> FsOut {\n /*GS_FRAGMENT_MAIN_BEGIN*/\n let A = -dot(in.vPos, in.vPos);\n var finalColor: vec4<f32>;\n if (A > -4.0) {\n let B = exp(A) * in.vColor.a;\n finalColor = vec4<f32>(in.vColor.rgb, B);\n } else {\n finalColor = vec4<f32>(0.0);\n }\n /*GS_FRAGMENT_BEFORE_FRAGCOLOR*/\n /*GS_FRAGMENT_MAIN_END*/\n return FsOut(finalColor, vec4<f32>(in.pos.z, 0.0, 0.0, 0.0));\n}\n`;\n return applyGsFragments(wgsl, [gsGpuPickingFragment]);\n}\n\nfunction getCache(engine: EngineContext): GsPickingCache {\n const device = engine._device;\n if (_cache && _cache.device === device) {\n return _cache;\n }\n const meshBGL = device.createBindGroupLayout({\n label: \"gs-picking-mesh-bgl\",\n entries: [\n { binding: 0, visibility: SS.VERTEX | SS.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: SS.VERTEX, sampler: { type: \"non-filtering\" } },\n { binding: 2, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 3, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 4, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 5, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n ],\n });\n const pickingBGL = device.createBindGroupLayout({\n label: \"gs-picking-pick-bgl\",\n entries: [{ binding: 0, visibility: SS.FRAGMENT, buffer: { type: \"uniform\" } }],\n });\n const module = device.createShaderModule({ label: \"gs-picking-shader\", code: buildPickingWgsl() });\n const pipeline = device.createRenderPipeline({\n label: \"gs-picking-pipeline\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [getPickingSceneBGL(engine), meshBGL, pickingBGL] }),\n vertex: {\n module,\n entryPoint: \"vs\",\n buffers: [\n { arrayStride: 8, stepMode: \"vertex\", attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }] },\n { arrayStride: 4, stepMode: \"instance\", attributes: [{ shaderLocation: 1, offset: 0, format: \"float32\" }] },\n ],\n },\n fragment: {\n module,\n entryPoint: \"fs\",\n targets: [{ format: \"rgba8unorm\" }, { format: \"r32float\" }],\n },\n primitive: { topology: \"triangle-list\", cullMode: \"none\" },\n depthStencil: { format: \"depth24plus\", depthCompare: \"less\", depthWriteEnabled: true },\n multisample: { count: 1 },\n });\n const pickMatrixUbo = device.createBuffer({ size: 64, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-scene-ubo\" });\n const sceneBG = device.createBindGroup({\n label: \"gs-picking-scene-bg\",\n layout: getPickingSceneBGL(engine),\n entries: [{ binding: 0, resource: { buffer: pickMatrixUbo } }],\n });\n _cache = { device, pipeline, meshBGL, pickingBGL, pickMatrixUbo, sceneBG };\n return _cache;\n}\n\n/** Write a 4x4 pickMatrix into the shared scene UBO and bind group 0 on `pass`. */\nexport function gsPickWritePickMatrixAndBind(pass: GPURenderPassEncoder, engine: EngineContext, pickMatrix: Float32Array): void {\n const cache = getCache(engine);\n engine._device.queue.writeBuffer(cache.pickMatrixUbo, 0, pickMatrix.buffer, pickMatrix.byteOffset, pickMatrix.byteLength);\n pass.setBindGroup(0, cache.sceneBG);\n}\n\n/** Per-GS-mesh state allocated on first pick of that mesh. */\nexport interface GsPickMeshResources {\n /** Per-mesh UBO (same 224-byte layout as the regular GS pipeline UBO). */\n meshUbo: GPUBuffer;\n /** Group 1 bind group: per-mesh UBO + sampler + 4 textures. */\n meshBG: GPUBindGroup;\n /** Per-pick picking-color UBO (16 bytes: vec3<f32> + pad). */\n pickingUbo: GPUBuffer;\n /** Group 2 bind group with the picking-color UBO. */\n pickingBG: GPUBindGroup;\n /** Scratch buffer for the per-mesh UBO. */\n meshCpu: Float32Array;\n /** Scratch buffer for the picking-color UBO. */\n pickingCpu: Float32Array;\n}\n\nexport function createGsPickMeshResources(engine: EngineContext, mesh: GaussianSplattingMesh): GsPickMeshResources {\n const device = engine._device;\n const cache = getCache(engine);\n\n const UBO_BYTES = 16 * 4 * 3 + 8 * 4;\n const meshUbo = device.createBuffer({ size: UBO_BYTES, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-mesh-ubo\" });\n const meshCpu = new F32(UBO_BYTES / 4);\n meshCpu[48 + 4] = mesh.textureWidth;\n meshCpu[48 + 5] = mesh.textureHeight;\n meshCpu[48 + 6] = 1;\n\n const meshBG = device.createBindGroup({\n label: \"gs-picking-mesh-bg\",\n layout: cache.meshBGL,\n entries: [\n { binding: 0, resource: { buffer: meshUbo } },\n { binding: 1, resource: mesh._gs._sampler },\n { binding: 2, resource: mesh._gs._centersView },\n { binding: 3, resource: mesh._gs._covAView },\n { binding: 4, resource: mesh._gs._covBView },\n { binding: 5, resource: mesh._gs._colorsView },\n ],\n });\n\n const pickingUbo = device.createBuffer({ size: 16, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-color-ubo\" });\n const pickingCpu = new F32(4);\n\n const pickingBG = device.createBindGroup({\n label: \"gs-picking-color-bg\",\n layout: cache.pickingBGL,\n entries: [{ binding: 0, resource: { buffer: pickingUbo } }],\n });\n\n return { meshUbo, meshBG, pickingUbo, pickingBG, meshCpu, pickingCpu };\n}\n\nexport function disposeGsPickMeshResources(res: GsPickMeshResources): void {\n res.meshUbo.destroy();\n res.pickingUbo.destroy();\n}\n\n/** Issue a pick draw for a single GS mesh. The caller must have already bound\n * the scene bind group (`pickMatrix` at group 0) on the pass; `pickId` is the\n * 24-bit pick id assigned by the picker. */\nexport function drawGsForPicking(\n pass: GPURenderPassEncoder,\n engine: EngineContext,\n scene: SceneContext,\n mesh: GaussianSplattingMesh,\n res: GsPickMeshResources,\n pickId: number,\n targetWidth: number,\n targetHeight: number\n): void {\n const cache = getCache(engine);\n\n // ── Per-mesh UBO ────────────────────────────────────────────────\n const cam = scene.camera;\n if (!cam) {\n return;\n }\n const size = getRenderTargetSize(engine);\n const aspect = (targetWidth || size.width) / (targetHeight || size.height);\n const view = getViewMatrix(cam) as unknown as Float32Array;\n const proj = getProjectionMatrix(cam, aspect) as unknown as Float32Array;\n const world = mesh.worldMatrix as unknown as Float32Array;\n const cpu = res.meshCpu;\n cpu.set(world, 0);\n cpu.set(view, 16);\n cpu.set(proj, 32);\n // Note: the GS picking pipeline still runs over the full-canvas viewport;\n // the picker output is a 1×1 target reached via the scene pickMatrix.\n cpu[48] = size.width;\n cpu[48 + 1] = size.height;\n cpu[48 + 2] = size.width * 0.5 * proj[0]!;\n cpu[48 + 3] = size.height * 0.5 * proj[5]!;\n // dataSize/alpha already written at construction.\n engine._device.queue.writeBuffer(res.meshUbo, 0, cpu.buffer, 0, cpu.byteLength);\n\n // ── Picking-color UBO ───────────────────────────────────────────\n const [r, g, b] = encodeIdToColor(pickId);\n res.pickingCpu[0] = r;\n res.pickingCpu[1] = g;\n res.pickingCpu[2] = b;\n res.pickingCpu[3] = 0;\n engine._device.queue.writeBuffer(res.pickingUbo, 0, res.pickingCpu.buffer, 0, 16);\n\n pass.setPipeline(cache.pipeline);\n pass.setBindGroup(1, res.meshBG);\n pass.setBindGroup(2, res.pickingBG);\n pass.setVertexBuffer(0, mesh._gs._quadBuffer);\n pass.setVertexBuffer(1, mesh._gs._splatIndexBuffer);\n pass.setIndexBuffer(mesh._gs._indexBuffer, \"uint16\");\n pass.drawIndexed(6, mesh.vertexCount);\n}\n\n/** Compute the pickMatrix for GS picking — same matrix `computePickVP` builds,\n * but applied to the clip-space output of the GS shader rather than the world.\n *\n * Maps canvas-NDC (px, py) ↦ (0, 0), and scales by (w, h) so a single canvas\n * pixel covers the full 1×1 pick render target. */\nexport function computeGsPickMatrix(out: Float32Array, px: number, py: number, w: number, h: number): void {\n const ndcX = (2 * (px + 0.5)) / w - 1;\n const ndcY = 1 - (2 * (py + 0.5)) / h;\n // column-major mat4\n out[0] = w;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = h;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = -ndcX * w;\n out[13] = -ndcY * h;\n out[14] = 0;\n out[15] = 1;\n}\n"],"names":[],"mappings":";AA6CA,IAAI,SAAgC;AAoBpC,SAAS,mBAA2B;AAChC,QAAM;AAAA;AAAA,IAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyHxB,SAAO,iBAAiB,MAAM,CAAC,oBAAoB,CAAC;AACxD;AAEA,SAAS,SAAS,QAAuC;AACrD,QAAM,SAAS,OAAO;AACtB,MAAI,UAAU,OAAO,WAAW,QAAQ;AACpC,WAAO;AAAA,EACX;AACA,QAAM,UAAU,OAAO,sBAAsB;AAAA,IACzC,OAAO;AAAA,IACP,SAAS;AAAA,MACL,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,QAAQ,EAAE,MAAM,UAAA,EAAU;AAAA,MAC7E,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,SAAS,EAAE,MAAM,kBAAgB;AAAA,MACtE,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,SAAS,EAAE,YAAY,uBAAqB;AAAA,MACjF,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,SAAS,EAAE,YAAY,uBAAqB;AAAA,MACjF,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,SAAS,EAAE,YAAY,uBAAqB;AAAA,MACjF,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,SAAS,EAAE,YAAY,qBAAA,EAAqB;AAAA,IAAE;AAAA,EACvF,CACH;AACD,QAAM,aAAa,OAAO,sBAAsB;AAAA,IAC5C,OAAO;AAAA,IACP,SAAS,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,UAAU,QAAQ,EAAE,MAAM,UAAA,GAAa;AAAA,EAAA,CACjF;AACD,QAAM,SAAS,OAAO,mBAAmB,EAAE,OAAO,qBAAqB,MAAM,iBAAA,GAAoB;AACjG,QAAM,WAAW,OAAO,qBAAqB;AAAA,IACzC,OAAO;AAAA,IACP,QAAQ,OAAO,qBAAqB,EAAE,kBAAkB,CAAC,mBAAmB,MAAM,GAAG,SAAS,UAAU,GAAG;AAAA,IAC3G,QAAQ;AAAA,MACJ;AAAA,MACA,YAAY;AAAA,MACZ,SAAS;AAAA,QACL,EAAE,aAAa,GAAG,UAAU,UAAU,YAAY,CAAC,EAAE,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,YAAA,CAAa,EAAA;AAAA,QACxG,EAAE,aAAa,GAAG,UAAU,YAAY,YAAY,CAAC,EAAE,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,UAAA,CAAW,EAAA;AAAA,MAAE;AAAA,IAC9G;AAAA,IAEJ,UAAU;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,SAAS,CAAC,EAAE,QAAQ,gBAAgB,EAAE,QAAQ,WAAA,CAAY;AAAA,IAAA;AAAA,IAE9D,WAAW,EAAE,UAAU,iBAAiB,UAAU,OAAA;AAAA,IAClD,cAAc,EAAE,QAAQ,eAAe,cAAc,QAAQ,mBAAmB,KAAA;AAAA,IAChF,aAAa,EAAE,OAAO,EAAA;AAAA,EAAE,CAC3B;AACD,QAAM,gBAAgB,OAAO,aAAa,EAAE,MAAM,IAAI,OAAO,GAAG,UAAU,GAAG,UAAU,OAAO,wBAAwB;AACtH,QAAM,UAAU,OAAO,gBAAgB;AAAA,IACnC,OAAO;AAAA,IACP,QAAQ,mBAAmB,MAAM;AAAA,IACjC,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,gBAAc,CAAG;AAAA,EAAA,CAChE;AACD,WAAS,EAAE,QAAQ,UAAU,SAAS,YAAY,eAAe,QAAA;AACjE,SAAO;AACX;AAGO,SAAS,6BAA6B,MAA4B,QAAuB,YAAgC;AAC5H,QAAM,QAAQ,SAAS,MAAM;AAC7B,SAAO,QAAQ,MAAM,YAAY,MAAM,eAAe,GAAG,WAAW,QAAQ,WAAW,YAAY,WAAW,UAAU;AACxH,OAAK,aAAa,GAAG,MAAM,OAAO;AACtC;AAkBO,SAAS,0BAA0B,QAAuB,MAAkD;AAC/G,QAAM,SAAS,OAAO;AACtB,QAAM,QAAQ,SAAS,MAAM;AAE7B,QAAM,YAAY,KAAK,IAAI,IAAI,IAAI;AACnC,QAAM,UAAU,OAAO,aAAa,EAAE,MAAM,WAAW,OAAO,GAAG,UAAU,GAAG,UAAU,OAAO,uBAAuB;AACtH,QAAM,UAAU,IAAI,IAAI,YAAY,CAAC;AACrC,UAAQ,KAAK,CAAC,IAAI,KAAK;AACvB,UAAQ,KAAK,CAAC,IAAI,KAAK;AACvB,UAAQ,KAAK,CAAC,IAAI;AAElB,QAAM,SAAS,OAAO,gBAAgB;AAAA,IAClC,OAAO;AAAA,IACP,QAAQ,MAAM;AAAA,IACd,SAAS;AAAA,MACL,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,UAAQ;AAAA,MAC1C,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,SAAA;AAAA,MACjC,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,aAAA;AAAA,MACjC,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,UAAA;AAAA,MACjC,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,UAAA;AAAA,MACjC,EAAE,SAAS,GAAG,UAAU,KAAK,IAAI,YAAA;AAAA,IAAY;AAAA,EACjD,CACH;AAED,QAAM,aAAa,OAAO,aAAa,EAAE,MAAM,IAAI,OAAO,GAAG,UAAU,GAAG,UAAU,OAAO,wBAAwB;AACnH,QAAM,aAAa,IAAI,IAAI,CAAC;AAE5B,QAAM,YAAY,OAAO,gBAAgB;AAAA,IACrC,OAAO;AAAA,IACP,QAAQ,MAAM;AAAA,IACd,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,aAAW,CAAG;AAAA,EAAA,CAC7D;AAED,SAAO,EAAE,SAAS,QAAQ,YAAY,WAAW,SAAS,WAAA;AAC9D;AAEO,SAAS,2BAA2B,KAAgC;AACvE,MAAI,QAAQ,QAAA;AACZ,MAAI,WAAW,QAAA;AACnB;AAKO,SAAS,iBACZ,MACA,QACA,OACA,MACA,KACA,QACA,aACA,cACI;AACJ,QAAM,QAAQ,SAAS,MAAM;AAG7B,QAAM,MAAM,MAAM;AAClB,MAAI,CAAC,KAAK;AACN;AAAA,EACJ;AACA,QAAM,OAAO,oBAAoB,MAAM;AACvC,QAAM,UAAU,eAAe,KAAK,UAAU,gBAAgB,KAAK;AACnE,QAAM,OAAO,cAAc,GAAG;AAC9B,QAAM,OAAO,oBAAoB,KAAK,MAAM;AAC5C,QAAM,QAAQ,KAAK;AACnB,QAAM,MAAM,IAAI;AAChB,MAAI,IAAI,OAAO,CAAC;AAChB,MAAI,IAAI,MAAM,EAAE;AAChB,MAAI,IAAI,MAAM,EAAE;AAGhB,MAAI,EAAE,IAAI,KAAK;AACf,MAAI,KAAK,CAAC,IAAI,KAAK;AACnB,MAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,MAAM,KAAK,CAAC;AACvC,MAAI,KAAK,CAAC,IAAI,KAAK,SAAS,MAAM,KAAK,CAAC;AAExC,SAAO,QAAQ,MAAM,YAAY,IAAI,SAAS,GAAG,IAAI,QAAQ,GAAG,IAAI,UAAU;AAG9E,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,gBAAgB,MAAM;AACxC,MAAI,WAAW,CAAC,IAAI;AACpB,MAAI,WAAW,CAAC,IAAI;AACpB,MAAI,WAAW,CAAC,IAAI;AACpB,MAAI,WAAW,CAAC,IAAI;AACpB,SAAO,QAAQ,MAAM,YAAY,IAAI,YAAY,GAAG,IAAI,WAAW,QAAQ,GAAG,EAAE;AAEhF,OAAK,YAAY,MAAM,QAAQ;AAC/B,OAAK,aAAa,GAAG,IAAI,MAAM;AAC/B,OAAK,aAAa,GAAG,IAAI,SAAS;AAClC,OAAK,gBAAgB,GAAG,KAAK,IAAI,WAAW;AAC5C,OAAK,gBAAgB,GAAG,KAAK,IAAI,iBAAiB;AAClD,OAAK,eAAe,KAAK,IAAI,cAAc,QAAQ;AACnD,OAAK,YAAY,GAAG,KAAK,WAAW;AACxC;AAOO,SAAS,oBAAoB,KAAmB,IAAY,IAAY,GAAW,GAAiB;AACvG,QAAM,OAAQ,KAAK,KAAK,OAAQ,IAAI;AACpC,QAAM,OAAO,IAAK,KAAK,KAAK,OAAQ;AAEpC,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,CAAC,IAAI;AACT,MAAI,EAAE,IAAI;AACV,MAAI,EAAE,IAAI;AACV,MAAI,EAAE,IAAI,CAAC,OAAO;AAClB,MAAI,EAAE,IAAI,CAAC,OAAO;AAClB,MAAI,EAAE,IAAI;AACV,MAAI,EAAE,IAAI;AACd;"}
|
|
1
|
+
{"version":3,"file":"gs-picking-pipeline-DlogO8fI.js","sources":["../src/picking/gs-picking-pipeline.ts"],"sourcesContent":["/** GS GPU-picking pipeline — dynamic-imported by `gpu-picker.ts` when a scene\n * contains a Gaussian-Splatting mesh.\n *\n * The pipeline is a variant of the base Gaussian-splatting render pipeline\n * (`gaussian-splatting.wgsl`) with three modifications, applied via string\n * substitution + the `applyGsFragments` plugin system so the base shader stays\n * untouched:\n *\n * 1. A scene UBO at `@group(0) @binding(0)` carries a `pickMatrix`\n * (column-major 4x4) that zooms NDC onto the pick pixel — same maths as\n * `computePickVP` in `gpu-picker.ts`, but applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read a pick id + NDC z from the 1×1 render target.\n * 3. `gsGpuPickingFragment` is applied (via `applyGsFragments`) to inject the\n * per-mesh `pickingColor` UBO at `@group(2) @binding(0)` and override the\n * fragment color with the encoded pick id. This mirrors BJS\n * `GaussianSplattingGpuPickingMaterialPlugin`'s `getCustomCode`/`bindForSubMesh`\n * split.\n *\n * The pipeline has no blending and `depthWriteEnabled = true`, so the\n * closest-splat wins at each pick pixel (matching BJS GPU picker behaviour). */\n\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport { BU, SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { GaussianSplattingMesh } from \"../mesh/GaussianSplatting/gaussian-splatting-mesh.js\";\nimport { applyGsFragments } from \"../mesh/GaussianSplatting/gaussian-splatting-pipeline.js\";\nimport { gsGpuPickingFragment, encodeIdToColor } from \"../mesh/GaussianSplatting/gs-gpu-picking-fragment.js\";\nimport { getPickingSceneBGL } from \"./picking-pipeline.js\";\nimport { getRenderTargetSize } from \"../engine/engine.js\";\nimport { getViewMatrix, getProjectionMatrix } from \"../camera/camera.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\n\ninterface GsPickingCache {\n device: GPUDevice;\n pipeline: GPURenderPipeline;\n meshBGL: GPUBindGroupLayout;\n pickingBGL: GPUBindGroupLayout;\n /** Shared \"pick scene\" UBO holding the 4x4 pickMatrix (set per pick). */\n pickMatrixUbo: GPUBuffer;\n /** Bind group exposing `pickMatrixUbo` at group(0) binding(0). */\n sceneBG: GPUBindGroup;\n}\n\nlet _cache: GsPickingCache | null = null;\n\n/** Build the GS picking WGSL as a self-contained template literal.\n *\n * This is a variant of the base GS shader (`gaussian-splatting.wgsl`) with two\n * modifications baked in directly (rather than string-patched at runtime), so\n * it survives identifier-mangling minification in production bundles:\n *\n * 1. The final `out.pos` is pre-multiplied by `gsPickScene.pickMatrix` (a 4×4\n * UBO at `@group(0) @binding(0)`) — applied *after* the GS-specific\n * projection so the EWA Jacobian / `u.focal` math is untouched.\n * 2. The fragment returns `FsOut { @location(0) color, @location(1) depth }`\n * so the picker can read pick id + NDC z from the 1×1 render target.\n *\n * The fragment keeps the `/* GS_FRAGMENT_* *\\/` slot markers so\n * `gsGpuPickingFragment` is still spliced in via `applyGsFragments` to\n * override `finalColor` with the encoded pick id. Template-literal WGSL\n * goes through `minifyTemplateWgsl` (preserves block comments) in the\n * bundle pipeline, so the slot markers survive minification.\n */\nfunction buildPickingWgsl(): string {\n const wgsl = /* wgsl */ `\nstruct GsPickScene { pickMatrix: mat4x4<f32> };\n@group(0) @binding(0) var<uniform> gsPickScene: GsPickScene;\n\nstruct U {\n world: mat4x4<f32>,\n view: mat4x4<f32>,\n projection: mat4x4<f32>,\n viewport: vec2<f32>,\n focal: vec2<f32>,\n dataSize: vec2<f32>,\n alpha: f32,\n _pad: f32,\n};\n@group(1) @binding(0) var<uniform> u: U;\n@group(1) @binding(1) var samp: sampler;\n@group(1) @binding(2) var centersTex: texture_2d<f32>;\n@group(1) @binding(3) var covATex: texture_2d<f32>;\n@group(1) @binding(4) var covBTex: texture_2d<f32>;\n@group(1) @binding(5) var colorsTex: texture_2d<f32>;\n\nstruct VOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) vColor: vec4<f32>,\n @location(1) vPos: vec2<f32>,\n};\n\nfn dataUv(idx: f32) -> vec2<f32> {\n let y = floor(idx / u.dataSize.x);\n let x = idx - y * u.dataSize.x;\n return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);\n}\n\n@vertex\nfn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {\n var out: VOut;\n let uv = dataUv(splatIndex);\n let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;\n let color = textureSampleLevel(colorsTex, samp, uv, 0.0);\n let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;\n let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;\n\n let worldPos = u.world * vec4<f32>(center, 1.0);\n let modelView = u.view * u.world;\n let camspace = u.view * worldPos;\n let pos2d = u.projection * camspace;\n\n let bounds = 1.2 * pos2d.w;\n if (pos2d.z < 0.0\n || pos2d.x < -bounds || pos2d.x > bounds\n || pos2d.y < -bounds || pos2d.y > bounds) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let Vrk = mat3x3<f32>(\n vec3<f32>(covA.x, covA.y, covA.z),\n vec3<f32>(covA.y, covB.x, covB.y),\n vec3<f32>(covA.z, covB.y, covB.z));\n\n let invZ = 1.0 / camspace.z;\n let invZ2 = invZ * invZ;\n let J = mat3x3<f32>(\n vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),\n vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),\n vec3<f32>(0.0, 0.0, 0.0));\n\n let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);\n let T = transpose(mv3) * J;\n var cov2d = transpose(T) * Vrk * T;\n\n let kernelSize: f32 = 0.3;\n cov2d[0][0] += kernelSize;\n cov2d[1][1] += kernelSize;\n\n let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;\n let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;\n let radius = length(vec2<f32>(dxy, cov2d[0][1]));\n let epsilon: f32 = 0.0001;\n let lambda1 = mid + radius + epsilon;\n let lambda2 = mid - radius + epsilon;\n if (lambda2 < 0.0) {\n out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);\n out.vColor = vec4<f32>(0.0);\n out.vPos = vec2<f32>(0.0);\n return out;\n }\n\n let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));\n let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;\n let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);\n\n let vCenter = pos2d.xy;\n out.pos = gsPickScene.pickMatrix * vec4<f32>(\n vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,\n pos2d.z, pos2d.w);\n out.vColor = vec4<f32>(color.rgb, color.a * u.alpha);\n out.vPos = corner;\n return out;\n}\n\n/*GS_FRAGMENT_DEFINITIONS*/\nstruct FsOut { @location(0) color: vec4<f32>, @location(1) depth: vec4<f32> };\n@fragment\nfn fs(in: VOut) -> FsOut {\n /*GS_FRAGMENT_MAIN_BEGIN*/\n let A = -dot(in.vPos, in.vPos);\n var finalColor: vec4<f32>;\n if (A > -4.0) {\n let B = exp(A) * in.vColor.a;\n finalColor = vec4<f32>(in.vColor.rgb, B);\n } else {\n finalColor = vec4<f32>(0.0);\n }\n /*GS_FRAGMENT_BEFORE_FRAGCOLOR*/\n /*GS_FRAGMENT_MAIN_END*/\n return FsOut(finalColor, vec4<f32>(in.pos.z, 0.0, 0.0, 0.0));\n}\n`;\n return applyGsFragments(wgsl, [gsGpuPickingFragment]);\n}\n\nfunction getCache(engine: EngineContext): GsPickingCache {\n const device = engine._device;\n if (_cache && _cache.device === device) {\n return _cache;\n }\n const meshBGL = device.createBindGroupLayout({\n label: \"gs-picking-mesh-bgl\",\n entries: [\n { binding: 0, visibility: SS.VERTEX | SS.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: SS.VERTEX, sampler: { type: \"non-filtering\" } },\n { binding: 2, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 3, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 4, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 5, visibility: SS.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n ],\n });\n const pickingBGL = device.createBindGroupLayout({\n label: \"gs-picking-pick-bgl\",\n entries: [{ binding: 0, visibility: SS.FRAGMENT, buffer: { type: \"uniform\" } }],\n });\n const module = device.createShaderModule({ label: \"gs-picking-shader\", code: buildPickingWgsl() });\n const pipeline = device.createRenderPipeline({\n label: \"gs-picking-pipeline\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [getPickingSceneBGL(engine), meshBGL, pickingBGL] }),\n vertex: {\n module,\n entryPoint: \"vs\",\n buffers: [\n { arrayStride: 8, stepMode: \"vertex\", attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }] },\n { arrayStride: 4, stepMode: \"instance\", attributes: [{ shaderLocation: 1, offset: 0, format: \"float32\" }] },\n ],\n },\n fragment: {\n module,\n entryPoint: \"fs\",\n targets: [{ format: \"rgba8unorm\" }, { format: \"r32float\" }],\n },\n primitive: { topology: \"triangle-list\", cullMode: \"none\" },\n depthStencil: { format: \"depth24plus\", depthCompare: \"less\", depthWriteEnabled: true },\n multisample: { count: 1 },\n });\n const pickMatrixUbo = device.createBuffer({ size: 64, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-scene-ubo\" });\n const sceneBG = device.createBindGroup({\n label: \"gs-picking-scene-bg\",\n layout: getPickingSceneBGL(engine),\n entries: [{ binding: 0, resource: { buffer: pickMatrixUbo } }],\n });\n _cache = { device, pipeline, meshBGL, pickingBGL, pickMatrixUbo, sceneBG };\n return _cache;\n}\n\n/** Write a 4x4 pickMatrix into the shared scene UBO and bind group 0 on `pass`. */\nexport function gsPickWritePickMatrixAndBind(pass: GPURenderPassEncoder, engine: EngineContext, pickMatrix: Float32Array): void {\n const cache = getCache(engine);\n engine._device.queue.writeBuffer(cache.pickMatrixUbo, 0, pickMatrix.buffer, pickMatrix.byteOffset, pickMatrix.byteLength);\n pass.setBindGroup(0, cache.sceneBG);\n}\n\n/** Per-GS-mesh state allocated on first pick of that mesh. */\nexport interface GsPickMeshResources {\n /** Per-mesh UBO (same 224-byte layout as the regular GS pipeline UBO). */\n meshUbo: GPUBuffer;\n /** Group 1 bind group: per-mesh UBO + sampler + 4 textures. */\n meshBG: GPUBindGroup;\n /** Per-pick picking-color UBO (16 bytes: vec3<f32> + pad). */\n pickingUbo: GPUBuffer;\n /** Group 2 bind group with the picking-color UBO. */\n pickingBG: GPUBindGroup;\n /** Scratch buffer for the per-mesh UBO. */\n meshCpu: Float32Array;\n /** Scratch buffer for the picking-color UBO. */\n pickingCpu: Float32Array;\n}\n\nexport function createGsPickMeshResources(engine: EngineContext, mesh: GaussianSplattingMesh): GsPickMeshResources {\n const device = engine._device;\n const cache = getCache(engine);\n\n const UBO_BYTES = 16 * 4 * 3 + 8 * 4;\n const meshUbo = device.createBuffer({ size: UBO_BYTES, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-mesh-ubo\" });\n const meshCpu = new F32(UBO_BYTES / 4);\n meshCpu[48 + 4] = mesh.textureWidth;\n meshCpu[48 + 5] = mesh.textureHeight;\n meshCpu[48 + 6] = 1;\n\n const meshBG = device.createBindGroup({\n label: \"gs-picking-mesh-bg\",\n layout: cache.meshBGL,\n entries: [\n { binding: 0, resource: { buffer: meshUbo } },\n { binding: 1, resource: mesh._gs._sampler },\n { binding: 2, resource: mesh._gs._centersView },\n { binding: 3, resource: mesh._gs._covAView },\n { binding: 4, resource: mesh._gs._covBView },\n { binding: 5, resource: mesh._gs._colorsView },\n ],\n });\n\n const pickingUbo = device.createBuffer({ size: 16, usage: BU.UNIFORM | BU.COPY_DST, label: \"gs-picking-color-ubo\" });\n const pickingCpu = new F32(4);\n\n const pickingBG = device.createBindGroup({\n label: \"gs-picking-color-bg\",\n layout: cache.pickingBGL,\n entries: [{ binding: 0, resource: { buffer: pickingUbo } }],\n });\n\n return { meshUbo, meshBG, pickingUbo, pickingBG, meshCpu, pickingCpu };\n}\n\nexport function disposeGsPickMeshResources(res: GsPickMeshResources): void {\n res.meshUbo.destroy();\n res.pickingUbo.destroy();\n}\n\n/** Issue a pick draw for a single GS mesh. The caller must have already bound\n * the scene bind group (`pickMatrix` at group 0) on the pass; `pickId` is the\n * 24-bit pick id assigned by the picker. */\nexport function drawGsForPicking(\n pass: GPURenderPassEncoder,\n engine: EngineContext,\n scene: SceneContext,\n mesh: GaussianSplattingMesh,\n res: GsPickMeshResources,\n pickId: number,\n targetWidth: number,\n targetHeight: number\n): void {\n const cache = getCache(engine);\n\n // ── Per-mesh UBO ────────────────────────────────────────────────\n const cam = scene.camera;\n if (!cam) {\n return;\n }\n const size = getRenderTargetSize(engine);\n const aspect = (targetWidth || size.width) / (targetHeight || size.height);\n const view = getViewMatrix(cam) as unknown as Float32Array;\n const proj = getProjectionMatrix(cam, aspect) as unknown as Float32Array;\n const world = mesh.worldMatrix as unknown as Float32Array;\n const cpu = res.meshCpu;\n cpu.set(world, 0);\n cpu.set(view, 16);\n cpu.set(proj, 32);\n // Note: the GS picking pipeline still runs over the full-canvas viewport;\n // the picker output is a 1×1 target reached via the scene pickMatrix.\n cpu[48] = size.width;\n cpu[48 + 1] = size.height;\n cpu[48 + 2] = size.width * 0.5 * proj[0]!;\n cpu[48 + 3] = size.height * 0.5 * proj[5]!;\n // dataSize/alpha already written at construction.\n engine._device.queue.writeBuffer(res.meshUbo, 0, cpu.buffer, 0, cpu.byteLength);\n\n // ── Picking-color UBO ───────────────────────────────────────────\n const [r, g, b] = encodeIdToColor(pickId);\n res.pickingCpu[0] = r;\n res.pickingCpu[1] = g;\n res.pickingCpu[2] = b;\n res.pickingCpu[3] = 0;\n engine._device.queue.writeBuffer(res.pickingUbo, 0, res.pickingCpu.buffer, 0, 16);\n\n pass.setPipeline(cache.pipeline);\n pass.setBindGroup(1, res.meshBG);\n pass.setBindGroup(2, res.pickingBG);\n pass.setVertexBuffer(0, mesh._gs._quadBuffer);\n pass.setVertexBuffer(1, mesh._gs._splatIndexBuffer);\n pass.setIndexBuffer(mesh._gs._indexBuffer, \"uint16\");\n pass.drawIndexed(6, mesh.vertexCount);\n}\n\n/** Compute the pickMatrix for GS picking — same matrix `computePickVP` builds,\n * but applied to the clip-space output of the GS shader rather than the world.\n *\n * Maps canvas-NDC (px, py) ↦ (0, 0), and scales by (w, h) so a single canvas\n * pixel covers the full 1×1 pick render target. */\nexport function computeGsPickMatrix(out: Float32Array, px: number, py: number, w: number, h: number): void {\n const ndcX = (2 * (px + 0.5)) / w - 1;\n const ndcY = 1 - (2 * (py + 0.5)) / h;\n // column-major mat4\n out[0] = w;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = h;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = -ndcX * w;\n out[13] = -ndcY * h;\n out[14] = 0;\n out[15] = 1;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ab as PhysicsMotionType } from "./index-C2sM8ERH.js";
|
|
2
2
|
function createHavokFloatingOriginContext(hkWorld, gravity, radius) {
|
|
3
3
|
return {
|
|
4
4
|
regions: [{ _world: hkWorld, origin: { x: 0, y: 0, z: 0 }, gravity: [...gravity] }],
|
|
@@ -195,4 +195,4 @@ function _syncNodeToBody(hknp, body) {
|
|
|
195
195
|
export {
|
|
196
196
|
createHavokFloatingOriginContext
|
|
197
197
|
};
|
|
198
|
-
//# sourceMappingURL=havok-floating-origin-
|
|
198
|
+
//# sourceMappingURL=havok-floating-origin-CQ7yE-XD.js.map
|