@babylonjs/lite 0.1.1 → 0.2.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-Bvh5TymE.js +10 -0
- package/_mat4-storage-f64-Bvh5TymE.js.map +1 -0
- package/{alpha-test-fragment-CUiHCw7W.js → alpha-test-fragment-BCChpzaV.js} +2 -2
- package/{alpha-test-fragment-CUiHCw7W.js.map → alpha-test-fragment-BCChpzaV.js.map} +1 -1
- package/{background-dds-skybox-yHTqabU3.js → background-dds-skybox-ZjrSIxrT.js} +4 -4
- package/background-dds-skybox-ZjrSIxrT.js.map +1 -0
- package/{background-ground-DIw6D3qf.js → background-ground-B2Mie-MI.js} +3 -3
- package/background-ground-B2Mie-MI.js.map +1 -0
- package/{background-hdr-skybox-c4uuTmkP.js → background-hdr-skybox-DDRJYuT2.js} +3 -3
- package/background-hdr-skybox-DDRJYuT2.js.map +1 -0
- package/{background-solid-skybox-DPGBpPbm.js → background-solid-skybox-fjXlnWaD.js} +3 -3
- package/{background-solid-skybox-DPGBpPbm.js.map → background-solid-skybox-fjXlnWaD.js.map} +1 -1
- package/{billboard-renderable-D8mlVGCd.js → billboard-renderable-DKmlOgbM.js} +2 -2
- package/{billboard-renderable-D8mlVGCd.js.map → billboard-renderable-DKmlOgbM.js.map} +1 -1
- package/{clamp-block-BdII67hT.js → clamp-block-CxRBPlUq.js} +2 -2
- package/{clamp-block-BdII67hT.js.map → clamp-block-CxRBPlUq.js.map} +1 -1
- package/{clearcoat-fragment-LCiG98Rf.js → clearcoat-fragment-KbZAa0TA.js} +2 -2
- package/{clearcoat-fragment-LCiG98Rf.js.map → clearcoat-fragment-KbZAa0TA.js.map} +1 -1
- package/{create-skeleton-C9JdIJnb.js → create-skeleton-BBI5urcj.js} +2 -2
- package/{create-skeleton-C9JdIJnb.js.map → create-skeleton-BBI5urcj.js.map} +1 -1
- package/{cubemap-skybox-material-DvXMVc4k.js → cubemap-skybox-material-DvW81drX.js} +2 -2
- package/{cubemap-skybox-material-DvXMVc4k.js.map → cubemap-skybox-material-DvW81drX.js.map} +1 -1
- package/{curve-block-BlJpXVYv.js → curve-block-Dh_xdUj-.js} +2 -2
- package/{curve-block-BlJpXVYv.js.map → curve-block-Dh_xdUj-.js.map} +1 -1
- package/{emissive-fragment-BnNvbBCw.js → emissive-fragment-DD8cvHyx.js} +2 -2
- package/{emissive-fragment-BnNvbBCw.js.map → emissive-fragment-DD8cvHyx.js.map} +1 -1
- package/{esm-shadow-view-DGKdF1NI.js → esm-shadow-view-15S4JK6p.js} +2 -2
- package/{esm-shadow-view-DGKdF1NI.js.map → esm-shadow-view-15S4JK6p.js.map} +1 -1
- package/{esm-shadow-view-Dk9NFtLq.js → esm-shadow-view-DHVS9r7H.js} +2 -2
- package/{esm-shadow-view-Dk9NFtLq.js.map → esm-shadow-view-DHVS9r7H.js.map} +1 -1
- package/{esm-shadow-view-DN9HIaM4.js → esm-shadow-view-DYAc62Kl.js} +2 -2
- package/{esm-shadow-view-DN9HIaM4.js.map → esm-shadow-view-DYAc62Kl.js.map} +1 -1
- package/{gaussian-splatting-pipeline-sh-DgJl7l56.js → gaussian-splatting-pipeline-sh-BvkUhA9V.js} +2 -2
- package/{gaussian-splatting-pipeline-sh-DgJl7l56.js.map → gaussian-splatting-pipeline-sh-BvkUhA9V.js.map} +1 -1
- package/{gltf-animation-D7uyTyO3.js → gltf-animation-KnPzeOIY.js} +3 -3
- package/{gltf-animation-D7uyTyO3.js.map → gltf-animation-KnPzeOIY.js.map} +1 -1
- package/gltf-color-normalize-Qxl-9C48.js +29 -0
- package/gltf-color-normalize-Qxl-9C48.js.map +1 -0
- package/{gltf-ext-basisu-CPg5kPrx.js → gltf-ext-basisu-kmth3UWX.js} +7 -4
- package/gltf-ext-basisu-kmth3UWX.js.map +1 -0
- package/{gltf-ext-node-visibility-MafA9ot2.js → gltf-ext-node-visibility-BjRRd6si.js} +2 -2
- package/{gltf-ext-node-visibility-MafA9ot2.js.map → gltf-ext-node-visibility-BjRRd6si.js.map} +1 -1
- package/{gltf-ext-uv-transform-CE_-T1Tr.js → gltf-ext-uv-transform-MHmR-YyM.js} +2 -2
- package/{gltf-ext-uv-transform-CE_-T1Tr.js.map → gltf-ext-uv-transform-MHmR-YyM.js.map} +1 -1
- package/{gltf-feature-animation-pointer-BjpwOOqo.js → gltf-feature-animation-pointer-rFqLfbO_.js} +3 -3
- package/{gltf-feature-animation-pointer-BjpwOOqo.js.map → gltf-feature-animation-pointer-rFqLfbO_.js.map} +1 -1
- package/{gltf-feature-animations-CCizegp8.js → gltf-feature-animations-DikONdzi.js} +2 -2
- package/{gltf-feature-animations-CCizegp8.js.map → gltf-feature-animations-DikONdzi.js.map} +1 -1
- package/{gltf-feature-gpu-instancing-2e_CFQnl.js → gltf-feature-gpu-instancing-Cj1XjmM6.js} +5 -4
- package/gltf-feature-gpu-instancing-Cj1XjmM6.js.map +1 -0
- package/{gltf-feature-lights-punctual-DDDg4j0U.js → gltf-feature-lights-punctual-C-0SlGmD.js} +5 -5
- package/{gltf-feature-lights-punctual-DDDg4j0U.js.map → gltf-feature-lights-punctual-C-0SlGmD.js.map} +1 -1
- package/{gltf-feature-morph-CKCw6tkX.js → gltf-feature-morph-BAcY14XU.js} +3 -3
- package/{gltf-feature-morph-CKCw6tkX.js.map → gltf-feature-morph-BAcY14XU.js.map} +1 -1
- package/gltf-feature-registry-97sY_x5O.js +59 -0
- package/gltf-feature-registry-97sY_x5O.js.map +1 -0
- package/{gltf-feature-skeleton-D8hWLqi2.js → gltf-feature-skeleton-lVjkDfIU.js} +3 -3
- package/{gltf-feature-skeleton-D8hWLqi2.js.map → gltf-feature-skeleton-lVjkDfIU.js.map} +1 -1
- package/{gltf-feature-variants-Ds6v9byg.js → gltf-feature-variants-BphF4JmV.js} +2 -2
- package/{gltf-feature-variants-Ds6v9byg.js.map → gltf-feature-variants-BphF4JmV.js.map} +1 -1
- package/{gltf-interleave-DGnUlz28.js → gltf-interleave-C9eBqH_F.js} +2 -2
- package/{gltf-interleave-DGnUlz28.js.map → gltf-interleave-C9eBqH_F.js.map} +1 -1
- package/gltf-normals-b2h74380.js +37 -0
- package/gltf-normals-b2h74380.js.map +1 -0
- package/{gltf-pbr-builder-ext-BFOxOCnQ.js → gltf-pbr-builder-ext-DPC0zg_u.js} +2 -2
- package/{gltf-pbr-builder-ext-BFOxOCnQ.js.map → gltf-pbr-builder-ext-DPC0zg_u.js.map} +1 -1
- package/{gltf-variants-DFbr8EES.js → gltf-variants-CnBEZr0o.js} +4 -4
- package/{gltf-variants-DFbr8EES.js.map → gltf-variants-CnBEZr0o.js.map} +1 -1
- package/{gs-picking-pipeline-DzfMASL9.js → gs-picking-pipeline-Bx8LTav6.js} +2 -2
- package/{gs-picking-pipeline-DzfMASL9.js.map → gs-picking-pipeline-Bx8LTav6.js.map} +1 -1
- package/{index-C8HOR2sB.js → index-B7Qhw0xL.js} +3047 -1037
- package/index-B7Qhw0xL.js.map +1 -0
- package/index.d.ts +504 -17
- package/index.js +322 -304
- package/{input-block-DgAJBzN_.js → input-block-Coi_aZwl.js} +2 -2
- package/{input-block-DgAJBzN_.js.map → input-block-Coi_aZwl.js.map} +1 -1
- package/{iridescence-fragment-Gymp7or5.js → iridescence-fragment-DwZcCTdD.js} +2 -2
- package/{iridescence-fragment-Gymp7or5.js.map → iridescence-fragment-DwZcCTdD.js.map} +1 -1
- package/{light-block-B11ew7FA.js → light-block-Np_h5gPI.js} +2 -2
- package/{light-block-B11ew7FA.js.map → light-block-Np_h5gPI.js.map} +1 -1
- package/{loop-block-Bb23EOMb.js → loop-block-BFkLFYGm.js} +2 -2
- package/{loop-block-Bb23EOMb.js.map → loop-block-BFkLFYGm.js.map} +1 -1
- package/{mesh-features-BLENkYVt.js → mesh-features-BAJpbMog.js} +6 -3
- package/mesh-features-BAJpbMog.js.map +1 -0
- package/{morph-fragment-DOVo70gP.js → morph-fragment-DqH-w61u.js} +2 -2
- package/{morph-fragment-DOVo70gP.js.map → morph-fragment-DqH-w61u.js.map} +1 -1
- package/{multilight-wgsl-BGyiIOp3.js → multilight-wgsl-B9Mf9d-q.js} +4 -4
- package/{multilight-wgsl-BGyiIOp3.js.map → multilight-wgsl-B9Mf9d-q.js.map} +1 -1
- package/no-color-view-DsyLSL-W.js +8 -0
- package/no-color-view-DsyLSL-W.js.map +1 -0
- package/{node-registry-DwgC4yth.js → node-registry-Bd-AlrgC.js} +8 -8
- package/{node-registry-DwgC4yth.js.map → node-registry-Bd-AlrgC.js.map} +1 -1
- package/{node-registry-extra-compat-Dhrw8fDQ.js → node-registry-extra-compat-Ch7ApZHF.js} +2 -2
- package/{node-registry-extra-compat-Dhrw8fDQ.js.map → node-registry-extra-compat-Ch7ApZHF.js.map} +1 -1
- package/{node-registry-extra-math-CsAHvIZo.js → node-registry-extra-math-6ezzTkPj.js} +2 -2
- package/{node-registry-extra-math-CsAHvIZo.js.map → node-registry-extra-math-6ezzTkPj.js.map} +1 -1
- package/{node-renderable-DlLIdBmd.js → node-renderable-CS0CmsSp.js} +28 -11
- package/node-renderable-CS0CmsSp.js.map +1 -0
- package/{node-shadow-DKrcqmNg.js → node-shadow-CpnrdvtJ.js} +2 -2
- package/{node-shadow-DKrcqmNg.js.map → node-shadow-CpnrdvtJ.js.map} +1 -1
- package/{normal-map-fragment-DpsIXrJf.js → normal-map-fragment-DradEMl-.js} +3 -3
- package/{normal-map-fragment-DpsIXrJf.js.map → normal-map-fragment-DradEMl-.js.map} +1 -1
- package/pack-mat4-with-offset-BqB8Jqo7.js +37 -0
- package/pack-mat4-with-offset-BqB8Jqo7.js.map +1 -0
- package/package.json +3 -3
- package/{parse-camera-DM3oJJeT.js → parse-camera-CgV4bWc0.js} +2 -2
- package/{parse-camera-DM3oJJeT.js.map → parse-camera-CgV4bWc0.js.map} +1 -1
- package/pbr-fog-wgsl-BqdCid6r.js +8 -0
- package/pbr-fog-wgsl-BqdCid6r.js.map +1 -0
- package/{pbr-metallic-roughness-block-h_KAOZrW.js → pbr-metallic-roughness-block-BFwZj2Nw.js} +2 -2
- package/{pbr-metallic-roughness-block-h_KAOZrW.js.map → pbr-metallic-roughness-block-BFwZj2Nw.js.map} +1 -1
- package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js → pbr-metallic-roughness-block-full-5t0HT3xl.js} +2 -2
- package/{pbr-metallic-roughness-block-full-6vMm1Jk6.js.map → pbr-metallic-roughness-block-full-5t0HT3xl.js.map} +1 -1
- package/{pbr-mr-helper-core-CIwm-T1G.js → pbr-mr-helper-core-R5tOZ8Ap.js} +2 -2
- package/{pbr-mr-helper-core-CIwm-T1G.js.map → pbr-mr-helper-core-R5tOZ8Ap.js.map} +1 -1
- package/{pbr-refraction-DGmMSa2v.js → pbr-refraction-Dd11HnaI.js} +2 -2
- package/{pbr-refraction-DGmMSa2v.js.map → pbr-refraction-Dd11HnaI.js.map} +1 -1
- package/{pbr-renderable-BJxUtPBb.js → pbr-renderable-BHAdF5Vw.js} +80 -38
- package/pbr-renderable-BHAdF5Vw.js.map +1 -0
- package/{pbr-shadow-fragment-LO9SlbJj.js → pbr-shadow-fragment-BxUrFJYZ.js} +6 -1
- package/pbr-shadow-fragment-BxUrFJYZ.js.map +1 -0
- package/{pbr-template-ext-8q7BcTDf.js → pbr-template-ext-CGgB2n2y.js} +3 -2
- package/{pbr-template-ext-8q7BcTDf.js.map → pbr-template-ext-CGgB2n2y.js.map} +1 -1
- package/{pbr-tracking-B3alzn91.js → pbr-tracking-D6i3yPb7.js} +2 -2
- package/{pbr-tracking-B3alzn91.js.map → pbr-tracking-D6i3yPb7.js.map} +1 -1
- package/pbr-transmission-ext-Dll8EYwE.js +190 -0
- package/pbr-transmission-ext-Dll8EYwE.js.map +1 -0
- package/{reflectance-fragment-BCrgPmrt.js → reflectance-fragment-ejMJ4O1o.js} +2 -2
- package/{reflectance-fragment-BCrgPmrt.js.map → reflectance-fragment-ejMJ4O1o.js.map} +1 -1
- package/{shader-renderable-D-6796KR.js → shader-renderable-BMf_vvO0.js} +41 -12
- package/shader-renderable-BMf_vvO0.js.map +1 -0
- package/shader-thin-instance-5_WUfi3m.js +150 -0
- package/shader-thin-instance-5_WUfi3m.js.map +1 -0
- package/shadow-fragment-core-DHN2G6FI.js.map +1 -1
- package/{sheen-fragment-Dze2f7XJ.js → sheen-fragment-CS6z29Fs.js} +2 -2
- package/{sheen-fragment-Dze2f7XJ.js.map → sheen-fragment-CS6z29Fs.js.map} +1 -1
- package/{singlelight-directional-wgsl-CmUDZxwz.js → singlelight-directional-wgsl-4MIgZMeC.js} +2 -2
- package/{singlelight-directional-wgsl-CmUDZxwz.js.map → singlelight-directional-wgsl-4MIgZMeC.js.map} +1 -1
- package/{singlelight-hemispheric-wgsl-t-83IP_s.js → singlelight-hemispheric-wgsl-CK-GUYWe.js} +2 -2
- package/{singlelight-hemispheric-wgsl-t-83IP_s.js.map → singlelight-hemispheric-wgsl-CK-GUYWe.js.map} +1 -1
- package/{singlelight-point-wgsl-CLzULIYV.js → singlelight-point-wgsl-CYtzqCbP.js} +2 -2
- package/{singlelight-point-wgsl-CLzULIYV.js.map → singlelight-point-wgsl-CYtzqCbP.js.map} +1 -1
- package/{singlelight-spot-wgsl-DEEUrfVM.js → singlelight-spot-wgsl-DVbaVufF.js} +2 -2
- package/{singlelight-spot-wgsl-DEEUrfVM.js.map → singlelight-spot-wgsl-DVbaVufF.js.map} +1 -1
- package/{skeleton-fragment-B_XlFbtx.js → skeleton-fragment-BOVmc8YS.js} +2 -2
- package/{skeleton-fragment-B_XlFbtx.js.map → skeleton-fragment-BOVmc8YS.js.map} +1 -1
- package/{skybox-renderable-DDwzu-PT.js → skybox-renderable-DDcCPSly.js} +3 -3
- package/{skybox-renderable-DDwzu-PT.js.map → skybox-renderable-DDcCPSly.js.map} +1 -1
- package/{standard-renderable-GjxL9xSf.js → standard-renderable-D1bhoF0K.js} +27 -81
- package/standard-renderable-D1bhoF0K.js.map +1 -0
- package/{std-ambient-fragment-BoUsD06w.js → std-ambient-fragment-C6WNm8dQ.js} +2 -2
- package/{std-ambient-fragment-BoUsD06w.js.map → std-ambient-fragment-C6WNm8dQ.js.map} +1 -1
- package/{std-cube-reflection-fragment-ulqc3bsP.js → std-cube-reflection-fragment-Bqutpy2q.js} +2 -2
- package/{std-cube-reflection-fragment-ulqc3bsP.js.map → std-cube-reflection-fragment-Bqutpy2q.js.map} +1 -1
- package/{std-emissive-fragment-DNGj1HdQ.js → std-emissive-fragment-B-A83rqX.js} +2 -2
- package/{std-emissive-fragment-DNGj1HdQ.js.map → std-emissive-fragment-B-A83rqX.js.map} +1 -1
- package/{std-lightmap-fragment-Bqj89aIe.js → std-lightmap-fragment-Df7KJezh.js} +2 -2
- package/{std-lightmap-fragment-Bqj89aIe.js.map → std-lightmap-fragment-Df7KJezh.js.map} +1 -1
- package/{std-opacity-fragment-KuPh5N2Z.js → std-opacity-fragment-D9et2jip.js} +2 -2
- package/{std-opacity-fragment-KuPh5N2Z.js.map → std-opacity-fragment-D9et2jip.js.map} +1 -1
- package/{std-reflection-fragment-BA5Ghn_M.js → std-reflection-fragment-DBJeT-yg.js} +2 -2
- package/{std-reflection-fragment-BA5Ghn_M.js.map → std-reflection-fragment-DBJeT-yg.js.map} +1 -1
- package/std-shadow-fragment-C6fD8rW-.js +13 -0
- package/std-shadow-fragment-C6fD8rW-.js.map +1 -0
- package/{std-specular-fragment-CE-6scqd.js → std-specular-fragment-C2ZOss-t.js} +2 -2
- package/{std-specular-fragment-CE-6scqd.js.map → std-specular-fragment-C2ZOss-t.js.map} +1 -1
- package/{std-tracking-CNKZ-hJN.js → std-tracking-C4L4nQGc.js} +2 -2
- package/{std-tracking-CNKZ-hJN.js.map → std-tracking-C4L4nQGc.js.map} +1 -1
- package/{subsurface-fragment-liM3y2-P.js → subsurface-fragment-C1H4ytqK.js} +2 -2
- package/{subsurface-fragment-liM3y2-P.js.map → subsurface-fragment-C1H4ytqK.js.map} +1 -1
- package/thin-instance-cull-binding-CCxrPNO6.js +310 -0
- package/thin-instance-cull-binding-CCxrPNO6.js.map +1 -0
- package/{thin-instance-gpu-C9Gv_Z1w.js → thin-instance-gpu-E8DBd8XL.js} +20 -3
- package/thin-instance-gpu-E8DBd8XL.js.map +1 -0
- package/{tracking-primitives-wgdBY85t.js → tracking-primitives-w4BVV9p9.js} +2 -2
- package/{tracking-primitives-wgdBY85t.js.map → tracking-primitives-w4BVV9p9.js.map} +1 -1
- package/{unlit-fragment-BIlhJpz6.js → unlit-fragment-DU9_mhzZ.js} +2 -2
- package/{unlit-fragment-BIlhJpz6.js.map → unlit-fragment-DU9_mhzZ.js.map} +1 -1
- package/{wgsl-helpers-DyzNzCeE.js → wgsl-helpers-D8sl1VVA.js} +4 -4
- package/{wgsl-helpers-DyzNzCeE.js.map → wgsl-helpers-D8sl1VVA.js.map} +1 -1
- package/background-dds-skybox-yHTqabU3.js.map +0 -1
- package/background-ground-DIw6D3qf.js.map +0 -1
- package/background-hdr-skybox-c4uuTmkP.js.map +0 -1
- package/gltf-ext-basisu-CPg5kPrx.js.map +0 -1
- package/gltf-feature-gpu-instancing-2e_CFQnl.js.map +0 -1
- package/index-C8HOR2sB.js.map +0 -1
- package/mesh-features-BLENkYVt.js.map +0 -1
- package/node-renderable-DlLIdBmd.js.map +0 -1
- package/pbr-renderable-BJxUtPBb.js.map +0 -1
- package/pbr-shadow-fragment-LO9SlbJj.js.map +0 -1
- package/pbr-transmission-ext-BxW4CEGu.js +0 -581
- package/pbr-transmission-ext-BxW4CEGu.js.map +0 -1
- package/shader-renderable-D-6796KR.js.map +0 -1
- package/standard-renderable-GjxL9xSf.js.map +0 -1
- package/std-shadow-fragment-FNQfrJuC.js +0 -8
- package/std-shadow-fragment-FNQfrJuC.js.map +0 -1
- package/thin-instance-gpu-C9Gv_Z1w.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"background-dds-skybox-yHTqabU3.js","sources":["../shaders/skybox-dds.vertex.wgsl?raw","../shaders/skybox-dds.fragment.wgsl?raw","../src/material/pbr/background-dds-skybox.ts"],"sourcesContent":["export default \"// DDS Skybox Vertex Shader — standard world transform.\\n// positionUVW uses local position for cube direction lookup.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) clipPos: vec4<f32>,\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@vertex\\nfn main(@location(0) position: vec3<f32>) -> VertexOutput {\\n var output: VertexOutput;\\n output.positionUVW = position;\\n let worldPos = (mesh.world * vec4<f32>(position, 1.0)).xyz;\\n output.positionW = worldPos;\\n output.clipPos = scene.viewProjection * vec4<f32>(worldPos, 1.0);\\n return output;\\n}\\n\"","export default \"// DDS Cube Skybox Fragment Shader — samples DDS cube texture with BJS image processing.\\n// Used by scenes that load backgroundSkybox.dds (createDefaultEnvironment).\\n// Pipeline: exposure → Reinhard tonemap → gamma → contrast → dither.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n exposureLinear: f32,\\n contrast: f32,\\n _pad1: f32,\\n _pad2: f32,\\n _pad3: f32,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n@group(1) @binding(1) var envCubemap: texture_cube<f32>;\\n@group(1) @binding(2) var envSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let dir = normalize(input.positionUVW);\\n var color = textureSampleLevel(envCubemap, envSampler, dir, 0.0).rgb;\\n\\n // BJS BackgroundMaterial: colorBase = reflectionColor.rgb * primaryColor.rgb\\n color *= mesh.primaryColor;\\n\\n if (scene.vImageInfos.w >= 0.0) {\\n // Exposure\\n color *= mesh.exposureLinear;\\n // Reinhard tonemap (matches BJS toneMappingType 0)\\n color = 1.0 - exp2(-1.590579 * color);\\n // Gamma\\n color = pow(color, vec3<f32>(1.0 / 2.2));\\n color = saturate(color);\\n\\n // Contrast\\n let highContrast = color * color * (3.0 - 2.0 * color);\\n color = mix(color, highContrast, mesh.contrast - 1.0);\\n\\n // Dithering (enableNoise=true, variance=0.5)\\n color = color + vec3<f32>(dither(input.positionW.xy, 0.5));\\n color = max(color, vec3<f32>(0.0));\\n }\\n\\n return vec4<f32>(color, 1.0);\\n}\\n\"","/** DDS cube skybox — lazy-loaded only when skyboxUrl ends with .dds.\n * Loads backgroundSkybox.dds and renders it with BJS image processing. */\n\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport { getOrCreateSampler } from \"../../resource/gpu-pool.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { WGSL_DITHER, WGSL_NO_DITHER } from \"../../shader/wgsl-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createCubemapSkyboxMaterial } from \"./cubemap-skybox-material.js\";\nimport ddsSkyboxVertSrc from \"../../../shaders/skybox-dds.vertex.wgsl?raw\";\nimport ddsSkyboxFragSrc from \"../../../shaders/skybox-dds.fragment.wgsl?raw\";\n\nconst SKY_DDS_UNIFORM_SIZE = 96;\nconst DEFAULT_SKY_URL = \"https://assets.babylonjs.com/core/environments/backgroundSkybox.dds\";\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer; idxCount: number } {\n // prettier-ignore\n const positions = new Float32Array([\n S,-S, S, -S,-S, S, -S, S, S, S, S, S,\n S, S,-S, -S, S,-S, -S,-S,-S, S,-S,-S,\n S, S,-S, S,-S,-S, S,-S, S, S, S, S,\n -S, S, S, -S,-S, S, -S,-S,-S, -S, S,-S,\n -S, S, S, -S, S,-S, S, S,-S, S, S, S,\n S,-S, S, S,-S,-S, -S,-S,-S, -S,-S, S,\n ]);\n // prettier-ignore\n const indices = new Uint16Array([\n 2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4,\n 10, 9, 8, 11,10, 8, 14,13,12, 15,14,12,\n 18,17,16, 19,18,16, 22,21,20, 23,22,20,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, GPUBufferUsage.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, GPUBufferUsage.INDEX),\n idxCount: 36,\n };\n}\n\nfunction buildSkyboxWorldMatrix(rootPosition: [number, number, number]): Mat4 {\n const world = new Float32Array(16) as Mat4;\n world[0] = 1;\n world[5] = 1;\n world[10] = 1;\n world[15] = 1;\n world[12] = rootPosition[0];\n world[13] = rootPosition[1];\n world[14] = rootPosition[2];\n return world;\n}\n\n/** Build a DDS cube skybox as a complete Renderable (order 0). */\nexport async function buildDdsSkyboxRenderable(\n scene: SceneContext,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number],\n skyboxTextureUrl?: string,\n enableNoise = true\n): Promise<Renderable> {\n const engine = scene.engine;\n\n const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);\n\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n const { cubeView, sampler } = await loadDdsCube(engine, skyboxTextureUrl ?? DEFAULT_SKY_URL);\n\n const fragCode = SCENE_UBO_WGSL + (enableNoise ? WGSL_DITHER : WGSL_NO_DITHER) + ddsSkyboxFragSrc;\n const mat = createCubemapSkyboxMaterial(enableNoise ? \"skybox-dds\" : \"skybox-dds0\", SCENE_UBO_WGSL + ddsSkyboxVertSrc, fragCode);\n const ubo = createDdsMeshUBO(engine, skyboxWorld, primaryColor, scene.imageProcessing.exposure, scene.imageProcessing.contrast);\n const bindGroup = mat.createBindGroup(engine, ubo, cubeView, sampler);\n\n const r: Renderable = {\n order: 0,\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: mat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(skyBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── DDS Skybox UBO ──────────────────────────────────────────────────────────\n\nfunction createDdsMeshUBO(engine: EngineContext, world: Float32Array, primaryColor: [number, number, number], exposureLinear: number, contrast: number): GPUBuffer {\n const data = new Float32Array(SKY_DDS_UNIFORM_SIZE / 4);\n data.set(world, 0);\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[19] = exposureLinear;\n data[20] = contrast;\n return createUniformBuffer(engine, data);\n}\n\n// ─── DDS Cube Texture Loader ─────────────────────────────────────────────────\n\n/** Load a DDS cube texture (rgba16float) and return a cube texture view + sampler.\n * Uploads only mip 0 from the DDS file and generates remaining mipmaps on the\n * GPU so that cube face edges blend seamlessly — matching BJS's behaviour. */\nasync function loadDdsCube(engine: EngineContext, url: string): Promise<{ cubeView: GPUTextureView; sampler: GPUSampler }> {\n const device = engine._device;\n const buf = await (await fetch(url)).arrayBuffer();\n const header = new Int32Array(buf, 0, 32);\n const width = header[3]!;\n const height = header[4]!;\n const mipCount = Math.max(header[7]!, 1);\n\n // DDS pixel format offset 76..107 — for rgba16float, FourCC = 'DX10'\n // DDS_HEADER_DX10 at byte 128: dxgiFormat, resourceDimension, miscFlag, arraySize, etc.\n // For cube: miscFlag has RESOURCE_MISC_TEXTURECUBE (0x4), arraySize = 1 (6 faces in data)\n const dataOffset = header[21] === 0x30315844 /* 'DX10' */ ? 128 + 20 : 128;\n const raw = new Uint8Array(buf, dataOffset);\n\n const fmt: GPUTextureFormat = \"rgba16float\";\n const tex = device.createTexture({\n size: [width, height, 6],\n format: fmt,\n mipLevelCount: mipCount,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n dimension: \"2d\",\n });\n\n // Upload all mip levels for each face from the DDS (face-major layout).\n // Even though the skybox shader samples mip 0 explicitly, uploading all\n // mips avoids the need for GPU-side mipmap generation.\n let offset = 0;\n for (let face = 0; face < 6; face++) {\n for (let m = 0; m < mipCount; m++) {\n const s = Math.max(width >> m, 1);\n device.queue.writeTexture(\n { texture: tex, origin: { x: 0, y: 0, z: face }, mipLevel: m },\n raw.buffer,\n { offset: raw.byteOffset + offset, bytesPerRow: s * 8 },\n { width: s, height: s }\n );\n offset += s * s * 8;\n }\n }\n\n const cubeView = tex.createView({ dimension: \"cube\" });\n const sampler = getOrCreateSampler(engine, {\n magFilter: \"linear\",\n minFilter: \"linear\",\n mipmapFilter: \"linear\",\n addressModeU: \"clamp-to-edge\",\n addressModeV: \"clamp-to-edge\",\n addressModeW: \"clamp-to-edge\",\n maxAnisotropy: 4,\n });\n\n return { cubeView, sampler };\n}\n"],"names":[],"mappings":";;;AAAA,MAAA,mBAAe;ACAf,MAAA,mBAAe;ACef,MAAM,uBAAuB;AAC7B,MAAM,kBAAkB;AAExB,SAAS,oBAAoB,QAAuB,GAA6E;AAE7H,QAAM,YAAY,IAAI,aAAa;AAAA,IAClC;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,IAAG,CAAC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IACpC;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IAAG,CAAC;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IAAI;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IACpC;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IAAI;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IAAI;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IACrC,CAAC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG,CAAC;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IACrC,CAAC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG,CAAC;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IAAI;AAAA,IAAG;AAAA,IAAE,CAAC;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IACpC;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,IAAI;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG,CAAC;AAAA,IAAE,CAAC;AAAA,IAAG;AAAA,EAAA,CACtC;AAEC,QAAM,UAAU,IAAI,YAAY;AAAA,IAC/B;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAK;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IACtC;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IACrC;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,IAAK;AAAA,IAAG;AAAA,IAAG;AAAA,IAAI;AAAA,IAAG;AAAA,IAAG;AAAA,EAAA,CACtC;AACC,SAAO;AAAA,IACH,WAAW,mBAAmB,QAAQ,WAAW,eAAe,MAAM;AAAA,IACtE,WAAW,mBAAmB,QAAQ,SAAS,eAAe,KAAK;AAAA,IACnE,UAAU;AAAA,EAAA;AAElB;AAEA,SAAS,uBAAuB,cAA8C;AAC1E,QAAM,QAAQ,IAAI,aAAa,EAAE;AACjC,QAAM,CAAC,IAAI;AACX,QAAM,CAAC,IAAI;AACX,QAAM,EAAE,IAAI;AACZ,QAAM,EAAE,IAAI;AACZ,QAAM,EAAE,IAAI,aAAa,CAAC;AAC1B,QAAM,EAAE,IAAI,aAAa,CAAC;AAC1B,QAAM,EAAE,IAAI,aAAa,CAAC;AAC1B,SAAO;AACX;AAGA,eAAsB,yBAClB,OACA,aACA,cACA,cACA,kBACA,cAAc,MACK;AACnB,QAAM,SAAS,MAAM;AAErB,QAAM,cAAc,uBAAuB,YAAY;AAEvD,QAAM,UAAU,oBAAoB,QAAQ,WAAW;AACvD,QAAM,EAAE,UAAU,QAAA,IAAY,MAAM,YAAY,QAAQ,oBAAoB,eAAe;AAE3F,QAAM,WAAW,kBAAkB,cAAc,cAAc,kBAAkB;AACjF,QAAM,MAAM,4BAA4B,cAAc,eAAe,eAAe,iBAAiB,kBAAkB,QAAQ;AAC/H,QAAM,MAAM,iBAAiB,QAAQ,aAAa,cAAc,MAAM,gBAAgB,UAAU,MAAM,gBAAgB,QAAQ;AAC9H,QAAM,YAAY,IAAI,gBAAgB,QAAQ,KAAK,UAAU,OAAO;AAEpE,QAAM,IAAgB;AAAA,IAClB,OAAO;AAAA,IACP,eAAe;AAAA,IACf,KAAK,KAAK,KAAK;AACX,aAAO;AAAA,QACH,YAAY;AAAA,QACZ,UAAU,IAAI,YAAY,KAAsB,GAAG;AAAA,QACnD,KAAK,MAAM;AACP,eAAK,aAAa,GAAG,SAAS;AAC9B,eAAK,gBAAgB,GAAG,QAAQ,SAAS;AACzC,eAAK,eAAe,QAAQ,WAAW,QAAQ;AAC/C,eAAK,YAAY,QAAQ,QAAQ;AACjC,iBAAO;AAAA,QACX;AAAA,MAAA;AAAA,IAER;AAAA,EAAA;AAEJ,SAAO;AACX;AAIA,SAAS,iBAAiB,QAAuB,OAAqB,cAAwC,gBAAwB,UAA6B;AAC/J,QAAM,OAAO,IAAI,aAAa,uBAAuB,CAAC;AACtD,OAAK,IAAI,OAAO,CAAC;AACjB,OAAK,EAAE,IAAI,aAAa,CAAC;AACzB,OAAK,EAAE,IAAI,aAAa,CAAC;AACzB,OAAK,EAAE,IAAI,aAAa,CAAC;AACzB,OAAK,EAAE,IAAI;AACX,OAAK,EAAE,IAAI;AACX,SAAO,oBAAoB,QAAQ,IAAI;AAC3C;AAOA,eAAe,YAAY,QAAuB,KAAyE;AACvH,QAAM,SAAS,OAAO;AACtB,QAAM,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG,YAAA;AACrC,QAAM,SAAS,IAAI,WAAW,KAAK,GAAG,EAAE;AACxC,QAAM,QAAQ,OAAO,CAAC;AACtB,QAAM,SAAS,OAAO,CAAC;AACvB,QAAM,WAAW,KAAK,IAAI,OAAO,CAAC,GAAI,CAAC;AAKvC,QAAM,aAAa,OAAO,EAAE,MAAM,YAA0B,MAAM,KAAK;AACvE,QAAM,MAAM,IAAI,WAAW,KAAK,UAAU;AAE1C,QAAM,MAAwB;AAC9B,QAAM,MAAM,OAAO,cAAc;AAAA,IAC7B,MAAM,CAAC,OAAO,QAAQ,CAAC;AAAA,IACvB,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,OAAO,gBAAgB,kBAAkB,gBAAgB,WAAW,gBAAgB;AAAA,IACpF,WAAW;AAAA,EAAA,CACd;AAKD,MAAI,SAAS;AACb,WAAS,OAAO,GAAG,OAAO,GAAG,QAAQ;AACjC,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AAC/B,YAAM,IAAI,KAAK,IAAI,SAAS,GAAG,CAAC;AAChC,aAAO,MAAM;AAAA,QACT,EAAE,SAAS,KAAK,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,QAAQ,UAAU,EAAA;AAAA,QAC3D,IAAI;AAAA,QACJ,EAAE,QAAQ,IAAI,aAAa,QAAQ,aAAa,IAAI,EAAA;AAAA,QACpD,EAAE,OAAO,GAAG,QAAQ,EAAA;AAAA,MAAE;AAE1B,gBAAU,IAAI,IAAI;AAAA,IACtB;AAAA,EACJ;AAEA,QAAM,WAAW,IAAI,WAAW,EAAE,WAAW,QAAQ;AACrD,QAAM,UAAU,mBAAmB,QAAQ;AAAA,IACvC,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,EAAA,CAClB;AAED,SAAO,EAAE,UAAU,QAAA;AACvB;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"background-ground-DIw6D3qf.js","sources":["../shaders/background.vertex.wgsl?raw","../shaders/background.ground.fragment.wgsl?raw","../src/material/pbr/background-ground.ts"],"sourcesContent":["export default \"// Background Ground Vertex Shader\\n// Matches BJS shd_15: DIFFUSE, OPACITYFRESNEL, PREMULTIPLYALPHA (no REFLECTION)\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\nstruct VertexInput {\\n @location(0) position: vec3<f32>,\\n @location(1) normal: vec3<f32>,\\n @location(2) uv: vec2<f32>,\\n};\\n\\nstruct VertexOutput {\\n @builtin(position) clipPos: vec4<f32>,\\n @location(0) vPositionW: vec3<f32>,\\n @location(1) vNormalW: vec3<f32>,\\n @location(2) vUV: vec2<f32>,\\n};\\n\\n@vertex\\nfn main(input: VertexInput) -> VertexOutput {\\n var output: VertexOutput;\\n let finalWorld = mesh.world;\\n let worldPos4 = finalWorld * vec4<f32>(input.position, 1.0);\\n output.vPositionW = worldPos4.xyz;\\n output.clipPos = scene.viewProjection * worldPos4;\\n let normalWorld = mat3x3<f32>(finalWorld[0].xyz, finalWorld[1].xyz, finalWorld[2].xyz);\\n output.vNormalW = normalize(normalWorld * input.normal);\\n output.vUV = input.uv;\\n return output;\\n}\\n\"","export default \"// Background Ground Fragment Shader\\n// Matches BJS shd_16: DIFFUSE, OPACITYFRESNEL, PREMULTIPLYALPHA (no REFLECTION)\\n// Verified via Spector.GPU capture of BJS scene 1\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n alpha: f32,\\n backgroundCenter: vec3<f32>,\\n _pad: f32,\\n};\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n\\n@group(1) @binding(1) var groundTexture: texture_2d<f32>;\\n@group(1) @binding(2) var groundSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) vPositionW: vec3<f32>,\\n @location(1) vNormalW: vec3<f32>,\\n @location(2) vUV: vec2<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let normalW = normalize(input.vNormalW);\\n\\n // Sample diffuse texture (BJS backgroundGround.png: white RGB, radial alpha gradient)\\n let diffuseMap = textureSample(groundTexture, groundSampler, input.vUV);\\n\\n // BJS: reflectionColor = vec4(1) (no REFLECTION define)\\n let diffuseColor = diffuseMap.rgb;\\n let colorBase = max(diffuseColor, vec3<f32>(0.0));\\n let mainColor = mesh.primaryColor;\\n let finalColor = colorBase * mainColor;\\n\\n // Alpha starts from material alpha, multiplied by texture alpha\\n var finalAlpha = mesh.alpha * diffuseMap.a;\\n\\n // OPACITYFRESNEL — BJS shd_16 lines 367-370\\n let viewAngleToFloor = dot(normalW, normalize(scene.vEyePosition.xyz - mesh.backgroundCenter));\\n const startAngle: f32 = 0.1;\\n let fadeFactor = clamp(viewAngleToFloor / startAngle, 0.0, 1.0);\\n finalAlpha *= fadeFactor * fadeFactor;\\n\\n // Image processing (preserves alpha)\\n var color = vec4<f32>(finalColor, finalAlpha);\\n if (scene.vImageInfos.w >= 0.0) {\\n color = applyImageProcessing(color);\\n }\\n\\n // PREMULTIPLYALPHA — BJS shd_16 line 373\\n color = vec4<f32>(color.rgb * color.a, color.a);\\n\\n // Dithering\\n color = vec4<f32>(color.rgb + vec3<f32>(dither(input.vPositionW.xy, 0.5)), color.a);\\n color = max(color, vec4<f32>(0.0));\\n\\n return color;\\n}\\n\"","/** Ground plane renderable — lazy-loaded only when a scene includes a ground.\n * Contains the ground material, mesh buffers, texture loading, and UBO creation.\n * Tree-shaken away from scenes that use `skipGround: true`. */\n\nimport type { Mat4 } from \"../../math/types.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport { getBilinearSampler } from \"../../resource/samplers.js\";\nimport { createUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport groundVertSrc from \"../../../shaders/background.vertex.wgsl?raw\";\nimport groundFragSrc from \"../../../shaders/background.ground.fragment.wgsl?raw\";\nimport { createMappedBuffer } from \"../../resource/gpu-buffers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { WGSL_DITHER, WGSL_NO_DITHER } from \"../../shader/wgsl-helpers.js\";\n\n// ── Ground-frag-only WGSL helpers (kept here so scenes that don't load the ground\n// don't pay for the image-processing helper in the shared wgsl-helpers chunk). ──\n\n/** Image processing: exposure → Reinhard tonemap → gamma → contrast. */\nconst WGSL_IMAGE_PROCESSING = `\nfn applyImageProcessing(result: vec4<f32>) -> vec4<f32> {\nvar rgb = result.rgb;\nrgb *= scene.vImageInfos.x;\nconst tonemappingCalibration: f32 = 1.590579;\nrgb = 1.0 - exp2(-tonemappingCalibration * rgb);\nrgb = pow(rgb, vec3<f32>(1.0 / 2.2));\nrgb = clamp(rgb, vec3<f32>(0.0), vec3<f32>(1.0));\nlet highContrast = rgb * rgb * (3.0 - 2.0 * rgb);\nif (scene.vImageInfos.y < 1.0) {\nrgb = mix(vec3<f32>(0.5), rgb, scene.vImageInfos.y);\n} else {\nrgb = mix(rgb, highContrast, scene.vImageInfos.y - 1.0);\n}\nrgb = max(rgb, vec3<f32>(0.0));\nreturn vec4<f32>(rgb, result.a);\n}\n`;\n\nconst BG_MESH_UNIFORM_SIZE = 96; // mat4x4 + primaryColor vec3 + alpha + backgroundCenter vec3 + pad\n\n/** Build the ground renderable for a PBR environment scene. */\nexport async function buildGroundRenderable(\n engine: EngineContext,\n groundSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number],\n groundTextureUrl?: string,\n groundImagePromise?: Promise<ImageBitmap>,\n enableNoise = true\n): Promise<Renderable> {\n const fragCode = SCENE_UBO_WGSL + WGSL_IMAGE_PROCESSING + (enableNoise ? WGSL_DITHER : WGSL_NO_DITHER) + groundFragSrc;\n const gndMat = createGroundMaterial(enableNoise, fragCode);\n\n // Ground world: rotated 90° X (XY→XZ), translated to rootPosition\n // Column-major for WGSL: ground quad in XY plane, normal +Z → world +Y\n // Offset Y by -0.01 to prevent z-fighting with scene floor geometry.\n const eps = 2.220446049250313e-16;\n const groundWorld = new Float32Array(16) as Mat4;\n groundWorld[0] = 1;\n groundWorld[5] = eps;\n groundWorld[6] = -1;\n groundWorld[9] = 1;\n groundWorld[10] = eps;\n groundWorld[12] = rootPosition[0];\n groundWorld[13] = rootPosition[1];\n groundWorld[14] = rootPosition[2];\n groundWorld[15] = 1;\n\n const gndBufs = createGroundBuffers(engine, groundSize);\n const gndUBO = createBgMeshUBO(engine, groundWorld, primaryColor);\n\n const groundTex = await loadGroundTexture(engine, groundTextureUrl, groundImagePromise);\n const groundTexView = groundTex.createView();\n const groundSamp = getBilinearSampler(engine);\n const gndBG = gndMat.createBindGroup(engine, gndUBO, groundTexView, groundSamp);\n\n const r: Renderable = {\n order: 200, // ground renders last (transparent)\n isTransparent: true,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: gndMat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, gndBG);\n pass.setVertexBuffer(0, gndBufs.posBuffer);\n pass.setVertexBuffer(1, gndBufs.normBuffer);\n pass.setVertexBuffer(2, gndBufs.uvBuffer);\n pass.setIndexBuffer(gndBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(gndBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── Ground Material ────────────────────────────────────────────────────────\n\ninterface GroundMaterial {\n getPipeline(engine: EngineContext, sig: RenderTargetSignature): GPURenderPipeline;\n createBindGroup(engine: EngineContext, meshUBO: GPUBuffer, groundTextureView: GPUTextureView, groundSampler: GPUSampler): GPUBindGroup;\n}\n\n/** Module-global pipeline cache — keyed by noise mode + full target signature (color/depth/samples/flipY).\n * All ground renderables share this cache. */\nconst _gndPipelines = new Map<string, GPURenderPipeline>();\nlet _gndLayout: GPUBindGroupLayout | null = null;\nlet _gndCachedDevice: GPUDevice | null = null;\n\nfunction createGroundMaterial(enableNoise: boolean, fragCode: string): GroundMaterial {\n function getLayout(engine: EngineContext): GPUBindGroupLayout {\n const device = engine._device;\n if (_gndLayout && _gndCachedDevice === device) {\n return _gndLayout;\n }\n _gndLayout = device.createBindGroupLayout({\n label: \"ground-material\",\n entries: [\n { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: \"uniform\" } },\n { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: \"float\", viewDimension: \"2d\" } },\n { binding: 2, visibility: GPUShaderStage.FRAGMENT, sampler: { type: \"filtering\" } },\n ],\n });\n _gndCachedDevice = device;\n return _gndLayout;\n }\n\n return {\n getPipeline(engine, sig) {\n const device = engine._device;\n if (_gndCachedDevice !== device) {\n _gndPipelines.clear();\n _gndLayout = null;\n _gndCachedDevice = device;\n }\n const key = `${+enableNoise}|${targetSignatureKey(sig)}`;\n const cached = _gndPipelines.get(key);\n if (cached) {\n return cached;\n }\n const vertModule = device.createShaderModule({ code: SCENE_UBO_WGSL + groundVertSrc, label: \"ground-vert\" });\n const fragModule = device.createShaderModule({ code: fragCode, label: \"ground-frag\" });\n\n // Matches BJS rp_8: premultiplied alpha blend, depthWrite=false\n const pipeline = device.createRenderPipeline({\n label: \"ground-pipeline\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [getSceneBindGroupLayout(engine), getLayout(engine)] }),\n vertex: {\n module: vertModule,\n entryPoint: \"main\",\n buffers: [\n { arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x3\" as GPUVertexFormat }] },\n { arrayStride: 12, attributes: [{ shaderLocation: 1, offset: 0, format: \"float32x3\" as GPUVertexFormat }] },\n { arrayStride: 8, attributes: [{ shaderLocation: 2, offset: 0, format: \"float32x2\" as GPUVertexFormat }] },\n ],\n },\n fragment: {\n module: fragModule,\n entryPoint: \"main\",\n targets: [\n {\n format: sig._colorFormat!,\n blend: {\n color: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n },\n },\n ],\n },\n depthStencil: {\n format: sig._depthStencilFormat ?? \"depth24plus-stencil8\",\n depthCompare: sig._depthCompare ?? \"greater-equal\",\n depthWriteEnabled: false,\n },\n multisample: { count: sig._sampleCount },\n primitive: { topology: \"triangle-list\", cullMode: \"back\", frontFace: sig._flipY ? \"cw\" : \"ccw\" },\n });\n _gndPipelines.set(key, pipeline);\n return pipeline;\n },\n\n createBindGroup(engine, meshUBO, groundTextureView, groundSampler) {\n const device = engine._device;\n return device.createBindGroup({\n layout: getLayout(engine),\n entries: [\n { binding: 0, resource: { buffer: meshUBO } },\n { binding: 1, resource: groundTextureView },\n { binding: 2, resource: groundSampler },\n ],\n });\n },\n };\n}\n\n// ─── Ground Mesh Data ───────────────────────────────────────────────────────\n\n/** Ground quad (4 verts, 6 indices — matches BJS CreatePlane with BACKSIDE).\n * XY plane, normals +Z (become +Y after world rotation). */\nfunction createGroundBuffers(\n engine: EngineContext,\n groundSize: number\n): {\n posBuffer: GPUBuffer;\n normBuffer: GPUBuffer;\n uvBuffer: GPUBuffer;\n idxBuffer: GPUBuffer;\n idxCount: number;\n} {\n const h = groundSize / 2;\n // prettier-ignore\n const positions = new Float32Array([\n -h, -h, 0,\n h, -h, 0,\n h, h, 0,\n -h, h, 0,\n ]);\n // prettier-ignore\n const normals = new Float32Array([\n 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,\n ]);\n // prettier-ignore\n const uvs = new Float32Array([\n 0, 0, 1, 0, 1, 1, 0, 1,\n ]);\n // BACKSIDE winding\n // prettier-ignore\n const indices = new Uint16Array([0, 2, 1, 0, 3, 2]);\n\n return {\n posBuffer: createMappedBuffer(engine, positions, GPUBufferUsage.VERTEX),\n normBuffer: createMappedBuffer(engine, normals, GPUBufferUsage.VERTEX),\n uvBuffer: createMappedBuffer(engine, uvs, GPUBufferUsage.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, GPUBufferUsage.INDEX),\n idxCount: 6,\n };\n}\n\n// ─── Ground UBO ─────────────────────────────────────────────────────────────\n\nfunction createBgMeshUBO(engine: EngineContext, world: Mat4, primaryColor: [number, number, number]): GPUBuffer {\n const data = new Float32Array(BG_MESH_UNIFORM_SIZE / 4);\n data.set(world, 0); // offset 0: world mat4x4\n data[16] = primaryColor[0]; // offset 64: primaryColor.r\n data[17] = primaryColor[1]; // offset 68: primaryColor.g\n data[18] = primaryColor[2]; // offset 72: primaryColor.b\n data[19] = 0.9; // offset 76: alpha (BJS default groundOpacity)\n data[20] = 0;\n data[21] = 0;\n data[22] = 0; // offset 80: backgroundCenter\n return createUniformBuffer(engine, data);\n}\n\n// ─── Ground Texture ─────────────────────────────────────────────────────────\n\n/** Load a ground diffuse texture from URL and upload to GPU.\n * Falls back to a 1×1 white pixel if no URL provided. */\nasync function loadGroundTexture(engine: EngineContext, url?: string, preloadedImage?: Promise<ImageBitmap>): Promise<GPUTexture> {\n const device = engine._device;\n if (!url) {\n const tex = device.createTexture({\n size: [1, 1],\n format: \"rgba8unorm\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n });\n device.queue.writeTexture({ texture: tex }, new Uint8Array([255, 255, 255, 255]), { bytesPerRow: 4 }, [1, 1]);\n return tex;\n }\n // Use pre-fetched image if available (started early in loadEnvironment)\n const bmp = preloadedImage\n ? await preloadedImage\n : await fetch(url)\n .then((r) => r.blob())\n .then((b) => createImageBitmap(b, { premultiplyAlpha: \"none\" }));\n const tex = device.createTexture({\n size: [bmp.width, bmp.height],\n format: \"rgba8unorm\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n });\n device.queue.copyExternalImageToTexture({ source: bmp }, { texture: tex }, [bmp.width, bmp.height]);\n bmp.close();\n return tex;\n}\n"],"names":["tex"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"background-hdr-skybox-c4uuTmkP.js","sources":["../shaders/skybox-hdr.fragment.wgsl?raw","../src/material/pbr/background-hdr-skybox.ts"],"sourcesContent":["export default \"// HDR Skybox Fragment Shader — samples HDR environment cubemap with image processing.\\n// Used when scene has an HDR environment rendered as the background.\\n// Matches BJS BackgroundMaterial: cubemap at LOD 0 + exposure + gamma + contrast.\\n\\nstruct MeshUniforms {\\n world: mat4x4<f32>,\\n primaryColor: vec3<f32>,\\n _pad: f32,\\n skyOutputColor: vec3<f32>,\\n _pad2: f32,\\n exposureLinear: f32,\\n contrast: f32,\\n _pad3: f32,\\n _pad4: f32,\\n};\\n\\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\\n@group(1) @binding(1) var envCubemap: texture_cube<f32>;\\n@group(1) @binding(2) var envSampler: sampler;\\n\\nstruct FragmentInput {\\n @location(0) positionUVW: vec3<f32>,\\n @location(1) positionW: vec3<f32>,\\n};\\n\\n@fragment\\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\\n let dir = normalize(input.positionUVW);\\n var color = textureSampleLevel(envCubemap, envSampler, dir, 0.0).rgb;\\n\\n // Image processing: exposure → gamma → contrast (matches BJS applyImageProcessing)\\n color *= mesh.exposureLinear;\\n color = pow(color, vec3<f32>(1.0 / 2.2));\\n color = clamp(color, vec3<f32>(0.0), vec3<f32>(1.0));\\n\\n let highContrast = color * color * (3.0 - 2.0 * color);\\n if (mesh.contrast < 1.0) { color = mix(vec3<f32>(0.5), color, mesh.contrast); }\\n else { color = mix(color, highContrast, mesh.contrast - 1.0); }\\n color = max(color, vec3<f32>(0.0));\\n\\n return vec4<f32>(color, 1.0);\\n}\\n\"","/** HDR cubemap skybox — lazy-loaded only when useCubemapSkybox is true.\n * Contains the HDR skybox material, shader, UBO, and skybox geometry.\n * Self-contained: computes scene bounds and builds a full Renderable.\n * Tree-shaken away from scenes that use the default solid-color skybox. */\n\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { EnvironmentTextures } from \"../../loader-env/load-env.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport type { Renderable } from \"../../render/renderable.js\";\nimport { createCubemapSkyboxMaterial } from \"./cubemap-skybox-material.js\";\nimport skyboxVertSrc from \"../../../shaders/skybox.vertex.wgsl?raw\";\nimport skyboxHdrFragSrc from \"../../../shaders/skybox-hdr.fragment.wgsl?raw\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { createMappedBuffer, createUniformBuffer } from \"../../resource/gpu-buffers.js\";\n\nconst SKY_HDR_UNIFORM_SIZE = 112; // mat4x4 + primaryColor vec3 + pad + skyOutputColor vec3 + pad + exposure + contrast + pad2\n\nfunction createSkyboxBuffers(engine: EngineContext, S: number): { posBuffer: GPUBuffer; idxBuffer: GPUBuffer; idxCount: number } {\n // prettier-ignore\n const positions = new Float32Array([\n S,-S, S, -S,-S, S, -S, S, S, S, S, S,\n S, S,-S, -S, S,-S, -S,-S,-S, S,-S,-S,\n S, S,-S, S,-S,-S, S,-S, S, S, S, S,\n -S, S, S, -S,-S, S, -S,-S,-S, -S, S,-S,\n -S, S, S, -S, S,-S, S, S,-S, S, S, S,\n S,-S, S, S,-S,-S, -S,-S,-S, -S,-S, S,\n ]);\n // prettier-ignore\n const indices = new Uint16Array([\n 2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4,\n 10, 9, 8, 11,10, 8, 14,13,12, 15,14,12,\n 18,17,16, 19,18,16, 22,21,20, 23,22,20,\n ]);\n return {\n posBuffer: createMappedBuffer(engine, positions, GPUBufferUsage.VERTEX),\n idxBuffer: createMappedBuffer(engine, indices, GPUBufferUsage.INDEX),\n idxCount: 36,\n };\n}\n\nfunction buildSkyboxWorldMatrix(rootPosition: [number, number, number]): Mat4 {\n const world = new Float32Array(16) as Mat4;\n world[0] = 1;\n world[5] = 1;\n world[10] = 1;\n world[15] = 1;\n world[12] = rootPosition[0];\n world[13] = rootPosition[1];\n world[14] = rootPosition[2];\n return world;\n}\n\n/** Build an HDR cubemap skybox as a complete Renderable (order 0). */\nexport function buildHdrSkyboxRenderable(\n scene: SceneContext,\n envTextures: EnvironmentTextures,\n skyHalfSize: number,\n rootPosition: [number, number, number],\n primaryColor: [number, number, number]\n): Renderable {\n const engine = scene.engine;\n\n const skyboxWorld = buildSkyboxWorldMatrix(rootPosition);\n\n const cc = scene.clearColor;\n\n const skyBufs = createSkyboxBuffers(engine, skyHalfSize);\n const mat = createCubemapSkyboxMaterial(\"skybox-hdr\", SCENE_UBO_WGSL + skyboxVertSrc, skyboxHdrFragSrc);\n const ubo = createSkyHdrMeshUBO(engine, skyboxWorld, primaryColor, [cc.r, cc.g, cc.b], scene.imageProcessing.exposure, scene.imageProcessing.contrast);\n\n const bindGroup = mat.createBindGroup(engine, ubo, envTextures.specularCubeView!, envTextures.cubeSampler);\n\n const r: Renderable = {\n order: 0,\n isTransparent: false,\n bind(eng, sig) {\n return {\n renderable: r,\n pipeline: mat.getPipeline(eng as EngineContext, sig),\n draw(pass) {\n pass.setBindGroup(1, bindGroup);\n pass.setVertexBuffer(0, skyBufs.posBuffer);\n pass.setIndexBuffer(skyBufs.idxBuffer, \"uint16\");\n pass.drawIndexed(skyBufs.idxCount);\n return 1;\n },\n };\n },\n };\n return r;\n}\n\n// ─── HDR Skybox UBO ─────────────────────────────────────────────────────────────\n\nfunction createSkyHdrMeshUBO(\n engine: EngineContext,\n world: Float32Array,\n primaryColor: [number, number, number],\n skyOutputColor: [number, number, number],\n exposure: number,\n contrast: number\n): GPUBuffer {\n const data = new Float32Array(SKY_HDR_UNIFORM_SIZE / 4);\n data.set(world, 0);\n data[16] = primaryColor[0];\n data[17] = primaryColor[1];\n data[18] = primaryColor[2];\n data[20] = skyOutputColor[0];\n data[21] = skyOutputColor[1];\n data[22] = skyOutputColor[2];\n data[24] = exposure; // exposureLinear\n data[25] = contrast; // contrast\n return createUniformBuffer(engine, data);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-ext-basisu-CPg5kPrx.js","sources":["../src/texture/ktx2-loader.ts","../src/loader-gltf/gltf-ext-basisu.ts"],"sourcesContent":["/** KTX2/Basis Universal decoder for glTF KHR_texture_basisu.\n *\n * Kept separate from `basis-loader.ts` so existing `.basis` texture scenes do\n * not pay for KTX2 decoder glue. The CDN decoder is still fetched lazily only\n * after an asset declares KHR_texture_basisu.\n */\n\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { acquireTexture, getOrCreateSampler } from \"../resource/gpu-pool.js\";\nimport type { Texture2D } from \"./texture-2d.js\";\nimport { getCompressedFormat } from \"./compressed-formats.js\";\nimport type { CompressedFormatInfo } from \"./compressed-formats.js\";\n\ninterface Ktx2DecoderCaps {\n astc: boolean;\n bptc: boolean;\n s3tc: boolean;\n pvrtc: boolean;\n etc2: boolean;\n etc1: boolean;\n}\n\ninterface Ktx2DecodedMip {\n width: number;\n height: number;\n data: Uint8Array;\n}\n\ninterface Ktx2DecodedData {\n width: number;\n height: number;\n transcodedFormat: number;\n isInGammaSpace: boolean;\n hasAlpha: boolean;\n transcoderName: string;\n errors?: string;\n mipmaps: Ktx2DecodedMip[];\n}\n\ninterface Ktx2Decoder {\n decode(data: Uint8Array, caps: Ktx2DecoderCaps, options?: { forceRGBA?: boolean }): Promise<Ktx2DecodedData>;\n}\n\ninterface Ktx2DecoderModule {\n KTX2Decoder: new () => Ktx2Decoder;\n MSCTranscoder: { UseFromWorkerThread: boolean };\n WASMMemoryManager: { LoadBinariesFromCurrentThread: boolean };\n}\n\nconst KTX2_DECODER_URL = \"https://cdn.babylonjs.com/babylon.ktx2Decoder.js\";\nlet _ktx2DecoderPromise: Promise<Ktx2Decoder> | null = null;\n\nconst GL_RGBA8 = 0x8058;\nconst GL_R8 = 0x8229;\nconst GL_RG8 = 0x822b;\nconst RGBA_CAPS: Ktx2DecoderCaps = { astc: false, bptc: false, s3tc: false, pvrtc: false, etc2: false, etc1: false };\n\nfunction loadKtx2Decoder(): Promise<Ktx2Decoder> {\n if (_ktx2DecoderPromise) {\n return _ktx2DecoderPromise;\n }\n _ktx2DecoderPromise = new Promise<Ktx2Decoder>((resolve, reject) => {\n const w = globalThis as unknown as { KTX2DECODER?: Ktx2DecoderModule };\n const init = (): void => {\n const mod = w.KTX2DECODER;\n if (!mod) {\n reject(new Error(\"KTX2: decoder global KTX2DECODER not found after script load\"));\n return;\n }\n mod.MSCTranscoder.UseFromWorkerThread = false;\n mod.WASMMemoryManager.LoadBinariesFromCurrentThread = true;\n resolve(new mod.KTX2Decoder());\n };\n if (w.KTX2DECODER) {\n init();\n return;\n }\n const script = document.createElement(\"script\");\n script.src = KTX2_DECODER_URL;\n script.async = true;\n script.onload = init;\n script.onerror = (): void => reject(new Error(`KTX2: failed to load ${script.src}`));\n document.head.appendChild(script);\n });\n _ktx2DecoderPromise.catch(() => {\n _ktx2DecoderPromise = null;\n });\n return _ktx2DecoderPromise;\n}\n\nfunction srgbFormat(format: GPUTextureFormat): GPUTextureFormat {\n switch (format) {\n case \"rgba8unorm\":\n return \"rgba8unorm-srgb\";\n case \"bc1-rgba-unorm\":\n return \"bc1-rgba-unorm-srgb\";\n case \"bc2-rgba-unorm\":\n return \"bc2-rgba-unorm-srgb\";\n case \"bc3-rgba-unorm\":\n return \"bc3-rgba-unorm-srgb\";\n case \"bc7-rgba-unorm\":\n return \"bc7-rgba-unorm-srgb\";\n case \"etc2-rgb8unorm\":\n return \"etc2-rgb8unorm-srgb\";\n case \"etc2-rgb8a1unorm\":\n return \"etc2-rgb8a1unorm-srgb\";\n case \"etc2-rgba8unorm\":\n return \"etc2-rgba8unorm-srgb\";\n case \"astc-4x4-unorm\":\n return \"astc-4x4-unorm-srgb\";\n case \"astc-5x4-unorm\":\n return \"astc-5x4-unorm-srgb\";\n case \"astc-5x5-unorm\":\n return \"astc-5x5-unorm-srgb\";\n case \"astc-6x5-unorm\":\n return \"astc-6x5-unorm-srgb\";\n case \"astc-6x6-unorm\":\n return \"astc-6x6-unorm-srgb\";\n case \"astc-8x5-unorm\":\n return \"astc-8x5-unorm-srgb\";\n case \"astc-8x6-unorm\":\n return \"astc-8x6-unorm-srgb\";\n case \"astc-8x8-unorm\":\n return \"astc-8x8-unorm-srgb\";\n case \"astc-10x5-unorm\":\n return \"astc-10x5-unorm-srgb\";\n case \"astc-10x6-unorm\":\n return \"astc-10x6-unorm-srgb\";\n case \"astc-10x8-unorm\":\n return \"astc-10x8-unorm-srgb\";\n case \"astc-10x10-unorm\":\n return \"astc-10x10-unorm-srgb\";\n case \"astc-12x10-unorm\":\n return \"astc-12x10-unorm-srgb\";\n case \"astc-12x12-unorm\":\n return \"astc-12x12-unorm-srgb\";\n default:\n return format;\n }\n}\n\nfunction uncompressedInfo(glFormat: number): { format: GPUTextureFormat; bytesPerPixel: number } | null {\n switch (glFormat) {\n case GL_RGBA8:\n return { format: \"rgba8unorm\", bytesPerPixel: 4 };\n case GL_R8:\n return { format: \"r8unorm\", bytesPerPixel: 1 };\n case GL_RG8:\n return { format: \"rg8unorm\", bytesPerPixel: 2 };\n default:\n return null;\n }\n}\n\nfunction validateDecoded(decoded: Ktx2DecodedData): Ktx2DecodedMip[] {\n if (decoded.errors) {\n throw new Error(`KTX2: ${decoded.errors}`);\n }\n if (!decoded.mipmaps.length) {\n throw new Error(\"KTX2: decoder produced no mipmaps\");\n }\n for (let i = 0; i < decoded.mipmaps.length; i++) {\n if (!decoded.mipmaps[i]?.data) {\n throw new Error(`KTX2: decoder produced an empty mip ${i}`);\n }\n }\n return decoded.mipmaps;\n}\n\nfunction makeSampler(engine: EngineContext, mipCount: number): GPUSampler {\n return getOrCreateSampler(engine, {\n addressModeU: \"repeat\",\n addressModeV: \"repeat\",\n minFilter: \"linear\",\n magFilter: \"linear\",\n mipmapFilter: mipCount > 1 ? \"linear\" : \"nearest\",\n maxAnisotropy: mipCount > 1 ? 4 : 1,\n });\n}\n\nfunction uploadCompressed(engine: EngineContext, mips: Ktx2DecodedMip[], format: CompressedFormatInfo, sRGB: boolean): Texture2D {\n if (!engine._device.features.has(format.feature as GPUFeatureName)) {\n throw new Error(`KTX2: device does not support ${format.feature}`);\n }\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(format.gpuFormat) : format.gpuFormat,\n mipLevelCount: mips.length,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const rowBytes = Math.ceil(mip.width / format.blockW) * format.blockBytes;\n engine._device.queue.writeTexture({ texture, mipLevel: level }, mip.data as Uint8Array<ArrayBuffer>, { bytesPerRow: rowBytes }, { width: mip.width, height: mip.height });\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\nfunction uploadUncompressed(engine: EngineContext, mips: Ktx2DecodedMip[], info: { format: GPUTextureFormat; bytesPerPixel: number }, sRGB: boolean): Texture2D {\n const width = mips[0]!.width;\n const height = mips[0]!.height;\n const texture = engine._device.createTexture({\n size: { width, height },\n format: sRGB ? srgbFormat(info.format) : info.format,\n mipLevelCount: mips.length,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n });\n for (let level = 0; level < mips.length; level++) {\n const mip = mips[level]!;\n const expected = mip.width * mip.height * info.bytesPerPixel;\n if (mip.data.length !== expected) {\n throw new Error(`KTX2: uncompressed mip ${level} has ${mip.data.length} bytes, expected ${expected}`);\n }\n engine._device.queue.writeTexture(\n { texture, mipLevel: level },\n mip.data as Uint8Array<ArrayBuffer>,\n { bytesPerRow: mip.width * info.bytesPerPixel },\n { width: mip.width, height: mip.height }\n );\n }\n const tex2d: Texture2D = { texture, view: texture.createView(), sampler: makeSampler(engine, mips.length), width, height, invertY: true };\n acquireTexture(tex2d);\n return tex2d;\n}\n\n/** Decode a KTX2 texture with the current WebGPU compression caps and upload the\n * decoder-provided full mip chain directly to a Texture2D. */\nexport async function uploadKtx2Texture2D(engine: EngineContext, buffer: ArrayBuffer, sRGB: boolean): Promise<Texture2D> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new Uint8Array(buffer), RGBA_CAPS, { forceRGBA: true });\n const mips = validateDecoded(decoded);\n\n const compressed = getCompressedFormat(decoded.transcodedFormat);\n if (compressed) {\n return uploadCompressed(engine, mips, compressed, sRGB);\n }\n\n const uncompressed = uncompressedInfo(decoded.transcodedFormat);\n if (uncompressed) {\n return uploadUncompressed(engine, mips, uncompressed, sRGB);\n }\n\n throw new Error(`KTX2: unsupported transcoded format 0x${decoded.transcodedFormat.toString(16)}`);\n}\n\n/** Decode the first mip level of a KTX2 texture into an ImageBitmap so glTF\n * material extensions can reuse the core image upload path. */\nexport async function decodeKtx2ImageBitmapFromBuffer(buffer: ArrayBuffer): Promise<ImageBitmap> {\n const decoder = await loadKtx2Decoder();\n const decoded = await decoder.decode(new Uint8Array(buffer), RGBA_CAPS, { forceRGBA: true });\n const mip0 = validateDecoded(decoded)[0]!;\n if (mip0.data.length !== mip0.width * mip0.height * 4) {\n throw new Error(\"KTX2: RGBA decode size does not match image dimensions\");\n }\n const pixels = new Uint8ClampedArray(mip0.data.length);\n pixels.set(mip0.data);\n return createImageBitmap(new ImageData(pixels, mip0.width, mip0.height));\n}\n","/** KHR_texture_basisu glTF texture-source extension.\n *\n * The extension redirects textureInfos whose glTF texture declares\n * `extensions.KHR_texture_basisu.source` to the referenced KTX2 image and\n * uploads it through the lazily fetched KTX2 decoder. Core glTF\n * material parsing remains extension-agnostic: this module only loads when the\n * asset lists KHR_texture_basisu in `extensionsUsed`.\n */\n\nimport type { GltfMatExtCtx } from \"./gltf-material.js\";\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { DecodedPrimitive } from \"./gltf-feature.js\";\nimport type { PbrMaterialProps } from \"../material/pbr/pbr-material.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { decodeKtx2ImageBitmapFromBuffer, uploadKtx2Texture2D } from \"../texture/ktx2-loader.js\";\n\nconst NAME = \"KHR_texture_basisu\";\nconst FLOAT = 5126;\nconst TYPE_SIZES: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16,\n};\nconst BASISU_MATERIAL_DATA = \"__basisuMaterialData\";\n\ninterface BasisuMaterialData {\n json: any;\n binChunk: DataView;\n baseUrl: string;\n baseColorTexture?: any;\n metallicRoughnessTexture?: any;\n normalTexture?: any;\n occlusionTexture?: any;\n emissiveTexture?: any;\n specularTexture?: any;\n specularColorTexture?: any;\n bitmaps?: Map<number, Promise<ImageBitmap>>;\n textures?: Map<string, Texture2D>;\n}\n\nfunction basisSourceIndex(tex: unknown): number | null {\n const source = (tex as { extensions?: { KHR_texture_basisu?: { source?: unknown } } } | undefined)?.extensions?.KHR_texture_basisu?.source;\n return typeof source === \"number\" ? source : null;\n}\n\nfunction textureIndex(texInfo: unknown): number | null {\n const index = (texInfo as { index?: unknown } | undefined)?.index;\n return typeof index === \"number\" ? index : null;\n}\n\nfunction textureUsesBasisu(json: any, texInfo: unknown): boolean {\n const index = textureIndex(texInfo);\n return index !== null && basisSourceIndex(json.textures?.[index]) !== null;\n}\n\nfunction stripBasisuTexture(json: any, owner: any, slot: keyof BasisuMaterialData, data: BasisuMaterialData): boolean {\n if (!textureUsesBasisu(json, owner?.[slot])) {\n return false;\n }\n data[slot] = owner[slot];\n delete owner[slot];\n return true;\n}\n\nfunction prepareBasisuMaterials(json: any, binChunk: DataView, baseUrl: string): void {\n for (const mat of json.materials ?? []) {\n const data: BasisuMaterialData = { json, binChunk, baseUrl };\n const pbr = mat.pbrMetallicRoughness ?? {};\n let hasBasisu = stripBasisuTexture(json, pbr, \"baseColorTexture\", data);\n hasBasisu = stripBasisuTexture(json, pbr, \"metallicRoughnessTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"normalTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"occlusionTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, mat, \"emissiveTexture\", data) || hasBasisu;\n const spec = mat.extensions?.KHR_materials_specular;\n if (spec) {\n hasBasisu = stripBasisuTexture(json, spec, \"specularTexture\", data) || hasBasisu;\n hasBasisu = stripBasisuTexture(json, spec, \"specularColorTexture\", data) || hasBasisu;\n }\n if (hasBasisu) {\n Object.defineProperty(mat, BASISU_MATERIAL_DATA, { value: data });\n }\n }\n}\n\nasync function resolveImageBuffer(ctx: BasisuMaterialData, imageIdx: number): Promise<ArrayBuffer> {\n const image = ctx.json.images?.[imageIdx];\n if (!image) {\n throw new Error(`${NAME}: image ${imageIdx} not found`);\n }\n if (image.bufferView !== undefined) {\n const bv = ctx.json.bufferViews?.[image.bufferView];\n if (!bv) {\n throw new Error(`${NAME}: bufferView ${image.bufferView} not found`);\n }\n const offset = ctx.binChunk.byteOffset + (bv.byteOffset ?? 0);\n const copy = new Uint8Array(bv.byteLength);\n copy.set(new Uint8Array(ctx.binChunk.buffer, offset, bv.byteLength));\n return copy.buffer;\n }\n if (image.uri) {\n const url = new URL(image.uri, ctx.baseUrl + \"x\").href;\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`${NAME}: failed to load image ${response.status} ${response.statusText}`);\n }\n return response.arrayBuffer();\n }\n throw new Error(`${NAME}: image has neither bufferView nor uri`);\n}\n\nasync function loadBasisuBitmap(data: BasisuMaterialData, texInfo: unknown): Promise<ImageBitmap | null> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return null;\n }\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return null;\n }\n data.bitmaps ??= new Map();\n let bitmap = data.bitmaps.get(index);\n if (!bitmap) {\n bitmap = resolveImageBuffer(data, source).then(decodeKtx2ImageBitmapFromBuffer);\n data.bitmaps.set(index, bitmap);\n }\n return bitmap;\n}\n\nasync function uploadBasisuTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx, texInfo: unknown, sRGB: boolean): Promise<Texture2D | undefined> {\n const index = textureIndex(texInfo);\n if (index === null) {\n return undefined;\n }\n data.textures ??= new Map();\n const key = `${index}:${sRGB ? 1 : 0}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const source = basisSourceIndex(data.json.textures?.[index]);\n if (source === null) {\n return undefined;\n }\n tex = await uploadKtx2Texture2D(ctx._engine, await resolveImageBuffer(data, source), sRGB);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\nasync function compositeOrm(mr: ImageBitmap, occ: ImageBitmap): Promise<ImageBitmap> {\n const w = mr.width;\n const h = mr.height;\n const c1 = new OffscreenCanvas(w, h);\n const x1 = c1.getContext(\"2d\")!;\n x1.drawImage(mr, 0, 0, w, h);\n const d1 = x1.getImageData(0, 0, w, h);\n const c2 = new OffscreenCanvas(w, h);\n const x2 = c2.getContext(\"2d\")!;\n x2.drawImage(occ, 0, 0, w, h);\n const d2 = x2.getImageData(0, 0, w, h);\n for (let j = 0; j < d1.data.length; j += 4) {\n d1.data[j] = d2.data[j]!;\n }\n x1.putImageData(d1, 0, 0);\n return createImageBitmap(c1);\n}\n\nasync function uploadOrmTexture(data: BasisuMaterialData, ctx: GltfMatExtCtx): Promise<Texture2D | undefined> {\n const mrInfo = data.metallicRoughnessTexture;\n const occInfo = data.occlusionTexture;\n const mrIndex = textureIndex(mrInfo);\n const occIndex = textureIndex(occInfo);\n if (mrIndex === null && occIndex === null) {\n return undefined;\n }\n if (mrIndex === null || occIndex === null || mrIndex === occIndex) {\n return uploadBasisuTexture(data, ctx, mrInfo ?? occInfo, false);\n }\n data.textures ??= new Map();\n const key = `orm:${mrIndex}:${occIndex}`;\n let tex = data.textures.get(key);\n if (!tex) {\n const [mr, occ] = await Promise.all([loadBasisuBitmap(data, mrInfo), loadBasisuBitmap(data, occInfo)]);\n if (!mr || !occ) {\n return undefined;\n }\n tex = ctx._uploadImage(await compositeOrm(mr, occ), false);\n data.textures.set(key, tex);\n }\n return tex;\n}\n\nfunction readStridedFloat(json: any, binChunk: DataView, accessorIdx: number): Float32Array {\n const accessor = json.accessors[accessorIdx];\n const bufferView = json.bufferViews[accessor.bufferView];\n if (accessor.componentType !== FLOAT) {\n throw new Error(`${NAME}: strided accessor ${accessorIdx} uses unsupported component type: ${accessor.componentType}`);\n }\n const componentCount = TYPE_SIZES[accessor.type] ?? 1;\n const elementBytes = componentCount * 4;\n const byteStride = bufferView.byteStride ?? elementBytes;\n if (byteStride < elementBytes) {\n throw new Error(`${NAME}: invalid accessor stride ${byteStride} for accessor ${accessorIdx}`);\n }\n const baseOffset = binChunk.byteOffset + (bufferView.byteOffset ?? 0) + (accessor.byteOffset ?? 0);\n const view = new DataView(binChunk.buffer);\n const out = new Float32Array(accessor.count * componentCount);\n for (let i = 0, o = 0; i < accessor.count; i++) {\n const src = baseOffset + i * byteStride;\n for (let c = 0; c < componentCount; c++, o++) {\n out[o] = view.getFloat32(src + c * 4, true);\n }\n }\n return out;\n}\n\nconst ext: GltfFeature = {\n id: NAME,\n async preMesh(json, binChunk, baseUrl) {\n const gltf = json as any;\n prepareBasisuMaterials(gltf, binChunk, baseUrl);\n const decoded = new Map<unknown, DecodedPrimitive>();\n for (const mesh of gltf.meshes ?? []) {\n for (const primitive of mesh.primitives ?? []) {\n const attrs = primitive.attributes ?? {};\n const strided = Object.keys(attrs).some((name) => gltf.bufferViews?.[gltf.accessors?.[attrs[name]]?.bufferView]?.byteStride !== undefined);\n if (!strided) {\n continue;\n }\n const attributes = new Map<string, Float32Array>();\n for (const name of Object.keys(attrs)) {\n const accessorIdx = attrs[name];\n const accessor = gltf.accessors[accessorIdx];\n if (gltf.bufferViews?.[accessor.bufferView]?.byteStride !== undefined) {\n attributes.set(name, readStridedFloat(gltf, binChunk, accessorIdx));\n }\n }\n const posAcc = gltf.accessors[attrs.POSITION];\n const idx =\n primitive.indices === undefined\n ? new Uint32Array(0)\n : new Uint32Array(resolveAccessor(gltf, binChunk, primitive.indices)._data as Uint16Array | Uint32Array | Uint8Array);\n decoded.set(primitive, {\n _attributes: attributes,\n _indices: idx,\n _vertexCount: posAcc.count,\n _indexCount: idx.length,\n });\n }\n }\n return decoded;\n },\n async applyMaterial(mat, ctx) {\n const data = mat._rawMatDef?.[BASISU_MATERIAL_DATA] as BasisuMaterialData | undefined;\n if (!data) {\n return null;\n }\n const [baseColorTexture, ormTexture, normalTexture, emissiveTexture, specularTexture, specularColorTexture] = await Promise.all([\n uploadBasisuTexture(data, ctx, data.baseColorTexture, true),\n uploadOrmTexture(data, ctx),\n uploadBasisuTexture(data, ctx, data.normalTexture, false),\n uploadBasisuTexture(data, ctx, data.emissiveTexture, true),\n uploadBasisuTexture(data, ctx, data.specularTexture, false),\n uploadBasisuTexture(data, ctx, data.specularColorTexture, true),\n ]);\n const out: Partial<PbrMaterialProps> = {\n ...(baseColorTexture ? { baseColorTexture } : undefined),\n ...(ormTexture\n ? {\n ormTexture,\n ...(data.metallicRoughnessTexture ? { metallicFactor: mat._metallicFactor, roughnessFactor: mat._roughnessFactor } : undefined),\n ...(data.occlusionTexture ? { occlusionStrength: 1.0, occlusionTexCoord: data.occlusionTexture.texCoord ?? 0 } : undefined),\n }\n : undefined),\n ...(normalTexture ? { normalTexture, normalTextureScale: data.normalTexture?.scale ?? 1 } : undefined),\n ...(emissiveTexture ? { emissiveTexture } : undefined),\n ...(specularTexture ? { metallicReflectanceTexture: specularTexture, useOnlyMetallicFromMetallicReflectanceTexture: true } : undefined),\n ...(specularColorTexture ? { reflectanceTexture: specularColorTexture } : undefined),\n };\n if (!out.baseColorTexture && !out.ormTexture && !out.normalTexture && !out.emissiveTexture && !out.metallicReflectanceTexture && !out.reflectanceTexture) {\n return null;\n }\n return out;\n },\n};\n\nexport default ext;\n"],"names":["_b","_a"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gltf-feature-gpu-instancing-2e_CFQnl.js","sources":["../src/loader-gltf/gltf-feature-gpu-instancing.ts"],"sourcesContent":["/** glTF EXT_mesh_gpu_instancing extension.\n *\n * Attaches hardware-instanced thin instances to every mesh that belongs to a\n * node carrying `extensions.EXT_mesh_gpu_instancing`. The extension provides\n * per-instance TRANSLATION / ROTATION / SCALE accessors (all optional); each\n * instance matrix is composed as T·R·S in the node's local frame. The node's\n * own TRS is applied through the regular parent-chain world matrix at render\n * time (`finalWorld = mesh.world * instanceWorld` in thin-instance-fragment),\n * so instance matrices must NOT pre-multiply the node transform.\n *\n * Dynamically imported by load-gltf only when the asset declares the\n * extension in `extensionsUsed`, so bundles pay zero bytes otherwise.\n *\n * Spec: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md\n */\n\nimport type { GltfFeature } from \"./gltf-feature.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport { resolveAccessor } from \"./gltf-parser.js\";\nimport { computeAabb } from \"../math/compute-aabb.js\";\nimport { mat4ComposeInto } from \"../math/mat4-compose-into.js\";\nimport { mat4Multiply } from \"../math/mat4-multiply.js\";\nimport type { Mat4 } from \"../math/types.js\";\nimport { setThinInstances } from \"../mesh/thin-instance.js\";\n\n/** Collect every Mesh child (direct children only — matches buildNodeHierarchy). */\nfunction collectMeshesUnderNode(tn: { children?: unknown[] } | undefined): Mesh[] {\n const out: Mesh[] = [];\n for (const c of tn?.children ?? []) {\n if (c && typeof c === \"object\" && \"material\" in (c as object)) {\n out.push(c as Mesh);\n }\n }\n return out;\n}\n\nfunction buildInstanceMatrices(translation: Float32Array | null, rotation: Float32Array | null, scale: Float32Array | null, count: number): Float32Array {\n const matrices = new Float32Array(count * 16);\n for (let i = 0; i < count; i++) {\n const tx = translation ? translation[i * 3]! : 0;\n const ty = translation ? translation[i * 3 + 1]! : 0;\n const tz = translation ? translation[i * 3 + 2]! : 0;\n const qx = rotation ? rotation[i * 4]! : 0;\n const qy = rotation ? rotation[i * 4 + 1]! : 0;\n const qz = rotation ? rotation[i * 4 + 2]! : 0;\n const qw = rotation ? rotation[i * 4 + 3]! : 1;\n const sx = scale ? scale[i * 3]! : 1;\n const sy = scale ? scale[i * 3 + 1]! : 1;\n const sz = scale ? scale[i * 3 + 2]! : 1;\n mat4ComposeInto(matrices, i * 16, tx, ty, tz, qx, qy, qz, qw, sx, sy, sz);\n }\n return matrices;\n}\n\nconst ext: GltfFeature = {\n id: \"EXT_mesh_gpu_instancing\",\n async applyAsset(_meshes, _root, ctx) {\n const { _json: json, _binChunk: binChunk, _nodeMap: nodeMap } = ctx;\n if (!nodeMap) {\n return {};\n }\n const nodes = json.nodes ?? [];\n for (let nodeIdx = 0; nodeIdx < nodes.length; nodeIdx++) {\n const attrs = nodes[nodeIdx]?.extensions?.EXT_mesh_gpu_instancing?.attributes;\n if (!attrs) {\n continue;\n }\n const tn = nodeMap[nodeIdx];\n if (!tn) {\n continue;\n }\n const meshesForNode = collectMeshesUnderNode(tn as unknown as { children?: unknown[] });\n if (meshesForNode.length === 0) {\n continue;\n }\n\n const tAcc = attrs.TRANSLATION !== undefined ? resolveAccessor(json, binChunk, attrs.TRANSLATION) : null;\n const rAcc = attrs.ROTATION !== undefined ? resolveAccessor(json, binChunk, attrs.ROTATION) : null;\n const sAcc = attrs.SCALE !== undefined ? resolveAccessor(json, binChunk, attrs.SCALE) : null;\n\n let count = 0;\n for (const acc of [tAcc, rAcc, sAcc]) {\n if (!acc) {\n continue;\n }\n if (count === 0) {\n count = acc._count;\n } else if (acc._count !== count) {\n throw new Error(`EXT_mesh_gpu_instancing: accessor count mismatch on node ${nodeIdx}`);\n }\n }\n if (count === 0) {\n continue;\n }\n\n const matrices = buildInstanceMatrices(\n tAcc ? (tAcc._data as Float32Array) : null,\n rAcc ? (rAcc._data as Float32Array) : null,\n sAcc ? (sAcc._data as Float32Array) : null,\n count\n );\n const nodeWorld = ctx._worldMatrixCache.get(nodeIdx);\n for (const mesh of meshesForNode) {\n setThinInstances(mesh, matrices, count);\n expandMeshAabbForInstances(mesh, matrices, count, nodeWorld);\n }\n }\n return {};\n },\n};\nexport default ext;\n\n/** Expand a mesh's world-space AABB to enclose all thin instances so that\n * auto-framing cameras see the full instanced grid, not just the base mesh. */\nfunction expandMeshAabbForInstances(mesh: Mesh, matrices: Float32Array, count: number, nodeWorld: Mat4 | undefined): void {\n const positions = mesh._cpuPositions;\n if (!positions || !nodeWorld || count === 0) {\n return;\n }\n // Local AABB of the base mesh (before any per-instance / node transform).\n const [lmin, lmax] = computeAabb(positions);\n if (!isFinite(lmin[0]!)) {\n return;\n }\n // 8 corners of the local AABB, packed as 24 floats for computeAabb.\n const corners = new Float32Array([\n lmin[0]!,\n lmin[1]!,\n lmin[2]!,\n lmax[0]!,\n lmin[1]!,\n lmin[2]!,\n lmin[0]!,\n lmax[1]!,\n lmin[2]!,\n lmax[0]!,\n lmax[1]!,\n lmin[2]!,\n lmin[0]!,\n lmin[1]!,\n lmax[2]!,\n lmax[0]!,\n lmin[1]!,\n lmax[2]!,\n lmin[0]!,\n lmax[1]!,\n lmax[2]!,\n lmax[0]!,\n lmax[1]!,\n lmax[2]!,\n ]);\n let wMinX = Infinity,\n wMinY = Infinity,\n wMinZ = Infinity;\n let wMaxX = -Infinity,\n wMaxY = -Infinity,\n wMaxZ = -Infinity;\n const instWorld = new Float32Array(16) as Mat4;\n for (let i = 0; i < count; i++) {\n for (let k = 0; k < 16; k++) {\n instWorld[k] = matrices[i * 16 + k]!;\n }\n const combined = mat4Multiply(nodeWorld, instWorld);\n const [imin, imax] = computeAabb(corners, combined);\n if (imin[0]! < wMinX) {\n wMinX = imin[0]!;\n }\n if (imin[1]! < wMinY) {\n wMinY = imin[1]!;\n }\n if (imin[2]! < wMinZ) {\n wMinZ = imin[2]!;\n }\n if (imax[0]! > wMaxX) {\n wMaxX = imax[0]!;\n }\n if (imax[1]! > wMaxY) {\n wMaxY = imax[1]!;\n }\n if (imax[2]! > wMaxZ) {\n wMaxZ = imax[2]!;\n }\n }\n mesh.boundMin = [wMinX, wMinY, wMinZ];\n mesh.boundMax = [wMaxX, wMaxY, wMaxZ];\n}\n"],"names":[],"mappings":";AA0BA,SAAS,uBAAuB,IAAkD;AAC9E,QAAM,MAAc,CAAA;AACpB,aAAW,MAAK,yBAAI,aAAY,CAAA,GAAI;AAChC,QAAI,KAAK,OAAO,MAAM,YAAY,cAAe,GAAc;AAC3D,UAAI,KAAK,CAAS;AAAA,IACtB;AAAA,EACJ;AACA,SAAO;AACX;AAEA,SAAS,sBAAsB,aAAkC,UAA+B,OAA4B,OAA6B;AACrJ,QAAM,WAAW,IAAI,aAAa,QAAQ,EAAE;AAC5C,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAM,KAAK,cAAc,YAAY,IAAI,CAAC,IAAK;AAC/C,UAAM,KAAK,cAAc,YAAY,IAAI,IAAI,CAAC,IAAK;AACnD,UAAM,KAAK,cAAc,YAAY,IAAI,IAAI,CAAC,IAAK;AACnD,UAAM,KAAK,WAAW,SAAS,IAAI,CAAC,IAAK;AACzC,UAAM,KAAK,WAAW,SAAS,IAAI,IAAI,CAAC,IAAK;AAC7C,UAAM,KAAK,WAAW,SAAS,IAAI,IAAI,CAAC,IAAK;AAC7C,UAAM,KAAK,WAAW,SAAS,IAAI,IAAI,CAAC,IAAK;AAC7C,UAAM,KAAK,QAAQ,MAAM,IAAI,CAAC,IAAK;AACnC,UAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,CAAC,IAAK;AACvC,UAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,CAAC,IAAK;AACvC,oBAAgB,UAAU,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,EAC5E;AACA,SAAO;AACX;AAEA,MAAM,MAAmB;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM,WAAW,SAAS,OAAO,KAAK;;AAClC,UAAM,EAAE,OAAO,MAAM,WAAW,UAAU,UAAU,YAAY;AAChE,QAAI,CAAC,SAAS;AACV,aAAO,CAAA;AAAA,IACX;AACA,UAAM,QAAQ,KAAK,SAAS,CAAA;AAC5B,aAAS,UAAU,GAAG,UAAU,MAAM,QAAQ,WAAW;AACrD,YAAM,SAAQ,uBAAM,OAAO,MAAb,mBAAgB,eAAhB,mBAA4B,4BAA5B,mBAAqD;AACnE,UAAI,CAAC,OAAO;AACR;AAAA,MACJ;AACA,YAAM,KAAK,QAAQ,OAAO;AAC1B,UAAI,CAAC,IAAI;AACL;AAAA,MACJ;AACA,YAAM,gBAAgB,uBAAuB,EAAyC;AACtF,UAAI,cAAc,WAAW,GAAG;AAC5B;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM,gBAAgB,SAAY,gBAAgB,MAAM,UAAU,MAAM,WAAW,IAAI;AACpG,YAAM,OAAO,MAAM,aAAa,SAAY,gBAAgB,MAAM,UAAU,MAAM,QAAQ,IAAI;AAC9F,YAAM,OAAO,MAAM,UAAU,SAAY,gBAAgB,MAAM,UAAU,MAAM,KAAK,IAAI;AAExF,UAAI,QAAQ;AACZ,iBAAW,OAAO,CAAC,MAAM,MAAM,IAAI,GAAG;AAClC,YAAI,CAAC,KAAK;AACN;AAAA,QACJ;AACA,YAAI,UAAU,GAAG;AACb,kBAAQ,IAAI;AAAA,QAChB,WAAW,IAAI,WAAW,OAAO;AAC7B,gBAAM,IAAI,MAAM,4DAA4D,OAAO,EAAE;AAAA,QACzF;AAAA,MACJ;AACA,UAAI,UAAU,GAAG;AACb;AAAA,MACJ;AAEA,YAAM,WAAW;AAAA,QACb,OAAQ,KAAK,QAAyB;AAAA,QACtC,OAAQ,KAAK,QAAyB;AAAA,QACtC,OAAQ,KAAK,QAAyB;AAAA,QACtC;AAAA,MAAA;AAEJ,YAAM,YAAY,IAAI,kBAAkB,IAAI,OAAO;AACnD,iBAAW,QAAQ,eAAe;AAC9B,yBAAiB,MAAM,UAAU,KAAK;AACtC,mCAA2B,MAAM,UAAU,OAAO,SAAS;AAAA,MAC/D;AAAA,IACJ;AACA,WAAO,CAAA;AAAA,EACX;AACJ;AAKA,SAAS,2BAA2B,MAAY,UAAwB,OAAe,WAAmC;AACtH,QAAM,YAAY,KAAK;AACvB,MAAI,CAAC,aAAa,CAAC,aAAa,UAAU,GAAG;AACzC;AAAA,EACJ;AAEA,QAAM,CAAC,MAAM,IAAI,IAAI,YAAY,SAAS;AAC1C,MAAI,CAAC,SAAS,KAAK,CAAC,CAAE,GAAG;AACrB;AAAA,EACJ;AAEA,QAAM,UAAU,IAAI,aAAa;AAAA,IAC7B,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,EAAA,CACT;AACD,MAAI,QAAQ,UACR,QAAQ,UACR,QAAQ;AACZ,MAAI,QAAQ,WACR,QAAQ,WACR,QAAQ;AACZ,QAAM,YAAY,IAAI,aAAa,EAAE;AACrC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AACzB,gBAAU,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAAA,IACtC;AACA,UAAM,WAAW,aAAa,WAAW,SAAS;AAClD,UAAM,CAAC,MAAM,IAAI,IAAI,YAAY,SAAS,QAAQ;AAClD,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AACA,QAAI,KAAK,CAAC,IAAK,OAAO;AAClB,cAAQ,KAAK,CAAC;AAAA,IAClB;AAAA,EACJ;AACA,OAAK,WAAW,CAAC,OAAO,OAAO,KAAK;AACpC,OAAK,WAAW,CAAC,OAAO,OAAO,KAAK;AACxC;"}
|