@babylonjs/lite 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_math-factory-C-QqW-Wi.js +55 -0
- package/_math-factory-C-QqW-Wi.js.map +1 -0
- package/add-block-CikX5gWy.js +6 -0
- package/add-block-CikX5gWy.js.map +1 -0
- package/alpha-test-fragment-CUiHCw7W.js +22 -0
- package/alpha-test-fragment-CUiHCw7W.js.map +1 -0
- package/ambient-occlusion-block-DForhWL3.js +77 -0
- package/ambient-occlusion-block-DForhWL3.js.map +1 -0
- package/anisotropy-block-D5fXH_OY.js +12 -0
- package/anisotropy-block-D5fXH_OY.js.map +1 -0
- package/anisotropy-fragment-HgasXS7l.js +89 -0
- package/anisotropy-fragment-HgasXS7l.js.map +1 -0
- package/arc-tan2-block-d8sWt_x0.js +12 -0
- package/arc-tan2-block-d8sWt_x0.js.map +1 -0
- package/assets/splat-sort-worker-Crg3CaCc.js.map +1 -0
- package/background-dds-skybox-yHTqabU3.js +221 -0
- package/background-dds-skybox-yHTqabU3.js.map +1 -0
- package/background-ground-DIw6D3qf.js +235 -0
- package/background-ground-DIw6D3qf.js.map +1 -0
- package/background-hdr-skybox-c4uuTmkP.js +179 -0
- package/background-hdr-skybox-c4uuTmkP.js.map +1 -0
- package/background-solid-skybox-DPGBpPbm.js +235 -0
- package/background-solid-skybox-DPGBpPbm.js.map +1 -0
- package/bake-local-matrix-Dfpd3b06.js +28 -0
- package/bake-local-matrix-Dfpd3b06.js.map +1 -0
- package/billboard-renderable-D8mlVGCd.js +242 -0
- package/billboard-renderable-D8mlVGCd.js.map +1 -0
- package/biplanar-block-DZnKuV81.js +115 -0
- package/biplanar-block-DZnKuV81.js.map +1 -0
- package/bones-block-D6IhqUVV.js +31 -0
- package/bones-block-D6IhqUVV.js.map +1 -0
- package/clamp-block-BdII67hT.js +21 -0
- package/clamp-block-BdII67hT.js.map +1 -0
- package/clearcoat-block-BGML4npi.js +12 -0
- package/clearcoat-block-BGML4npi.js.map +1 -0
- package/clearcoat-fragment-LCiG98Rf.js +256 -0
- package/clearcoat-fragment-LCiG98Rf.js.map +1 -0
- package/clip-planes-block-BPfFJrbf.js +26 -0
- package/clip-planes-block-BPfFJrbf.js.map +1 -0
- package/cloud-block-BeVrangc.js +90 -0
- package/cloud-block-BeVrangc.js.map +1 -0
- package/color-converter-block-CvwKiW4k.js +123 -0
- package/color-converter-block-CvwKiW4k.js.map +1 -0
- package/color-merger-CCu21ZII.js +57 -0
- package/color-merger-CCu21ZII.js.map +1 -0
- package/color-splitter-CGn1G4ow.js +33 -0
- package/color-splitter-CGn1G4ow.js.map +1 -0
- package/conditional-block-Cd2pbejI.js +51 -0
- package/conditional-block-Cd2pbejI.js.map +1 -0
- package/create-skeleton-C9JdIJnb.js +44 -0
- package/create-skeleton-C9JdIJnb.js.map +1 -0
- package/cross-block-DCrLwCpt.js +12 -0
- package/cross-block-DCrLwCpt.js.map +1 -0
- package/cubemap-skybox-material-DvXMVc4k.js +79 -0
- package/cubemap-skybox-material-DvXMVc4k.js.map +1 -0
- package/curve-block-BlJpXVYv.js +89 -0
- package/curve-block-BlJpXVYv.js.map +1 -0
- package/debug-block-D2pg4Yf6.js +14 -0
- package/debug-block-D2pg4Yf6.js.map +1 -0
- package/derivative-block-B8KjtaWs.js +20 -0
- package/derivative-block-B8KjtaWs.js.map +1 -0
- package/desaturate-block-C1RghNSB.js +15 -0
- package/desaturate-block-C1RghNSB.js.map +1 -0
- package/discard-block-B2jKjaEL.js +21 -0
- package/discard-block-B2jKjaEL.js.map +1 -0
- package/distance-block-3NkgFZ3f.js +16 -0
- package/distance-block-3NkgFZ3f.js.map +1 -0
- package/divide-block-ZyepIg_-.js +6 -0
- package/divide-block-ZyepIg_-.js.map +1 -0
- package/dot-block-VlfAC6cD.js +16 -0
- package/dot-block-VlfAC6cD.js.map +1 -0
- package/elbow-block-NEOiIxzO.js +10 -0
- package/elbow-block-NEOiIxzO.js.map +1 -0
- package/emissive-fragment-BnNvbBCw.js +39 -0
- package/emissive-fragment-BnNvbBCw.js.map +1 -0
- package/esm-shadow-view-DGKdF1NI.js +18 -0
- package/esm-shadow-view-DGKdF1NI.js.map +1 -0
- package/esm-shadow-view-DN9HIaM4.js +15 -0
- package/esm-shadow-view-DN9HIaM4.js.map +1 -0
- package/esm-shadow-view-Dk9NFtLq.js +15 -0
- package/esm-shadow-view-Dk9NFtLq.js.map +1 -0
- package/fog-block-DJ9hEolm.js +41 -0
- package/fog-block-DJ9hEolm.js.map +1 -0
- package/frag-coord-block-DzXfFgfV.js +25 -0
- package/frag-coord-block-DzXfFgfV.js.map +1 -0
- package/frag-depth-block-UQbeKP2D.js +34 -0
- package/frag-depth-block-UQbeKP2D.js.map +1 -0
- package/fragment-output-BOphkIeh.js +26 -0
- package/fragment-output-BOphkIeh.js.map +1 -0
- package/fresnel-block-DefHWeO-.js +20 -0
- package/fresnel-block-DefHWeO-.js.map +1 -0
- package/front-facing-0d6aiyrv.js +11 -0
- package/front-facing-0d6aiyrv.js.map +1 -0
- package/gaussian-splatting-pipeline-sh-DgJl7l56.js +500 -0
- package/gaussian-splatting-pipeline-sh-DgJl7l56.js.map +1 -0
- package/gltf-animation-D7uyTyO3.js +245 -0
- package/gltf-animation-D7uyTyO3.js.map +1 -0
- package/gltf-ext-anisotropy-CknJiJK8.js +22 -0
- package/gltf-ext-anisotropy-CknJiJK8.js.map +1 -0
- package/gltf-ext-basisu-CPg5kPrx.js +452 -0
- package/gltf-ext-basisu-CPg5kPrx.js.map +1 -0
- package/gltf-ext-clearcoat-CLH2SVph.js +31 -0
- package/gltf-ext-clearcoat-CLH2SVph.js.map +1 -0
- package/gltf-ext-dielectric-qHzlnvdl.js +105 -0
- package/gltf-ext-dielectric-qHzlnvdl.js.map +1 -0
- package/gltf-ext-emissive-strength-nzGZXZVK.js +19 -0
- package/gltf-ext-emissive-strength-nzGZXZVK.js.map +1 -0
- package/gltf-ext-iridescence-C6bq7jiM.js +26 -0
- package/gltf-ext-iridescence-C6bq7jiM.js.map +1 -0
- package/gltf-ext-node-visibility-MafA9ot2.js +25 -0
- package/gltf-ext-node-visibility-MafA9ot2.js.map +1 -0
- package/gltf-ext-orm-CT18G_vQ.js +33 -0
- package/gltf-ext-orm-CT18G_vQ.js.map +1 -0
- package/gltf-ext-quantization-CpZyLDIz.js +94 -0
- package/gltf-ext-quantization-CpZyLDIz.js.map +1 -0
- package/gltf-ext-sheen-BgIxUzyZ.js +25 -0
- package/gltf-ext-sheen-BgIxUzyZ.js.map +1 -0
- package/gltf-ext-spec-gloss-D0LJLBUM.js +24 -0
- package/gltf-ext-spec-gloss-D0LJLBUM.js.map +1 -0
- package/gltf-ext-unlit-D2ANui0V.js +16 -0
- package/gltf-ext-unlit-D2ANui0V.js.map +1 -0
- package/gltf-ext-uv-transform-CE_-T1Tr.js +38 -0
- package/gltf-ext-uv-transform-CE_-T1Tr.js.map +1 -0
- package/gltf-feature-animation-pointer-BjpwOOqo.js +88 -0
- package/gltf-feature-animation-pointer-BjpwOOqo.js.map +1 -0
- package/gltf-feature-animations-CCizegp8.js +15 -0
- package/gltf-feature-animations-CCizegp8.js.map +1 -0
- package/gltf-feature-draco-yGSMGTE3.js +124 -0
- package/gltf-feature-draco-yGSMGTE3.js.map +1 -0
- package/gltf-feature-gpu-instancing-2e_CFQnl.js +151 -0
- package/gltf-feature-gpu-instancing-2e_CFQnl.js.map +1 -0
- package/gltf-feature-lights-punctual-DDDg4j0U.js +71 -0
- package/gltf-feature-lights-punctual-DDDg4j0U.js.map +1 -0
- package/gltf-feature-meshopt-Des96YFI.js +84 -0
- package/gltf-feature-meshopt-Des96YFI.js.map +1 -0
- package/gltf-feature-morph-CKCw6tkX.js +29 -0
- package/gltf-feature-morph-CKCw6tkX.js.map +1 -0
- package/gltf-feature-skeleton-D8hWLqi2.js +36 -0
- package/gltf-feature-skeleton-D8hWLqi2.js.map +1 -0
- package/gltf-feature-variants-Ds6v9byg.js +17 -0
- package/gltf-feature-variants-Ds6v9byg.js.map +1 -0
- package/gltf-feature-xmp-BUfq_IVG.js +15 -0
- package/gltf-feature-xmp-BUfq_IVG.js.map +1 -0
- package/gltf-glb-parser-D6UZWFuC.js +27 -0
- package/gltf-glb-parser-D6UZWFuC.js.map +1 -0
- package/gltf-interleave-DGnUlz28.js +241 -0
- package/gltf-interleave-DGnUlz28.js.map +1 -0
- package/gltf-pbr-builder-ext-BFOxOCnQ.js +85 -0
- package/gltf-pbr-builder-ext-BFOxOCnQ.js.map +1 -0
- package/gltf-variants-DFbr8EES.js +88 -0
- package/gltf-variants-DFbr8EES.js.map +1 -0
- package/gradient-block-DL_60sDc.js +50 -0
- package/gradient-block-DL_60sDc.js.map +1 -0
- package/gs-picking-pipeline-DzfMASL9.js +280 -0
- package/gs-picking-pipeline-DzfMASL9.js.map +1 -0
- package/height-to-normal-block-DhPHkDFg.js +65 -0
- package/height-to-normal-block-DhPHkDFg.js.map +1 -0
- package/ibl-fragment-DqQVi8k0.js +91 -0
- package/ibl-fragment-DqQVi8k0.js.map +1 -0
- package/ibl-skybox-wgsl-DCah0kWV.js +13 -0
- package/ibl-skybox-wgsl-DCah0kWV.js.map +1 -0
- package/image-processing-block-DwrhhmuF.js +40 -0
- package/image-processing-block-DwrhhmuF.js.map +1 -0
- package/image-source-BuMJgd9-.js +17 -0
- package/image-source-BuMJgd9-.js.map +1 -0
- package/index-C8HOR2sB.js +19222 -0
- package/index-C8HOR2sB.js.map +1 -0
- package/index.d.ts +4611 -0
- package/index.js +309 -0
- package/index.js.map +1 -0
- package/input-block-DgAJBzN_.js +109 -0
- package/input-block-DgAJBzN_.js.map +1 -0
- package/instances-block-BaSSiz8m.js +12 -0
- package/instances-block-BaSSiz8m.js.map +1 -0
- package/iridescence-block-B0pRFoOU.js +67 -0
- package/iridescence-block-B0pRFoOU.js.map +1 -0
- package/iridescence-fragment-Gymp7or5.js +243 -0
- package/iridescence-fragment-Gymp7or5.js.map +1 -0
- package/length-block-ChOkeiHR.js +11 -0
- package/length-block-ChOkeiHR.js.map +1 -0
- package/lerp-block-DjI2SfmI.js +18 -0
- package/lerp-block-DjI2SfmI.js.map +1 -0
- package/light-block-B11ew7FA.js +123 -0
- package/light-block-B11ew7FA.js.map +1 -0
- package/light-information-VJbW0jbs.js +19 -0
- package/light-information-VJbW0jbs.js.map +1 -0
- package/loop-block-Bb23EOMb.js +71 -0
- package/loop-block-Bb23EOMb.js.map +1 -0
- package/manifold-AS8POaOr.js +3022 -0
- package/manifold-AS8POaOr.js.map +1 -0
- package/manifold-RCa7RkKz.js +5 -0
- package/manifold-RCa7RkKz.js.map +1 -0
- package/matrix-blocks-acWn_V6g.js +51 -0
- package/matrix-blocks-acWn_V6g.js.map +1 -0
- package/max-block-CjFgljZ7.js +6 -0
- package/max-block-CjFgljZ7.js.map +1 -0
- package/mesh-attribute-exists-block-BfK8UiSL.js +44 -0
- package/mesh-attribute-exists-block-BfK8UiSL.js.map +1 -0
- package/mesh-features-BLENkYVt.js +341 -0
- package/mesh-features-BLENkYVt.js.map +1 -0
- package/min-block-CHtBngNl.js +6 -0
- package/min-block-CHtBngNl.js.map +1 -0
- package/mod-block-Ceizv8Y7.js +6 -0
- package/mod-block-Ceizv8Y7.js.map +1 -0
- package/morph-fragment-DOVo70gP.js +59 -0
- package/morph-fragment-DOVo70gP.js.map +1 -0
- package/morph-targets-55z342ZB.js +35 -0
- package/morph-targets-55z342ZB.js.map +1 -0
- package/multilight-wgsl-BGyiIOp3.js +112 -0
- package/multilight-wgsl-BGyiIOp3.js.map +1 -0
- package/multiply-block-DaXLJ7Ud.js +6 -0
- package/multiply-block-DaXLJ7Ud.js.map +1 -0
- package/negate-block-9CSLc5pM.js +6 -0
- package/negate-block-9CSLc5pM.js.map +1 -0
- package/nlerp-block-BNK1adIb.js +21 -0
- package/nlerp-block-BNK1adIb.js.map +1 -0
- package/node-env-BPZXZzBf.js +39 -0
- package/node-env-BPZXZzBf.js.map +1 -0
- package/node-registry-DwgC4yth.js +190 -0
- package/node-registry-DwgC4yth.js.map +1 -0
- package/node-registry-extra-advanced-2DJVt67-.js +45 -0
- package/node-registry-extra-advanced-2DJVt67-.js.map +1 -0
- package/node-registry-extra-compat-Dhrw8fDQ.js +41 -0
- package/node-registry-extra-compat-Dhrw8fDQ.js.map +1 -0
- package/node-registry-extra-math-CsAHvIZo.js +49 -0
- package/node-registry-extra-math-CsAHvIZo.js.map +1 -0
- package/node-registry-extra-procedural-5pLQ3Bhz.js +45 -0
- package/node-registry-extra-procedural-5pLQ3Bhz.js.map +1 -0
- package/node-renderable-DlLIdBmd.js +269 -0
- package/node-renderable-DlLIdBmd.js.map +1 -0
- package/node-shadow-DKrcqmNg.js +122 -0
- package/node-shadow-DKrcqmNg.js.map +1 -0
- package/node-snippet-DUMm9qEO.js +22 -0
- package/node-snippet-DUMm9qEO.js.map +1 -0
- package/normal-blend-block-BfH_nBoj.js +29 -0
- package/normal-blend-block-BfH_nBoj.js.map +1 -0
- package/normal-map-fragment-DpsIXrJf.js +38 -0
- package/normal-map-fragment-DpsIXrJf.js.map +1 -0
- package/normalize-block-F2bLNj9K.js +6 -0
- package/normalize-block-F2bLNj9K.js.map +1 -0
- package/oneminus-block-BP9x4Dc3.js +6 -0
- package/oneminus-block-BP9x4Dc3.js.map +1 -0
- package/opposite-block-Cnqmm-lH.js +6 -0
- package/opposite-block-Cnqmm-lH.js.map +1 -0
- package/package.json +26 -0
- package/panner-block-BwMQq-6Y.js +13 -0
- package/panner-block-BwMQq-6Y.js.map +1 -0
- package/parse-camera-DM3oJJeT.js +23 -0
- package/parse-camera-DM3oJJeT.js.map +1 -0
- package/pbr-aces-wgsl-HpiQHGN_.js +13 -0
- package/pbr-aces-wgsl-HpiQHGN_.js.map +1 -0
- package/pbr-metallic-roughness-block-full-6vMm1Jk6.js +763 -0
- package/pbr-metallic-roughness-block-full-6vMm1Jk6.js.map +1 -0
- package/pbr-metallic-roughness-block-h_KAOZrW.js +104 -0
- package/pbr-metallic-roughness-block-h_KAOZrW.js.map +1 -0
- package/pbr-mr-helper-core-CIwm-T1G.js +237 -0
- package/pbr-mr-helper-core-CIwm-T1G.js.map +1 -0
- package/pbr-refraction-DGmMSa2v.js +17 -0
- package/pbr-refraction-DGmMSa2v.js.map +1 -0
- package/pbr-renderable-BJxUtPBb.js +961 -0
- package/pbr-renderable-BJxUtPBb.js.map +1 -0
- package/pbr-shadow-fragment-LO9SlbJj.js +14 -0
- package/pbr-shadow-fragment-LO9SlbJj.js.map +1 -0
- package/pbr-template-ext-8q7BcTDf.js +88 -0
- package/pbr-template-ext-8q7BcTDf.js.map +1 -0
- package/pbr-tracking-B3alzn91.js +31 -0
- package/pbr-tracking-B3alzn91.js.map +1 -0
- package/pbr-transmission-ext-BxW4CEGu.js +581 -0
- package/pbr-transmission-ext-BxW4CEGu.js.map +1 -0
- package/perturb-normal-0Q8EM9ig.js +39 -0
- package/perturb-normal-0Q8EM9ig.js.map +1 -0
- package/posterize-block-DfdKsbEf.js +28 -0
- package/posterize-block-DfdKsbEf.js.map +1 -0
- package/pow-block-DI5ICzhc.js +13 -0
- package/pow-block-DI5ICzhc.js.map +1 -0
- package/random-number-block-2OyRYljF.js +15 -0
- package/random-number-block-2OyRYljF.js.map +1 -0
- package/reciprocal-block-Ck3CW-j-.js +14 -0
- package/reciprocal-block-Ck3CW-j-.js.map +1 -0
- package/reflect-block-CizpzrX4.js +12 -0
- package/reflect-block-CizpzrX4.js.map +1 -0
- package/reflectance-fragment-BCrgPmrt.js +143 -0
- package/reflectance-fragment-BCrgPmrt.js.map +1 -0
- package/reflection-block-DqcwyYqr.js +12 -0
- package/reflection-block-DqcwyYqr.js.map +1 -0
- package/reflection-texture-base-block-1xmJ0HDj.js +10 -0
- package/reflection-texture-base-block-1xmJ0HDj.js.map +1 -0
- package/reflection-texture-block-C3QtzoV8.js +60 -0
- package/reflection-texture-block-C3QtzoV8.js.map +1 -0
- package/refract-block-HHiAk-7U.js +13 -0
- package/refract-block-HHiAk-7U.js.map +1 -0
- package/refraction-block-U8y6XiXs.js +11 -0
- package/refraction-block-U8y6XiXs.js.map +1 -0
- package/refraction-dispersion-wgsl-DdQCyyO1.js +16 -0
- package/refraction-dispersion-wgsl-DdQCyyO1.js.map +1 -0
- package/remap-block-DxK1W1vp.js +27 -0
- package/remap-block-DxK1W1vp.js.map +1 -0
- package/replace-color-block-1m--hiru.js +17 -0
- package/replace-color-block-1m--hiru.js.map +1 -0
- package/rgbd-decode-DCvzUYeI.js +110 -0
- package/rgbd-decode-DCvzUYeI.js.map +1 -0
- package/rotate2d-block-nEe1N2MJ.js +15 -0
- package/rotate2d-block-nEe1N2MJ.js.map +1 -0
- package/scale-block-C5Z8159G.js +13 -0
- package/scale-block-C5Z8159G.js.map +1 -0
- package/scene-material-swap-C2ykv55W.js +34 -0
- package/scene-material-swap-C2ykv55W.js.map +1 -0
- package/screen-size-block-BVNnOvE8.js +21 -0
- package/screen-size-block-BVNnOvE8.js.map +1 -0
- package/screen-space-block-CwaxdfSe.js +28 -0
- package/screen-space-block-CwaxdfSe.js.map +1 -0
- package/shader-renderable-D-6796KR.js +531 -0
- package/shader-renderable-D-6796KR.js.map +1 -0
- package/shadow-fragment-core-DHN2G6FI.js +110 -0
- package/shadow-fragment-core-DHN2G6FI.js.map +1 -0
- package/shadow-map-CQNQC-Fw.js +13 -0
- package/shadow-map-CQNQC-Fw.js.map +1 -0
- package/sheen-block-BugfJqK3.js +12 -0
- package/sheen-block-BugfJqK3.js.map +1 -0
- package/sheen-fragment-Dze2f7XJ.js +215 -0
- package/sheen-fragment-Dze2f7XJ.js.map +1 -0
- package/simplex-perlin-3d-block-CcMtofzV.js +58 -0
- package/simplex-perlin-3d-block-CcMtofzV.js.map +1 -0
- package/singlelight-directional-wgsl-CmUDZxwz.js +39 -0
- package/singlelight-directional-wgsl-CmUDZxwz.js.map +1 -0
- package/singlelight-hemispheric-wgsl-t-83IP_s.js +40 -0
- package/singlelight-hemispheric-wgsl-t-83IP_s.js.map +1 -0
- package/singlelight-point-wgsl-CLzULIYV.js +45 -0
- package/singlelight-point-wgsl-CLzULIYV.js.map +1 -0
- package/singlelight-spot-wgsl-DEEUrfVM.js +47 -0
- package/singlelight-spot-wgsl-DEEUrfVM.js.map +1 -0
- package/skeleton-fragment-B_XlFbtx.js +71 -0
- package/skeleton-fragment-B_XlFbtx.js.map +1 -0
- package/skybox-renderable-DDwzu-PT.js +92 -0
- package/skybox-renderable-DDwzu-PT.js.map +1 -0
- package/skybox.vertex-DJgi072W.js +5 -0
- package/skybox.vertex-DJgi072W.js.map +1 -0
- package/smoothstep-block-Di4t37x-.js +15 -0
- package/smoothstep-block-Di4t37x-.js.map +1 -0
- package/splat-ply-compressed-BahdBG1r.js +394 -0
- package/splat-ply-compressed-BahdBG1r.js.map +1 -0
- package/standard-renderable-GjxL9xSf.js +636 -0
- package/standard-renderable-GjxL9xSf.js.map +1 -0
- package/std-ambient-fragment-BoUsD06w.js +37 -0
- package/std-ambient-fragment-BoUsD06w.js.map +1 -0
- package/std-cube-reflection-fragment-ulqc3bsP.js +31 -0
- package/std-cube-reflection-fragment-ulqc3bsP.js.map +1 -0
- package/std-emissive-fragment-DNGj1HdQ.js +40 -0
- package/std-emissive-fragment-DNGj1HdQ.js.map +1 -0
- package/std-lightmap-fragment-Bqj89aIe.js +37 -0
- package/std-lightmap-fragment-Bqj89aIe.js.map +1 -0
- package/std-opacity-fragment-KuPh5N2Z.js +37 -0
- package/std-opacity-fragment-KuPh5N2Z.js.map +1 -0
- package/std-reflection-fragment-BA5Ghn_M.js +57 -0
- package/std-reflection-fragment-BA5Ghn_M.js.map +1 -0
- package/std-shadow-fragment-FNQfrJuC.js +8 -0
- package/std-shadow-fragment-FNQfrJuC.js.map +1 -0
- package/std-specular-fragment-CE-6scqd.js +37 -0
- package/std-specular-fragment-CE-6scqd.js.map +1 -0
- package/std-tracking-CNKZ-hJN.js +15 -0
- package/std-tracking-CNKZ-hJN.js.map +1 -0
- package/step-block-BkywzTYm.js +13 -0
- package/step-block-BkywzTYm.js.map +1 -0
- package/storage-read-block-BdzhJfln.js +25 -0
- package/storage-read-block-BdzhJfln.js.map +1 -0
- package/storage-write-block-DjLKZ0Ro.js +11 -0
- package/storage-write-block-DjLKZ0Ro.js.map +1 -0
- package/subsurface-block-CBhxT9ui.js +12 -0
- package/subsurface-block-CBhxT9ui.js.map +1 -0
- package/subsurface-fragment-liM3y2-P.js +158 -0
- package/subsurface-fragment-liM3y2-P.js.map +1 -0
- package/subtract-block-NPfKvzQP.js +6 -0
- package/subtract-block-NPfKvzQP.js.map +1 -0
- package/swapchain-overlay-DcCSFDp7.js +35 -0
- package/swapchain-overlay-DcCSFDp7.js.map +1 -0
- package/tbn-block-ByOI6Y43.js +43 -0
- package/tbn-block-ByOI6Y43.js.map +1 -0
- package/teleport-in-block-BMa17cqq.js +10 -0
- package/teleport-in-block-BMa17cqq.js.map +1 -0
- package/teleport-out-block-5AkB25H6.js +19 -0
- package/teleport-out-block-5AkB25H6.js.map +1 -0
- package/texture-block-rr21KIL_.js +70 -0
- package/texture-block-rr21KIL_.js.map +1 -0
- package/thin-instance-fragment-hsv-RyDs.js +69 -0
- package/thin-instance-fragment-hsv-RyDs.js.map +1 -0
- package/thin-instance-gpu-C9Gv_Z1w.js +62 -0
- package/thin-instance-gpu-C9Gv_Z1w.js.map +1 -0
- package/tracking-primitives-wgdBY85t.js +82 -0
- package/tracking-primitives-wgdBY85t.js.map +1 -0
- package/transform-block-DbRph9JI.js +32 -0
- package/transform-block-DbRph9JI.js.map +1 -0
- package/trigonometry-block-BYQcTHiD.js +36 -0
- package/trigonometry-block-BYQcTHiD.js.map +1 -0
- package/triplanar-block-BZHkD9hX.js +148 -0
- package/triplanar-block-BZHkD9hX.js.map +1 -0
- package/twirl-block-78WtdiBd.js +39 -0
- package/twirl-block-78WtdiBd.js.map +1 -0
- package/unlit-fragment-BIlhJpz6.js +43 -0
- package/unlit-fragment-BIlhJpz6.js.map +1 -0
- package/uv-transform-fragment-hYujGpZg.js +47 -0
- package/uv-transform-fragment-hYujGpZg.js.map +1 -0
- package/vector-merger-CrW-ONB0.js +43 -0
- package/vector-merger-CrW-ONB0.js.map +1 -0
- package/vector-splitter-BoJuHrAU.js +34 -0
- package/vector-splitter-BoJuHrAU.js.map +1 -0
- package/vertex-output-Cvft64y0.js +14 -0
- package/vertex-output-Cvft64y0.js.map +1 -0
- package/view-direction-CWVucfnT.js +12 -0
- package/view-direction-CWVucfnT.js.map +1 -0
- package/voronoi-noise-block-iNQxa_Ls.js +43 -0
- package/voronoi-noise-block-iNQxa_Ls.js.map +1 -0
- package/wave-block-CY_mk1ec.js +41 -0
- package/wave-block-CY_mk1ec.js.map +1 -0
- package/wgsl-helpers-DyzNzCeE.js +48 -0
- package/wgsl-helpers-DyzNzCeE.js.map +1 -0
- package/worley-noise-3d-block-CyR2-k4s.js +58 -0
- package/worley-noise-3d-block-CyR2-k4s.js.map +1 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { J as getRenderTargetSize, K as getViewMatrix, L as getProjectionMatrix, W as encodeIdToColor, X as getPickingSceneBGL, H as applyGsFragments, Y as gsGpuPickingFragment } from "./index-C8HOR2sB.js";
|
|
2
|
+
let _cache = null;
|
|
3
|
+
function buildPickingWgsl() {
|
|
4
|
+
const wgsl = (
|
|
5
|
+
/* wgsl */
|
|
6
|
+
`
|
|
7
|
+
struct GsPickScene { pickMatrix: mat4x4<f32> };
|
|
8
|
+
@group(0) @binding(0) var<uniform> gsPickScene: GsPickScene;
|
|
9
|
+
|
|
10
|
+
struct U {
|
|
11
|
+
world: mat4x4<f32>,
|
|
12
|
+
view: mat4x4<f32>,
|
|
13
|
+
projection: mat4x4<f32>,
|
|
14
|
+
viewport: vec2<f32>,
|
|
15
|
+
focal: vec2<f32>,
|
|
16
|
+
dataSize: vec2<f32>,
|
|
17
|
+
alpha: f32,
|
|
18
|
+
_pad: f32,
|
|
19
|
+
};
|
|
20
|
+
@group(1) @binding(0) var<uniform> u: U;
|
|
21
|
+
@group(1) @binding(1) var samp: sampler;
|
|
22
|
+
@group(1) @binding(2) var centersTex: texture_2d<f32>;
|
|
23
|
+
@group(1) @binding(3) var covATex: texture_2d<f32>;
|
|
24
|
+
@group(1) @binding(4) var covBTex: texture_2d<f32>;
|
|
25
|
+
@group(1) @binding(5) var colorsTex: texture_2d<f32>;
|
|
26
|
+
|
|
27
|
+
struct VOut {
|
|
28
|
+
@builtin(position) pos: vec4<f32>,
|
|
29
|
+
@location(0) vColor: vec4<f32>,
|
|
30
|
+
@location(1) vPos: vec2<f32>,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
fn dataUv(idx: f32) -> vec2<f32> {
|
|
34
|
+
let y = floor(idx / u.dataSize.x);
|
|
35
|
+
let x = idx - y * u.dataSize.x;
|
|
36
|
+
return vec2<f32>((x + 0.5) / u.dataSize.x, (y + 0.5) / u.dataSize.y);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@vertex
|
|
40
|
+
fn vs(@location(0) corner: vec2<f32>, @location(1) splatIndex: f32) -> VOut {
|
|
41
|
+
var out: VOut;
|
|
42
|
+
let uv = dataUv(splatIndex);
|
|
43
|
+
let center = textureSampleLevel(centersTex, samp, uv, 0.0).xyz;
|
|
44
|
+
let color = textureSampleLevel(colorsTex, samp, uv, 0.0);
|
|
45
|
+
let covA = textureSampleLevel(covATex, samp, uv, 0.0).xyz;
|
|
46
|
+
let covB = textureSampleLevel(covBTex, samp, uv, 0.0).xyz;
|
|
47
|
+
|
|
48
|
+
let worldPos = u.world * vec4<f32>(center, 1.0);
|
|
49
|
+
let modelView = u.view * u.world;
|
|
50
|
+
let camspace = u.view * worldPos;
|
|
51
|
+
let pos2d = u.projection * camspace;
|
|
52
|
+
|
|
53
|
+
let bounds = 1.2 * pos2d.w;
|
|
54
|
+
if (pos2d.z < 0.0
|
|
55
|
+
|| pos2d.x < -bounds || pos2d.x > bounds
|
|
56
|
+
|| pos2d.y < -bounds || pos2d.y > bounds) {
|
|
57
|
+
out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);
|
|
58
|
+
out.vColor = vec4<f32>(0.0);
|
|
59
|
+
out.vPos = vec2<f32>(0.0);
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let Vrk = mat3x3<f32>(
|
|
64
|
+
vec3<f32>(covA.x, covA.y, covA.z),
|
|
65
|
+
vec3<f32>(covA.y, covB.x, covB.y),
|
|
66
|
+
vec3<f32>(covA.z, covB.y, covB.z));
|
|
67
|
+
|
|
68
|
+
let invZ = 1.0 / camspace.z;
|
|
69
|
+
let invZ2 = invZ * invZ;
|
|
70
|
+
let J = mat3x3<f32>(
|
|
71
|
+
vec3<f32>(u.focal.x * invZ, 0.0, -u.focal.x * camspace.x * invZ2),
|
|
72
|
+
vec3<f32>(0.0, u.focal.y * invZ, -u.focal.y * camspace.y * invZ2),
|
|
73
|
+
vec3<f32>(0.0, 0.0, 0.0));
|
|
74
|
+
|
|
75
|
+
let mv3 = mat3x3<f32>(modelView[0].xyz, modelView[1].xyz, modelView[2].xyz);
|
|
76
|
+
let T = transpose(mv3) * J;
|
|
77
|
+
var cov2d = transpose(T) * Vrk * T;
|
|
78
|
+
|
|
79
|
+
let kernelSize: f32 = 0.3;
|
|
80
|
+
cov2d[0][0] += kernelSize;
|
|
81
|
+
cov2d[1][1] += kernelSize;
|
|
82
|
+
|
|
83
|
+
let mid = (cov2d[0][0] + cov2d[1][1]) * 0.5;
|
|
84
|
+
let dxy = (cov2d[0][0] - cov2d[1][1]) * 0.5;
|
|
85
|
+
let radius = length(vec2<f32>(dxy, cov2d[0][1]));
|
|
86
|
+
let epsilon: f32 = 0.0001;
|
|
87
|
+
let lambda1 = mid + radius + epsilon;
|
|
88
|
+
let lambda2 = mid - radius + epsilon;
|
|
89
|
+
if (lambda2 < 0.0) {
|
|
90
|
+
out.pos = vec4<f32>(0.0, 0.0, 2.0, 1.0);
|
|
91
|
+
out.vColor = vec4<f32>(0.0);
|
|
92
|
+
out.vPos = vec2<f32>(0.0);
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let diag = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));
|
|
97
|
+
let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diag;
|
|
98
|
+
let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diag.y, -diag.x);
|
|
99
|
+
|
|
100
|
+
let vCenter = pos2d.xy;
|
|
101
|
+
out.pos = gsPickScene.pickMatrix * vec4<f32>(
|
|
102
|
+
vCenter + (corner.x * majorAxis + corner.y * minorAxis) * pos2d.w / u.viewport,
|
|
103
|
+
pos2d.z, pos2d.w);
|
|
104
|
+
out.vColor = vec4<f32>(color.rgb, color.a * u.alpha);
|
|
105
|
+
out.vPos = corner;
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/*GS_FRAGMENT_DEFINITIONS*/
|
|
110
|
+
struct FsOut { @location(0) color: vec4<f32>, @location(1) depth: vec4<f32> };
|
|
111
|
+
@fragment
|
|
112
|
+
fn fs(in: VOut) -> FsOut {
|
|
113
|
+
/*GS_FRAGMENT_MAIN_BEGIN*/
|
|
114
|
+
let A = -dot(in.vPos, in.vPos);
|
|
115
|
+
var finalColor: vec4<f32>;
|
|
116
|
+
if (A > -4.0) {
|
|
117
|
+
let B = exp(A) * in.vColor.a;
|
|
118
|
+
finalColor = vec4<f32>(in.vColor.rgb, B);
|
|
119
|
+
} else {
|
|
120
|
+
finalColor = vec4<f32>(0.0);
|
|
121
|
+
}
|
|
122
|
+
/*GS_FRAGMENT_BEFORE_FRAGCOLOR*/
|
|
123
|
+
/*GS_FRAGMENT_MAIN_END*/
|
|
124
|
+
return FsOut(finalColor, vec4<f32>(in.pos.z, 0.0, 0.0, 0.0));
|
|
125
|
+
}
|
|
126
|
+
`
|
|
127
|
+
);
|
|
128
|
+
return applyGsFragments(wgsl, [gsGpuPickingFragment]);
|
|
129
|
+
}
|
|
130
|
+
function getCache(engine) {
|
|
131
|
+
const device = engine._device;
|
|
132
|
+
if (_cache && _cache.device === device) {
|
|
133
|
+
return _cache;
|
|
134
|
+
}
|
|
135
|
+
const meshBGL = device.createBindGroupLayout({
|
|
136
|
+
label: "gs-picking-mesh-bgl",
|
|
137
|
+
entries: [
|
|
138
|
+
{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } },
|
|
139
|
+
{ binding: 1, visibility: GPUShaderStage.VERTEX, sampler: { type: "non-filtering" } },
|
|
140
|
+
{ binding: 2, visibility: GPUShaderStage.VERTEX, texture: { sampleType: "unfilterable-float" } },
|
|
141
|
+
{ binding: 3, visibility: GPUShaderStage.VERTEX, texture: { sampleType: "unfilterable-float" } },
|
|
142
|
+
{ binding: 4, visibility: GPUShaderStage.VERTEX, texture: { sampleType: "unfilterable-float" } },
|
|
143
|
+
{ binding: 5, visibility: GPUShaderStage.VERTEX, texture: { sampleType: "unfilterable-float" } }
|
|
144
|
+
]
|
|
145
|
+
});
|
|
146
|
+
const pickingBGL = device.createBindGroupLayout({
|
|
147
|
+
label: "gs-picking-pick-bgl",
|
|
148
|
+
entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } }]
|
|
149
|
+
});
|
|
150
|
+
const module = device.createShaderModule({ label: "gs-picking-shader", code: buildPickingWgsl() });
|
|
151
|
+
const pipeline = device.createRenderPipeline({
|
|
152
|
+
label: "gs-picking-pipeline",
|
|
153
|
+
layout: device.createPipelineLayout({ bindGroupLayouts: [getPickingSceneBGL(engine), meshBGL, pickingBGL] }),
|
|
154
|
+
vertex: {
|
|
155
|
+
module,
|
|
156
|
+
entryPoint: "vs",
|
|
157
|
+
buffers: [
|
|
158
|
+
{ arrayStride: 8, stepMode: "vertex", attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }] },
|
|
159
|
+
{ arrayStride: 4, stepMode: "instance", attributes: [{ shaderLocation: 1, offset: 0, format: "float32" }] }
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
fragment: {
|
|
163
|
+
module,
|
|
164
|
+
entryPoint: "fs",
|
|
165
|
+
targets: [{ format: "rgba8unorm" }, { format: "r32float" }]
|
|
166
|
+
},
|
|
167
|
+
primitive: { topology: "triangle-list", cullMode: "none" },
|
|
168
|
+
depthStencil: { format: "depth24plus", depthCompare: "less", depthWriteEnabled: true },
|
|
169
|
+
multisample: { count: 1 }
|
|
170
|
+
});
|
|
171
|
+
const pickMatrixUbo = device.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: "gs-picking-scene-ubo" });
|
|
172
|
+
const sceneBG = device.createBindGroup({
|
|
173
|
+
label: "gs-picking-scene-bg",
|
|
174
|
+
layout: getPickingSceneBGL(engine),
|
|
175
|
+
entries: [{ binding: 0, resource: { buffer: pickMatrixUbo } }]
|
|
176
|
+
});
|
|
177
|
+
_cache = { device, pipeline, meshBGL, pickingBGL, pickMatrixUbo, sceneBG };
|
|
178
|
+
return _cache;
|
|
179
|
+
}
|
|
180
|
+
function gsPickWritePickMatrixAndBind(pass, engine, pickMatrix) {
|
|
181
|
+
const cache = getCache(engine);
|
|
182
|
+
engine._device.queue.writeBuffer(cache.pickMatrixUbo, 0, pickMatrix.buffer, pickMatrix.byteOffset, pickMatrix.byteLength);
|
|
183
|
+
pass.setBindGroup(0, cache.sceneBG);
|
|
184
|
+
}
|
|
185
|
+
function createGsPickMeshResources(engine, mesh) {
|
|
186
|
+
const device = engine._device;
|
|
187
|
+
const cache = getCache(engine);
|
|
188
|
+
const UBO_BYTES = 16 * 4 * 3 + 8 * 4;
|
|
189
|
+
const meshUbo = device.createBuffer({ size: UBO_BYTES, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: "gs-picking-mesh-ubo" });
|
|
190
|
+
const meshCpu = new Float32Array(UBO_BYTES / 4);
|
|
191
|
+
meshCpu[48 + 4] = mesh.textureWidth;
|
|
192
|
+
meshCpu[48 + 5] = mesh.textureHeight;
|
|
193
|
+
meshCpu[48 + 6] = 1;
|
|
194
|
+
const meshBG = device.createBindGroup({
|
|
195
|
+
label: "gs-picking-mesh-bg",
|
|
196
|
+
layout: cache.meshBGL,
|
|
197
|
+
entries: [
|
|
198
|
+
{ binding: 0, resource: { buffer: meshUbo } },
|
|
199
|
+
{ binding: 1, resource: mesh._gs._sampler },
|
|
200
|
+
{ binding: 2, resource: mesh._gs._centersView },
|
|
201
|
+
{ binding: 3, resource: mesh._gs._covAView },
|
|
202
|
+
{ binding: 4, resource: mesh._gs._covBView },
|
|
203
|
+
{ binding: 5, resource: mesh._gs._colorsView }
|
|
204
|
+
]
|
|
205
|
+
});
|
|
206
|
+
const pickingUbo = device.createBuffer({ size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: "gs-picking-color-ubo" });
|
|
207
|
+
const pickingCpu = new Float32Array(4);
|
|
208
|
+
const pickingBG = device.createBindGroup({
|
|
209
|
+
label: "gs-picking-color-bg",
|
|
210
|
+
layout: cache.pickingBGL,
|
|
211
|
+
entries: [{ binding: 0, resource: { buffer: pickingUbo } }]
|
|
212
|
+
});
|
|
213
|
+
return { meshUbo, meshBG, pickingUbo, pickingBG, meshCpu, pickingCpu };
|
|
214
|
+
}
|
|
215
|
+
function disposeGsPickMeshResources(res) {
|
|
216
|
+
res.meshUbo.destroy();
|
|
217
|
+
res.pickingUbo.destroy();
|
|
218
|
+
}
|
|
219
|
+
function drawGsForPicking(pass, engine, scene, mesh, res, pickId, targetWidth, targetHeight) {
|
|
220
|
+
const cache = getCache(engine);
|
|
221
|
+
const cam = scene.camera;
|
|
222
|
+
if (!cam) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const size = getRenderTargetSize(engine);
|
|
226
|
+
const aspect = (targetWidth || size.width) / (targetHeight || size.height);
|
|
227
|
+
const view = getViewMatrix(cam);
|
|
228
|
+
const proj = getProjectionMatrix(cam, aspect);
|
|
229
|
+
const world = mesh.worldMatrix;
|
|
230
|
+
const cpu = res.meshCpu;
|
|
231
|
+
cpu.set(world, 0);
|
|
232
|
+
cpu.set(view, 16);
|
|
233
|
+
cpu.set(proj, 32);
|
|
234
|
+
cpu[48] = size.width;
|
|
235
|
+
cpu[48 + 1] = size.height;
|
|
236
|
+
cpu[48 + 2] = size.width * 0.5 * proj[0];
|
|
237
|
+
cpu[48 + 3] = size.height * 0.5 * proj[5];
|
|
238
|
+
engine._device.queue.writeBuffer(res.meshUbo, 0, cpu.buffer, 0, cpu.byteLength);
|
|
239
|
+
const [r, g, b] = encodeIdToColor(pickId);
|
|
240
|
+
res.pickingCpu[0] = r;
|
|
241
|
+
res.pickingCpu[1] = g;
|
|
242
|
+
res.pickingCpu[2] = b;
|
|
243
|
+
res.pickingCpu[3] = 0;
|
|
244
|
+
engine._device.queue.writeBuffer(res.pickingUbo, 0, res.pickingCpu.buffer, 0, 16);
|
|
245
|
+
pass.setPipeline(cache.pipeline);
|
|
246
|
+
pass.setBindGroup(1, res.meshBG);
|
|
247
|
+
pass.setBindGroup(2, res.pickingBG);
|
|
248
|
+
pass.setVertexBuffer(0, mesh._gs._quadBuffer);
|
|
249
|
+
pass.setVertexBuffer(1, mesh._gs._splatIndexBuffer);
|
|
250
|
+
pass.setIndexBuffer(mesh._gs._indexBuffer, "uint16");
|
|
251
|
+
pass.drawIndexed(6, mesh.vertexCount);
|
|
252
|
+
}
|
|
253
|
+
function computeGsPickMatrix(out, px, py, w, h) {
|
|
254
|
+
const ndcX = 2 * (px + 0.5) / w - 1;
|
|
255
|
+
const ndcY = 1 - 2 * (py + 0.5) / h;
|
|
256
|
+
out[0] = w;
|
|
257
|
+
out[1] = 0;
|
|
258
|
+
out[2] = 0;
|
|
259
|
+
out[3] = 0;
|
|
260
|
+
out[4] = 0;
|
|
261
|
+
out[5] = h;
|
|
262
|
+
out[6] = 0;
|
|
263
|
+
out[7] = 0;
|
|
264
|
+
out[8] = 0;
|
|
265
|
+
out[9] = 0;
|
|
266
|
+
out[10] = 1;
|
|
267
|
+
out[11] = 0;
|
|
268
|
+
out[12] = -ndcX * w;
|
|
269
|
+
out[13] = -ndcY * h;
|
|
270
|
+
out[14] = 0;
|
|
271
|
+
out[15] = 1;
|
|
272
|
+
}
|
|
273
|
+
export {
|
|
274
|
+
computeGsPickMatrix,
|
|
275
|
+
createGsPickMeshResources,
|
|
276
|
+
disposeGsPickMeshResources,
|
|
277
|
+
drawGsForPicking,
|
|
278
|
+
gsPickWritePickMatrixAndBind
|
|
279
|
+
};
|
|
280
|
+
//# sourceMappingURL=gs-picking-pipeline-DzfMASL9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gs-picking-pipeline-DzfMASL9.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 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: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: GPUShaderStage.VERTEX, sampler: { type: \"non-filtering\" } },\n { binding: 2, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 3, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 4, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n { binding: 5, visibility: GPUShaderStage.VERTEX, texture: { sampleType: \"unfilterable-float\" } },\n ],\n });\n const pickingBGL = device.createBindGroupLayout({\n label: \"gs-picking-pick-bgl\",\n entries: [{ binding: 0, visibility: GPUShaderStage.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: GPUBufferUsage.UNIFORM | GPUBufferUsage.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: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: \"gs-picking-mesh-ubo\" });\n const meshCpu = new Float32Array(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: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, label: \"gs-picking-color-ubo\" });\n const pickingCpu = new Float32Array(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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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const HELPER_KEY = "nme_heightToNormal";
|
|
2
|
+
const HELPER_WGSL = `
|
|
3
|
+
fn nme_heightToNormal(height: f32, position: vec3<f32>, tangent: vec3<f32>, normal: vec3<f32>, generateInWorldSpace: bool, normalizeNormal: bool, normalizeTangent: bool) -> vec4<f32> {
|
|
4
|
+
let norm = select(normal, normalize(normal), normalizeNormal);
|
|
5
|
+
let tgt = select(tangent, normalize(tangent), normalizeTangent);
|
|
6
|
+
let worlddX = dpdx(position);
|
|
7
|
+
let worlddY = dpdy(position);
|
|
8
|
+
let crossX = cross(norm, worlddX);
|
|
9
|
+
let crossY = cross(worlddY, norm);
|
|
10
|
+
let d = abs(dot(crossY, worlddX));
|
|
11
|
+
var inToNormal = (((height + dpdx(height)) - height) * crossY + ((height + dpdy(height)) - height) * crossX) * sign(d);
|
|
12
|
+
inToNormal.y = -inToNormal.y;
|
|
13
|
+
var result = normalize(d * norm - inToNormal);
|
|
14
|
+
if (!generateInWorldSpace) {
|
|
15
|
+
let biTangent = cross(norm, tgt);
|
|
16
|
+
let tbn = mat3x3<f32>(tgt, biTangent, norm);
|
|
17
|
+
result = tbn * result;
|
|
18
|
+
result = result * vec3<f32>(0.5) + vec3<f32>(0.5);
|
|
19
|
+
}
|
|
20
|
+
return vec4<f32>(result, 0.0);
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
function boolLiteral(value, fallback) {
|
|
24
|
+
return (typeof value === "boolean" ? value : fallback) ? "true" : "false";
|
|
25
|
+
}
|
|
26
|
+
function emitHeightNormal(block, stage, state, ctx) {
|
|
27
|
+
const stageState = stage === "vertex" ? state.vertex : state.fragment;
|
|
28
|
+
const memoKey = `_heightToNormal_${block.id}`;
|
|
29
|
+
const existing = stageState.memo.get(memoKey);
|
|
30
|
+
if (existing) {
|
|
31
|
+
return existing;
|
|
32
|
+
}
|
|
33
|
+
state.fragment.helpers.set(HELPER_KEY, HELPER_WGSL);
|
|
34
|
+
const height = ctx.cast(ctx.resolve(block, "input", stage, state), "f32").expr;
|
|
35
|
+
const pos = ctx.cast(ctx.resolve(block, "worldPosition", stage, state), "vec3f").expr;
|
|
36
|
+
const normal = ctx.cast(ctx.resolve(block, "worldNormal", stage, state), "vec3f").expr;
|
|
37
|
+
const tangentInput = block.inputs.get("worldTangent");
|
|
38
|
+
const generateInWorldSpace = block.serialized.generateInWorldSpace === true;
|
|
39
|
+
if (!generateInWorldSpace && !(tangentInput == null ? void 0 : tangentInput.source)) {
|
|
40
|
+
throw new Error(`NodeMaterial: HeightToNormalBlock "${block.name}" requires worldTangent when generateInWorldSpace is false`);
|
|
41
|
+
}
|
|
42
|
+
const tangent = (tangentInput == null ? void 0 : tangentInput.source) ? ctx.cast(ctx.resolve(block, "worldTangent", stage, state), "vec3f").expr : "vec3<f32>(0.0)";
|
|
43
|
+
const out = `_hn${ctx.temp(state, "heightNormal")}`;
|
|
44
|
+
stageState.body.push(
|
|
45
|
+
`let ${out} = nme_heightToNormal(${height}, ${pos}, ${tangent}, ${normal}, ${boolLiteral(block.serialized.generateInWorldSpace, false)}, ${boolLiteral(block.serialized.automaticNormalizationNormal, true)}, ${boolLiteral(block.serialized.automaticNormalizationTangent, true)});`
|
|
46
|
+
);
|
|
47
|
+
const result = { expr: out, type: "vec4f" };
|
|
48
|
+
stageState.memo.set(memoKey, result);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
const emitter = {
|
|
52
|
+
className: "HeightToNormalBlock",
|
|
53
|
+
stage: "fragment",
|
|
54
|
+
emit(block, outputName, stage, state, ctx) {
|
|
55
|
+
const value = emitHeightNormal(block, stage, state, ctx);
|
|
56
|
+
if (outputName === "xyz") {
|
|
57
|
+
return { expr: `${value.expr}.xyz`, type: "vec3f" };
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
emitter
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=height-to-normal-block-DhPHkDFg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"height-to-normal-block-DhPHkDFg.js","sources":["../src/material/node/blocks/height-to-normal-block.ts"],"sourcesContent":["import type { BlockEmitter, NodeExpr } from \"../node-types.js\";\n\nconst HELPER_KEY = \"nme_heightToNormal\";\nconst HELPER_WGSL = `\nfn nme_heightToNormal(height: f32, position: vec3<f32>, tangent: vec3<f32>, normal: vec3<f32>, generateInWorldSpace: bool, normalizeNormal: bool, normalizeTangent: bool) -> vec4<f32> {\n let norm = select(normal, normalize(normal), normalizeNormal);\n let tgt = select(tangent, normalize(tangent), normalizeTangent);\n let worlddX = dpdx(position);\n let worlddY = dpdy(position);\n let crossX = cross(norm, worlddX);\n let crossY = cross(worlddY, norm);\n let d = abs(dot(crossY, worlddX));\n var inToNormal = (((height + dpdx(height)) - height) * crossY + ((height + dpdy(height)) - height) * crossX) * sign(d);\n inToNormal.y = -inToNormal.y;\n var result = normalize(d * norm - inToNormal);\n if (!generateInWorldSpace) {\n let biTangent = cross(norm, tgt);\n let tbn = mat3x3<f32>(tgt, biTangent, norm);\n result = tbn * result;\n result = result * vec3<f32>(0.5) + vec3<f32>(0.5);\n }\n return vec4<f32>(result, 0.0);\n}\n`;\n\nfunction boolLiteral(value: unknown, fallback: boolean): string {\n return (typeof value === \"boolean\" ? value : fallback) ? \"true\" : \"false\";\n}\n\nfunction emitHeightNormal(\n block: Parameters<BlockEmitter[\"emit\"]>[0],\n stage: Parameters<BlockEmitter[\"emit\"]>[2],\n state: Parameters<BlockEmitter[\"emit\"]>[3],\n ctx: Parameters<BlockEmitter[\"emit\"]>[4]\n): NodeExpr {\n const stageState = stage === \"vertex\" ? state.vertex : state.fragment;\n const memoKey = `_heightToNormal_${block.id}`;\n const existing = stageState.memo.get(memoKey);\n if (existing) {\n return existing;\n }\n\n state.fragment.helpers.set(HELPER_KEY, HELPER_WGSL);\n const height = ctx.cast(ctx.resolve(block, \"input\", stage, state), \"f32\").expr;\n const pos = ctx.cast(ctx.resolve(block, \"worldPosition\", stage, state), \"vec3f\").expr;\n const normal = ctx.cast(ctx.resolve(block, \"worldNormal\", stage, state), \"vec3f\").expr;\n const tangentInput = block.inputs.get(\"worldTangent\");\n const generateInWorldSpace = block.serialized.generateInWorldSpace === true;\n if (!generateInWorldSpace && !tangentInput?.source) {\n throw new Error(`NodeMaterial: HeightToNormalBlock \"${block.name}\" requires worldTangent when generateInWorldSpace is false`);\n }\n const tangent = tangentInput?.source ? ctx.cast(ctx.resolve(block, \"worldTangent\", stage, state), \"vec3f\").expr : \"vec3<f32>(0.0)\";\n const out = `_hn${ctx.temp(state, \"heightNormal\")}`;\n stageState.body.push(\n `let ${out} = nme_heightToNormal(${height}, ${pos}, ${tangent}, ${normal}, ${boolLiteral(block.serialized.generateInWorldSpace, false)}, ${boolLiteral(block.serialized.automaticNormalizationNormal, true)}, ${boolLiteral(block.serialized.automaticNormalizationTangent, true)});`\n );\n const result = { expr: out, type: \"vec4f\" } as const;\n stageState.memo.set(memoKey, result);\n return result;\n}\n\nexport const emitter: BlockEmitter = {\n className: \"HeightToNormalBlock\",\n stage: \"fragment\",\n emit(block, outputName, stage, state, ctx) {\n const value = emitHeightNormal(block, stage, state, ctx);\n if (outputName === \"xyz\") {\n return { expr: `${value.expr}.xyz`, type: \"vec3f\" };\n }\n return value;\n },\n};\n"],"names":[],"mappings":"AAEA,MAAM,aAAa;AACnB,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBpB,SAAS,YAAY,OAAgB,UAA2B;AAC5D,UAAQ,OAAO,UAAU,YAAY,QAAQ,YAAY,SAAS;AACtE;AAEA,SAAS,iBACL,OACA,OACA,OACA,KACQ;AACR,QAAM,aAAa,UAAU,WAAW,MAAM,SAAS,MAAM;AAC7D,QAAM,UAAU,mBAAmB,MAAM,EAAE;AAC3C,QAAM,WAAW,WAAW,KAAK,IAAI,OAAO;AAC5C,MAAI,UAAU;AACV,WAAO;AAAA,EACX;AAEA,QAAM,SAAS,QAAQ,IAAI,YAAY,WAAW;AAClD,QAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,OAAO,SAAS,OAAO,KAAK,GAAG,KAAK,EAAE;AAC1E,QAAM,MAAM,IAAI,KAAK,IAAI,QAAQ,OAAO,iBAAiB,OAAO,KAAK,GAAG,OAAO,EAAE;AACjF,QAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,OAAO,eAAe,OAAO,KAAK,GAAG,OAAO,EAAE;AAClF,QAAM,eAAe,MAAM,OAAO,IAAI,cAAc;AACpD,QAAM,uBAAuB,MAAM,WAAW,yBAAyB;AACvE,MAAI,CAAC,wBAAwB,EAAC,6CAAc,SAAQ;AAChD,UAAM,IAAI,MAAM,sCAAsC,MAAM,IAAI,4DAA4D;AAAA,EAChI;AACA,QAAM,WAAU,6CAAc,UAAS,IAAI,KAAK,IAAI,QAAQ,OAAO,gBAAgB,OAAO,KAAK,GAAG,OAAO,EAAE,OAAO;AAClH,QAAM,MAAM,MAAM,IAAI,KAAK,OAAO,cAAc,CAAC;AACjD,aAAW,KAAK;AAAA,IACZ,OAAO,GAAG,yBAAyB,MAAM,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM,KAAK,YAAY,MAAM,WAAW,sBAAsB,KAAK,CAAC,KAAK,YAAY,MAAM,WAAW,8BAA8B,IAAI,CAAC,KAAK,YAAY,MAAM,WAAW,+BAA+B,IAAI,CAAC;AAAA,EAAA;AAErR,QAAM,SAAS,EAAE,MAAM,KAAK,MAAM,QAAA;AAClC,aAAW,KAAK,IAAI,SAAS,MAAM;AACnC,SAAO;AACX;AAEO,MAAM,UAAwB;AAAA,EACjC,WAAW;AAAA,EACX,OAAO;AAAA,EACP,KAAK,OAAO,YAAY,OAAO,OAAO,KAAK;AACvC,UAAM,QAAQ,iBAAiB,OAAO,OAAO,OAAO,GAAG;AACvD,QAAI,eAAe,OAAO;AACtB,aAAO,EAAE,MAAM,GAAG,MAAM,IAAI,QAAQ,MAAM,QAAA;AAAA,IAC9C;AACA,WAAO;AAAA,EACX;AACJ;"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const STAGE_FRAGMENT = 2;
|
|
2
|
+
const IBL_HELPERS = `
|
|
3
|
+
fn environmentHorizonOcclusion(V: vec3<f32>, N: vec3<f32>, geoN: vec3<f32>) -> f32 {
|
|
4
|
+
let R = reflect(V, N);
|
|
5
|
+
let temp = saturate(1.0 + 1.1 * dot(R, geoN));
|
|
6
|
+
return temp * temp;
|
|
7
|
+
}
|
|
8
|
+
fn getEnergyConservationFactor(F0: vec3<f32>, brdfY: f32) -> vec3<f32> {
|
|
9
|
+
return 1.0 + F0 * (1.0 / brdfY - 1.0);
|
|
10
|
+
}
|
|
11
|
+
fn rotateY(v: vec3<f32>, angle: f32) -> vec3<f32> {
|
|
12
|
+
let c = cos(angle);
|
|
13
|
+
let s = sin(angle);
|
|
14
|
+
return vec3<f32>(v.x * c + v.z * s, v.y, -v.x * s + v.z * c);
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
function makeIblCalculation(hasNormalMap, anisoBentNormalCode = "", skyboxCalculation = "") {
|
|
18
|
+
if (skyboxCalculation) {
|
|
19
|
+
return skyboxCalculation;
|
|
20
|
+
}
|
|
21
|
+
const ehoLine = hasNormalMap ? `let eho = environmentHorizonOcclusion(-V, N, N_geom);` : `let eho = 1.0;`;
|
|
22
|
+
const reflectionDir = anisoBentNormalCode ? anisoBentNormalCode : `let R_raw = reflect(-V, N);`;
|
|
23
|
+
const irradianceCode = `let environmentIrradiance = (scene.vSphericalL00.rgb
|
|
24
|
+
+ scene.vSphericalL1_1.rgb * N_env.y + scene.vSphericalL10.rgb * N_env.z + scene.vSphericalL11.rgb * N_env.x
|
|
25
|
+
+ scene.vSphericalL2_2.rgb * (N_env.y * N_env.x) + scene.vSphericalL2_1.rgb * (N_env.y * N_env.z)
|
|
26
|
+
+ scene.vSphericalL20.rgb * (3.0 * N_env.z * N_env.z - 1.0) + scene.vSphericalL21.rgb * (N_env.z * N_env.x)
|
|
27
|
+
+ scene.vSphericalL22.rgb * (N_env.x * N_env.x - N_env.y * N_env.y)) * material.environmentIntensity;`;
|
|
28
|
+
return `${reflectionDir}
|
|
29
|
+
let R = rotateY(R_raw, scene.envRotationY);
|
|
30
|
+
let N_env = rotateY(N, scene.envRotationY);
|
|
31
|
+
let brdf = textureSample(brdfLUT, brdfSampler_, vec2<f32>(NdotV, roughness));
|
|
32
|
+
let environmentBrdf = brdf.rgb;
|
|
33
|
+
let specularEnvironmentReflectance = (colorF90 - colorF0) * environmentBrdf.x + colorF0 * environmentBrdf.y;
|
|
34
|
+
let seo = clamp((NdotVUnclamped + occlusion) * (NdotVUnclamped + occlusion) - 1.0 + occlusion, 0.0, 1.0);
|
|
35
|
+
${ehoLine}
|
|
36
|
+
let colorSpecularEnvReflectance = specularEnvironmentReflectance * seo * eho;
|
|
37
|
+
let energyConservation = getEnergyConservationFactor(colorF0, max(environmentBrdf.y, 0.001));
|
|
38
|
+
${irradianceCode}
|
|
39
|
+
let maxLod = f32(textureNumLevels(iblTexture) - 1);
|
|
40
|
+
let cubemapDim = f32(textureDimensions(iblTexture).x);
|
|
41
|
+
var specLod = log2(cubemapDim * alphaG) * scene.vImageInfos.z;
|
|
42
|
+
var environmentRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(specLod, 0.0, maxLod)).rgb * material.environmentIntensity;
|
|
43
|
+
environmentRadiance = mix(environmentRadiance, environmentIrradiance, alphaG);
|
|
44
|
+
let finalIrradiance = environmentIrradiance * surfaceAlbedo * occlusion;
|
|
45
|
+
let finalSpecularScaled = directSpecular * energyConservation;
|
|
46
|
+
let finalRadianceScaled = environmentRadiance * colorSpecularEnvReflectance * energyConservation;
|
|
47
|
+
color = finalIrradiance + finalRadianceScaled + finalSpecularScaled + directDiffuse + emissive;`;
|
|
48
|
+
}
|
|
49
|
+
function createIblFragment(hasNormalMap, anisoBentNormalCode = "", skyboxCalculation = "") {
|
|
50
|
+
return {
|
|
51
|
+
_id: "ibl",
|
|
52
|
+
// SH coefficients are in the PBR template's baseSceneUboFields (not here)
|
|
53
|
+
// to preserve fixed scene UBO layout compatibility.
|
|
54
|
+
_bindings: [
|
|
55
|
+
{ _name: "brdfLUT", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT },
|
|
56
|
+
{ _name: "brdfSampler_", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT },
|
|
57
|
+
{ _name: "iblTexture", _type: { _kind: "texture", _textureType: "texture_cube<f32>" }, _visibility: STAGE_FRAGMENT },
|
|
58
|
+
{ _name: "iblSampler", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT }
|
|
59
|
+
],
|
|
60
|
+
_helperFunctions: IBL_HELPERS,
|
|
61
|
+
_fragmentSlots: {
|
|
62
|
+
AI: makeIblCalculation(hasNormalMap, anisoBentNormalCode, skyboxCalculation),
|
|
63
|
+
BA: `luminanceOverAlpha += dot(finalRadianceScaled, vec3<f32>(0.2126, 0.7152, 0.0722));`
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const pbrExt = {
|
|
68
|
+
id: "ibl",
|
|
69
|
+
phase: "ibl",
|
|
70
|
+
frag(ctx) {
|
|
71
|
+
if (!ctx._hasIbl) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return createIblFragment(ctx._hasAnyNormal, ctx._anisoBentNormalCode ?? "", ctx._iblSkyboxCalc ?? "");
|
|
75
|
+
},
|
|
76
|
+
bind(ctx, entries, b) {
|
|
77
|
+
if (!ctx._env) {
|
|
78
|
+
return b;
|
|
79
|
+
}
|
|
80
|
+
entries.push({ binding: b++, resource: ctx._env.brdfLutView });
|
|
81
|
+
entries.push({ binding: b++, resource: ctx._env.brdfSampler });
|
|
82
|
+
entries.push({ binding: b++, resource: ctx._env.specularCubeView });
|
|
83
|
+
entries.push({ binding: b++, resource: ctx._env.cubeSampler });
|
|
84
|
+
return b;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
export {
|
|
88
|
+
createIblFragment,
|
|
89
|
+
pbrExt
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=ibl-fragment-DqQVi8k0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ibl-fragment-DqQVi8k0.js","sources":["../src/material/pbr/fragments/ibl-fragment.ts"],"sourcesContent":["/**\n * IBL/Environment Fragment\n *\n * Adds image-based lighting via spherical harmonics irradiance + specular\n * cubemap. Only bundled when a scene loads an environment.\n *\n * Provides: scene UBO SH fields, BRDF LUT + IBL cube bindings,\n * horizon occlusion / energy conservation helpers, IBL calculation.\n */\n\nimport type { ShaderFragment } from \"../../../shader/fragment-types.js\";\n\n// WebGPU shader stage constants\nconst STAGE_FRAGMENT = 0x2;\n\nconst IBL_HELPERS = `\nfn environmentHorizonOcclusion(V: vec3<f32>, N: vec3<f32>, geoN: vec3<f32>) -> f32 {\nlet R = reflect(V, N);\nlet temp = saturate(1.0 + 1.1 * dot(R, geoN));\nreturn temp * temp;\n}\nfn getEnergyConservationFactor(F0: vec3<f32>, brdfY: f32) -> vec3<f32> {\nreturn 1.0 + F0 * (1.0 / brdfY - 1.0);\n}\nfn rotateY(v: vec3<f32>, angle: f32) -> vec3<f32> {\nlet c = cos(angle);\nlet s = sin(angle);\nreturn vec3<f32>(v.x * c + v.z * s, v.y, -v.x * s + v.z * c);\n}\n`;\n\nfunction makeIblCalculation(hasNormalMap: boolean, anisoBentNormalCode: string = \"\", skyboxCalculation: string = \"\"): string {\n // Skybox mode: caller passes pre-baked WGSL (from ibl-skybox-wgsl.ts) to avoid\n // bundling that ~1 KB string into scenes that don't use skyboxMode.\n if (skyboxCalculation) {\n return skyboxCalculation;\n }\n\n const ehoLine = hasNormalMap ? `let eho = environmentHorizonOcclusion(-V, N, N_geom);` : `let eho = 1.0;`;\n\n // Normal PBR: use reflected view or anisotropy bent normal.\n const reflectionDir = anisoBentNormalCode ? anisoBentNormalCode : `let R_raw = reflect(-V, N);`;\n\n const irradianceCode = `let environmentIrradiance = (scene.vSphericalL00.rgb\n + scene.vSphericalL1_1.rgb * N_env.y + scene.vSphericalL10.rgb * N_env.z + scene.vSphericalL11.rgb * N_env.x\n + scene.vSphericalL2_2.rgb * (N_env.y * N_env.x) + scene.vSphericalL2_1.rgb * (N_env.y * N_env.z)\n + scene.vSphericalL20.rgb * (3.0 * N_env.z * N_env.z - 1.0) + scene.vSphericalL21.rgb * (N_env.z * N_env.x)\n + scene.vSphericalL22.rgb * (N_env.x * N_env.x - N_env.y * N_env.y)) * material.environmentIntensity;`;\n\n return `${reflectionDir}\nlet R = rotateY(R_raw, scene.envRotationY);\nlet N_env = rotateY(N, scene.envRotationY);\nlet brdf = textureSample(brdfLUT, brdfSampler_, vec2<f32>(NdotV, roughness));\nlet environmentBrdf = brdf.rgb;\nlet specularEnvironmentReflectance = (colorF90 - colorF0) * environmentBrdf.x + colorF0 * environmentBrdf.y;\nlet seo = clamp((NdotVUnclamped + occlusion) * (NdotVUnclamped + occlusion) - 1.0 + occlusion, 0.0, 1.0);\n${ehoLine}\nlet colorSpecularEnvReflectance = specularEnvironmentReflectance * seo * eho;\nlet energyConservation = getEnergyConservationFactor(colorF0, max(environmentBrdf.y, 0.001));\n${irradianceCode}\nlet maxLod = f32(textureNumLevels(iblTexture) - 1);\nlet cubemapDim = f32(textureDimensions(iblTexture).x);\nvar specLod = log2(cubemapDim * alphaG) * scene.vImageInfos.z;\nvar environmentRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(specLod, 0.0, maxLod)).rgb * material.environmentIntensity;\nenvironmentRadiance = mix(environmentRadiance, environmentIrradiance, alphaG);\nlet finalIrradiance = environmentIrradiance * surfaceAlbedo * occlusion;\nlet finalSpecularScaled = directSpecular * energyConservation;\nlet finalRadianceScaled = environmentRadiance * colorSpecularEnvReflectance * energyConservation;\ncolor = finalIrradiance + finalRadianceScaled + finalSpecularScaled + directDiffuse + emissive;`;\n}\n\n/**\n * Create an IBL/environment fragment.\n * @param hasNormalMap - Whether the material uses a normal map (enables horizon occlusion).\n * @param anisoBentNormalCode - WGSL code for anisotropic bent normal (empty string = standard reflection).\n * @param skyboxCalculation - Pre-baked skybox-mode WGSL from ibl-skybox-wgsl.ts (empty string = normal PBR).\n */\nexport function createIblFragment(hasNormalMap: boolean, anisoBentNormalCode: string = \"\", skyboxCalculation: string = \"\"): ShaderFragment {\n return {\n _id: \"ibl\",\n\n // SH coefficients are in the PBR template's baseSceneUboFields (not here)\n // to preserve fixed scene UBO layout compatibility.\n\n _bindings: [\n { _name: \"brdfLUT\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"brdfSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iblTexture\", _type: { _kind: \"texture\", _textureType: \"texture_cube<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"iblSampler\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT },\n ],\n\n _helperFunctions: IBL_HELPERS,\n\n _fragmentSlots: {\n AI: makeIblCalculation(hasNormalMap, anisoBentNormalCode, skyboxCalculation),\n BA: `luminanceOverAlpha += dot(finalRadianceScaled, vec3<f32>(0.2126, 0.7152, 0.0722));`,\n },\n };\n}\n\nimport type { PbrExt } from \"../pbr-flags.js\";\n\nexport const pbrExt: PbrExt = {\n id: \"ibl\",\n phase: \"ibl\",\n frag(ctx) {\n if (!ctx._hasIbl) {\n return null;\n }\n return createIblFragment(ctx._hasAnyNormal, ctx._anisoBentNormalCode ?? \"\", ctx._iblSkyboxCalc ?? \"\");\n },\n bind(ctx, entries, b) {\n if (!ctx._env) {\n return b;\n }\n entries.push({ binding: b++, resource: ctx._env.brdfLutView });\n entries.push({ binding: b++, resource: ctx._env.brdfSampler });\n entries.push({ binding: b++, resource: ctx._env.specularCubeView });\n entries.push({ binding: b++, resource: ctx._env.cubeSampler });\n return b;\n },\n};\n"],"names":[],"mappings":"AAaA,MAAM,iBAAiB;AAEvB,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBpB,SAAS,mBAAmB,cAAuB,sBAA8B,IAAI,oBAA4B,IAAY;AAGzH,MAAI,mBAAmB;AACnB,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,eAAe,0DAA0D;AAGzF,QAAM,gBAAgB,sBAAsB,sBAAsB;AAElE,QAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAMvB,SAAO,GAAG,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB,OAAO;AAAA;AAAA;AAAA,EAGP,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUhB;AAQO,SAAS,kBAAkB,cAAuB,sBAA8B,IAAI,oBAA4B,IAAoB;AACvI,SAAO;AAAA,IACH,KAAK;AAAA;AAAA;AAAA,IAKL,WAAW;AAAA,MACP,EAAE,OAAO,WAAW,OAAO,EAAE,OAAO,WAAW,cAAc,kBAAA,GAAqB,aAAa,eAAA;AAAA,MAC/F,EAAE,OAAO,gBAAgB,OAAO,EAAE,OAAO,WAAW,cAAc,UAAA,GAAa,aAAa,eAAA;AAAA,MAC5F,EAAE,OAAO,cAAc,OAAO,EAAE,OAAO,WAAW,cAAc,oBAAA,GAAuB,aAAa,eAAA;AAAA,MACpG,EAAE,OAAO,cAAc,OAAO,EAAE,OAAO,WAAW,cAAc,aAAa,aAAa,eAAA;AAAA,IAAe;AAAA,IAG7G,kBAAkB;AAAA,IAElB,gBAAgB;AAAA,MACZ,IAAI,mBAAmB,cAAc,qBAAqB,iBAAiB;AAAA,MAC3E,IAAI;AAAA,IAAA;AAAA,EACR;AAER;AAIO,MAAM,SAAiB;AAAA,EAC1B,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK,KAAK;AACN,QAAI,CAAC,IAAI,SAAS;AACd,aAAO;AAAA,IACX;AACA,WAAO,kBAAkB,IAAI,eAAe,IAAI,wBAAwB,IAAI,IAAI,kBAAkB,EAAE;AAAA,EACxG;AAAA,EACA,KAAK,KAAK,SAAS,GAAG;AAClB,QAAI,CAAC,IAAI,MAAM;AACX,aAAO;AAAA,IACX;AACA,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,KAAK,aAAa;AAC7D,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,KAAK,aAAa;AAC7D,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,KAAK,kBAAkB;AAClE,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,IAAI,KAAK,aAAa;AAC7D,WAAO;AAAA,EACX;AACJ;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const IBL_SKYBOX_CALCULATION = `let R = input.worldPos - scene.vEyePosition.xyz;
|
|
2
|
+
let maxLod = f32(textureNumLevels(iblTexture) - 1);
|
|
3
|
+
let cubemapDim = f32(textureDimensions(iblTexture).x);
|
|
4
|
+
let skyboxAlphaG = max(roughness * roughness, 0.000001);
|
|
5
|
+
var specLod = log2(cubemapDim * skyboxAlphaG) * scene.vImageInfos.z;
|
|
6
|
+
var environmentRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(specLod, 0.0, maxLod)).rgb * material.environmentIntensity;
|
|
7
|
+
let finalSpecularScaled = vec3<f32>(0.0);
|
|
8
|
+
let finalRadianceScaled = environmentRadiance;
|
|
9
|
+
color = finalRadianceScaled + emissive;`;
|
|
10
|
+
export {
|
|
11
|
+
IBL_SKYBOX_CALCULATION
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=ibl-skybox-wgsl-DCah0kWV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ibl-skybox-wgsl-DCah0kWV.js","sources":["../src/material/pbr/fragments/ibl-skybox-wgsl.ts"],"sourcesContent":["/**\n * Skybox-mode IBL calculation (camera→fragment cubemap direction). Kept in a\n * separate module so scenes that don't use PBR skyboxMode don't pay the\n * ~1 KB string cost in their bundle. Dynamic-imported by pbr-renderable.ts\n * when PBR_HAS_SKYBOX is set.\n *\n * Matches BJS's disableLighting skybox-material path, where\n * MIX_IBL_RADIANCE_WITH_IRRADIANCE is not defined and the skybox uses the\n * sampled prefiltered radiance directly.\n */\n\nexport const IBL_SKYBOX_CALCULATION = `let R = input.worldPos - scene.vEyePosition.xyz;\nlet maxLod = f32(textureNumLevels(iblTexture) - 1);\nlet cubemapDim = f32(textureDimensions(iblTexture).x);\nlet skyboxAlphaG = max(roughness * roughness, 0.000001);\nvar specLod = log2(cubemapDim * skyboxAlphaG) * scene.vImageInfos.z;\nvar environmentRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(specLod, 0.0, maxLod)).rgb * material.environmentIntensity;\nlet finalSpecularScaled = vec3<f32>(0.0);\nlet finalRadianceScaled = environmentRadiance;\ncolor = finalRadianceScaled + emissive;`;\n"],"names":[],"mappings":"AAWO,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function imageProcessingHelper(convertInputToLinearSpace) {
|
|
2
|
+
const linearize = convertInputToLinearSpace ? `rgb = pow(max(rgb, vec3<f32>(0.0)), vec3<f32>(2.2));` : ``;
|
|
3
|
+
return `fn nme_apply_image_processing(inputColor: vec4<f32>) -> vec4<f32> {
|
|
4
|
+
var rgb = inputColor.rgb;
|
|
5
|
+
${linearize}
|
|
6
|
+
rgb = rgb * sceneU.vImageInfos.x;
|
|
7
|
+
if (sceneU.vImageInfos.w > 0.5) {
|
|
8
|
+
rgb = 1.0 - exp2(-1.590579 * rgb);
|
|
9
|
+
}
|
|
10
|
+
rgb = pow(max(rgb, vec3<f32>(0.0)), vec3<f32>(0.45454545));
|
|
11
|
+
rgb = clamp(rgb, vec3<f32>(0.0), vec3<f32>(1.0));
|
|
12
|
+
let highContrast = rgb * rgb * (vec3<f32>(3.0) - rgb * 2.0);
|
|
13
|
+
if (sceneU.vImageInfos.y < 1.0) {
|
|
14
|
+
rgb = mix(vec3<f32>(0.5), rgb, sceneU.vImageInfos.y);
|
|
15
|
+
} else {
|
|
16
|
+
rgb = mix(rgb, highContrast, sceneU.vImageInfos.y - 1.0);
|
|
17
|
+
}
|
|
18
|
+
return vec4<f32>(max(rgb, vec3<f32>(0.0)), inputColor.a);
|
|
19
|
+
}`;
|
|
20
|
+
}
|
|
21
|
+
const emitter = {
|
|
22
|
+
className: "ImageProcessingBlock",
|
|
23
|
+
stage: "fragment",
|
|
24
|
+
emit(block, outputName, stage, state, ctx) {
|
|
25
|
+
const convertInput = block.serialized.convertInputToLinearSpace !== false;
|
|
26
|
+
const helperKey = `nme_image_processing_${convertInput ? "linear" : "as_is"}`;
|
|
27
|
+
state.fragment.helpers.set(helperKey, imageProcessingHelper(convertInput));
|
|
28
|
+
const color = ctx.cast(ctx.resolve(block, "color", stage, state), "vec4f");
|
|
29
|
+
const t = ctx.temp(state, "ip");
|
|
30
|
+
state.fragment.body.push(`let ${t} = nme_apply_image_processing(${color.expr});`);
|
|
31
|
+
if (outputName === "rgb") {
|
|
32
|
+
return { expr: `${t}.rgb`, type: "vec3f" };
|
|
33
|
+
}
|
|
34
|
+
return { expr: t, type: "vec4f" };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
emitter
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=image-processing-block-DwrhhmuF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-processing-block-DwrhhmuF.js","sources":["../src/material/node/blocks/image-processing-block.ts"],"sourcesContent":["/** ImageProcessingBlock — scene image-processing output path.\n *\n * Matches Babylon.js' NME ImageProcessingBlock for the image-processing state\n * currently exposed by Lite's canonical scene UBO (sceneU.vImageInfos):\n * optional input `gamma->linear` conversion, exposure, standard exponential\n * tone mapping, gamma encode, clamp, and contrast. Color grading/vignette/\n * dither are intentionally absent because Lite does not expose those scene\n * states yet.\n */\n\nimport type { BlockEmitter, NodeExpr } from \"../node-types.js\";\n\nfunction imageProcessingHelper(convertInputToLinearSpace: boolean): string {\n const linearize = convertInputToLinearSpace ? `rgb = pow(max(rgb, vec3<f32>(0.0)), vec3<f32>(2.2));` : ``;\n return `fn nme_apply_image_processing(inputColor: vec4<f32>) -> vec4<f32> {\n var rgb = inputColor.rgb;\n ${linearize}\n rgb = rgb * sceneU.vImageInfos.x;\n if (sceneU.vImageInfos.w > 0.5) {\n rgb = 1.0 - exp2(-1.590579 * rgb);\n }\n rgb = pow(max(rgb, vec3<f32>(0.0)), vec3<f32>(0.45454545));\n rgb = clamp(rgb, vec3<f32>(0.0), vec3<f32>(1.0));\n let highContrast = rgb * rgb * (vec3<f32>(3.0) - rgb * 2.0);\n if (sceneU.vImageInfos.y < 1.0) {\n rgb = mix(vec3<f32>(0.5), rgb, sceneU.vImageInfos.y);\n } else {\n rgb = mix(rgb, highContrast, sceneU.vImageInfos.y - 1.0);\n }\n return vec4<f32>(max(rgb, vec3<f32>(0.0)), inputColor.a);\n}`;\n}\n\nexport const emitter: BlockEmitter = {\n className: \"ImageProcessingBlock\",\n stage: \"fragment\",\n emit(block, outputName, stage, state, ctx): NodeExpr {\n const convertInput = (block.serialized as { convertInputToLinearSpace?: boolean }).convertInputToLinearSpace !== false;\n const helperKey = `nme_image_processing_${convertInput ? \"linear\" : \"as_is\"}`;\n state.fragment.helpers.set(helperKey, imageProcessingHelper(convertInput));\n const color = ctx.cast(ctx.resolve(block, \"color\", stage, state), \"vec4f\");\n const t = ctx.temp(state, \"ip\");\n state.fragment.body.push(`let ${t} = nme_apply_image_processing(${color.expr});`);\n if (outputName === \"rgb\") {\n return { expr: `${t}.rgb`, type: \"vec3f\" };\n }\n return { expr: t, type: \"vec4f\" };\n },\n};\n"],"names":[],"mappings":"AAYA,SAAS,sBAAsB,2BAA4C;AACvE,QAAM,YAAY,4BAA4B,yDAAyD;AACvG,SAAO;AAAA;AAAA,MAEL,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAef;AAEO,MAAM,UAAwB;AAAA,EACjC,WAAW;AAAA,EACX,OAAO;AAAA,EACP,KAAK,OAAO,YAAY,OAAO,OAAO,KAAe;AACjD,UAAM,eAAgB,MAAM,WAAuD,8BAA8B;AACjH,UAAM,YAAY,wBAAwB,eAAe,WAAW,OAAO;AAC3E,UAAM,SAAS,QAAQ,IAAI,WAAW,sBAAsB,YAAY,CAAC;AACzE,UAAM,QAAQ,IAAI,KAAK,IAAI,QAAQ,OAAO,SAAS,OAAO,KAAK,GAAG,OAAO;AACzE,UAAM,IAAI,IAAI,KAAK,OAAO,IAAI;AAC9B,UAAM,SAAS,KAAK,KAAK,OAAO,CAAC,iCAAiC,MAAM,IAAI,IAAI;AAChF,QAAI,eAAe,OAAO;AACtB,aAAO,EAAE,MAAM,GAAG,CAAC,QAAQ,MAAM,QAAA;AAAA,IACrC;AACA,WAAO,EAAE,MAAM,GAAG,MAAM,QAAA;AAAA,EAC5B;AACJ;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const emitter = {
|
|
2
|
+
className: "ImageSourceBlock",
|
|
3
|
+
emit(block, _outputName, _stage, state, _ctx) {
|
|
4
|
+
const bindingName = sanitize(block.name || `img${block.id}`);
|
|
5
|
+
if (!state.textures.find((t) => t.name === bindingName)) {
|
|
6
|
+
state.textures.push({ name: bindingName, kind: "texture2d", texture: null });
|
|
7
|
+
}
|
|
8
|
+
return { expr: bindingName, type: "texture2d" };
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
function sanitize(name) {
|
|
12
|
+
return name.replace(/[^A-Za-z0-9_]/g, "_");
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
emitter
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=image-source-BuMJgd9-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-source-BuMJgd9-.js","sources":["../src/material/node/blocks/image-source.ts"],"sourcesContent":["/** ImageSourceBlock — holds a texture reference and feeds a TextureBlock's `source` input.\n *\n * The emitter does not emit any WGSL of its own; it just advertises that a\n * texture binding named after this block exists, so the downstream TextureBlock\n * can refer to it. The actual texture upload is handled at material-build time.\n */\n\nimport type { BlockEmitter } from \"../node-types.js\";\n\nexport const emitter: BlockEmitter = {\n className: \"ImageSourceBlock\",\n emit(block, _outputName, _stage, state, _ctx) {\n const bindingName = sanitize(block.name || `img${block.id}`);\n if (!state.textures.find((t) => t.name === bindingName)) {\n state.textures.push({ name: bindingName, kind: \"texture2d\", texture: null });\n }\n // Return a sentinel — the TextureBlock consumes the binding name via this.\n return { expr: bindingName, type: \"texture2d\" };\n },\n};\n\nfunction sanitize(name: string): string {\n return name.replace(/[^A-Za-z0-9_]/g, \"_\");\n}\n"],"names":[],"mappings":"AASO,MAAM,UAAwB;AAAA,EACjC,WAAW;AAAA,EACX,KAAK,OAAO,aAAa,QAAQ,OAAO,MAAM;AAC1C,UAAM,cAAc,SAAS,MAAM,QAAQ,MAAM,MAAM,EAAE,EAAE;AAC3D,QAAI,CAAC,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,WAAW,GAAG;AACrD,YAAM,SAAS,KAAK,EAAE,MAAM,aAAa,MAAM,aAAa,SAAS,MAAM;AAAA,IAC/E;AAEA,WAAO,EAAE,MAAM,aAAa,MAAM,YAAA;AAAA,EACtC;AACJ;AAEA,SAAS,SAAS,MAAsB;AACpC,SAAO,KAAK,QAAQ,kBAAkB,GAAG;AAC7C;"}
|