@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader-renderable-BMf_vvO0.js","sources":["../src/material/shader/shader-pipeline.ts","../src/material/shader/shader-renderable.ts"],"sourcesContent":["import type { EngineContext } from \"../../engine/engine.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport { targetSignatureKey } from \"../../engine/render-target.js\";\nimport { getSceneBindGroupLayout } from \"../../render/scene-helpers.js\";\nimport { SCENE_UBO_WGSL } from \"../../shader/scene-uniforms.js\";\nimport { computeUboLayout } from \"../../shader/ubo-layout.js\";\nimport type { UboField, UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderSamplerDecl, ShaderUniformDecl } from \"./shader-material.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\n\nexport interface ShaderPipelineBindings {\n readonly group1BGL: GPUBindGroupLayout;\n readonly systemSpec: UboSpec;\n readonly customSpec: UboSpec | null;\n readonly vertexBuffers: readonly GPUVertexBufferLayout[];\n readonly pipelines: Map<string, GPURenderPipeline>;\n}\n\ninterface ShaderMaterialPipelineState extends ShaderMaterial {\n _shaderDevice?: GPUDevice;\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\nconst SHADER_STAGE_ALL = GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT;\n\nexport function getOrCreateShaderPipelineBindings(engine: EngineContext, material: ShaderMaterial): ShaderPipelineBindings {\n const state = material as ShaderMaterialPipelineState;\n if (state._shaderBindings && state._shaderDevice === engine._device) {\n return state._shaderBindings;\n }\n\n state._shaderDevice = engine._device;\n const systemFields = material.uniformDecls.filter((u) => _isShaderSystemUniform(u.name)).map(toUboField);\n const customFields = material.uniformDecls.filter((u) => !_isShaderSystemUniform(u.name)).map(toUboField);\n const systemSpec = computeUboLayout(systemFields.length > 0 ? systemFields : [{ _name: \"_pad\", _type: \"vec4<f32>\" }]);\n const customSpec = customFields.length > 0 ? computeUboLayout(customFields) : null;\n const group1BGL = engine._device.createBindGroupLayout({\n label: \"shader-material-group1\",\n entries: buildBindGroupLayoutEntries(material.samplerDecls, customSpec !== null),\n });\n const bindings: ShaderPipelineBindings = {\n group1BGL,\n systemSpec,\n customSpec,\n vertexBuffers: material.attributes.map(attributeLayout),\n pipelines: new Map(),\n };\n state._shaderBindings = bindings;\n state._shaderCustomSpec = customSpec;\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = -1;\n return bindings;\n}\n\nexport function getOrCreateShaderPipeline(\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey = \"\",\n vertexBuffers: readonly GPUVertexBufferLayout[] = bindings.vertexBuffers,\n instanceAttrs = \"\"\n): GPURenderPipeline {\n // `variantKey`, `vertexBuffers` and `instanceAttrs` default to the\n // non-instanced pipeline — byte-for-byte identical behaviour to before\n // instancing existed. The dynamically-imported thin-instance module is the\n // only caller that passes non-default values, so no instancing logic runs\n // for non-instanced scenes.\n const key = `${targetSignatureKey(sig)}${variantKey}`;\n const cached = bindings.pipelines.get(key);\n if (cached) {\n return cached;\n }\n const device = engine._device;\n const prelude = buildShaderPrelude(material, bindings.systemSpec, bindings.customSpec, instanceAttrs);\n const vertModule = device.createShaderModule({ label: `${material.name ?? \"shader\"}-vertex`, code: `${prelude}\\n${material.vertexSource}` });\n const fragModule = sig._colorFormat ? device.createShaderModule({ label: `${material.name ?? \"shader\"}-fragment`, code: `${prelude}\\n${material.fragmentSource}` }) : null;\n const colorTarget: GPUColorTargetState | null = sig._colorFormat\n ? {\n format: sig._colorFormat,\n ...(material.needAlphaBlending\n ? {\n blend:\n material.blendMode === \"additive\"\n ? ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one\", operation: \"add\" },\n } satisfies GPUBlendState)\n : ({\n color: { srcFactor: \"src-alpha\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n alpha: { srcFactor: \"one\", dstFactor: \"one-minus-src-alpha\", operation: \"add\" },\n } satisfies GPUBlendState),\n }\n : {}),\n }\n : null;\n\n const pipeline = device.createRenderPipeline({\n label: `${material.name ?? \"shader\"}-pipeline`,\n layout: device.createPipelineLayout({ bindGroupLayouts: [getSceneBindGroupLayout(engine), bindings.group1BGL] }),\n vertex: { module: vertModule, entryPoint: \"mainVertex\", buffers: vertexBuffers as GPUVertexBufferLayout[] },\n ...(fragModule && colorTarget ? { fragment: { module: fragModule, entryPoint: \"mainFragment\", targets: [colorTarget] } } : {}),\n ...(sig._depthStencilFormat\n ? {\n depthStencil: {\n format: sig._depthStencilFormat,\n depthCompare: material.depthCompare,\n depthWriteEnabled: material.needAlphaBlending ? false : material.depthWrite,\n },\n }\n : {}),\n multisample: { count: sig._sampleCount },\n primitive: { topology: \"triangle-list\", cullMode: material.backFaceCulling ? \"back\" : \"none\", frontFace: sig._flipY ? \"cw\" : \"ccw\" },\n });\n bindings.pipelines.set(key, pipeline);\n return pipeline;\n}\n\nfunction toUboField(decl: ShaderUniformDecl): UboField {\n return { _name: decl.name, _type: decl.type };\n}\n\nfunction buildBindGroupLayoutEntries(samplers: readonly ShaderSamplerDecl[], hasCustomUbo: boolean): GPUBindGroupLayoutEntry[] {\n const entries: GPUBindGroupLayoutEntry[] = [{ binding: 0, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } }];\n let nextBinding = 1;\n if (hasCustomUbo) {\n entries.push({ binding: nextBinding++, visibility: SHADER_STAGE_ALL, buffer: { type: \"uniform\" } });\n }\n for (const sampler of samplers) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const sampleType = sampler.comparison === true ? \"depth\" : (sampler.sampleType ?? \"float\");\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n texture: {\n sampleType,\n viewDimension: isArray ? \"2d-array\" : \"2d\",\n },\n });\n entries.push({\n binding: nextBinding++,\n visibility: SHADER_STAGE_ALL,\n sampler: { type: sampler.comparison === true ? \"comparison\" : sampleType === \"float\" ? \"filtering\" : \"non-filtering\" },\n });\n }\n return entries;\n}\n\nfunction attributeLayout(name: ShaderAttributeName, shaderLocation: number): GPUVertexBufferLayout {\n switch (name) {\n case \"position\":\n case \"normal\":\n return { arrayStride: 12, attributes: [{ shaderLocation, offset: 0, format: \"float32x3\" }] };\n case \"uv\":\n case \"uv2\":\n return { arrayStride: 8, attributes: [{ shaderLocation, offset: 0, format: \"float32x2\" }] };\n case \"tangent\":\n case \"color\":\n return { arrayStride: 16, attributes: [{ shaderLocation, offset: 0, format: \"float32x4\" }] };\n }\n}\n\nfunction buildShaderPrelude(material: ShaderMaterial, systemSpec: UboSpec, customSpec: UboSpec | null, instanceAttrs = \"\"): string {\n let wgsl = `${SCENE_UBO_WGSL}\nstruct ShaderSystemUniforms {\n${systemSpec._structBody}\n}\n@group(1) @binding(0) var<uniform> shaderSystem: ShaderSystemUniforms;\n`;\n if (customSpec) {\n wgsl += `struct ShaderUniforms {\n${customSpec._structBody}\n}\n@group(1) @binding(1) var<uniform> shaderUniforms: ShaderUniforms;\n`;\n }\n let nextBinding = customSpec ? 2 : 1;\n for (const sampler of material.samplerDecls) {\n const isArray = sampler.viewDimension === \"2d-array\";\n const isDepth = sampler.comparison === true || sampler.sampleType === \"depth\";\n const texType = isDepth ? (isArray ? \"texture_depth_2d_array\" : \"texture_depth_2d\") : isArray ? \"texture_2d_array<f32>\" : \"texture_2d<f32>\";\n const samplerType = sampler.comparison === true ? \"sampler_comparison\" : \"sampler\";\n wgsl += `@group(1) @binding(${nextBinding++}) var ${sampler.name}: ${texType};\n@group(1) @binding(${nextBinding++}) var ${sampler.name}Sampler: ${samplerType};\n`;\n }\n for (const define of material.defines) {\n wgsl += `const ${define.name}: ${typeof define.value === \"boolean\" ? \"bool\" : \"f32\"} = ${formatDefineValue(define.value)};\n`;\n }\n wgsl += `struct VertexInput {\n`;\n for (let i = 0; i < material.attributes.length; i++) {\n const attr = material.attributes[i]!;\n wgsl += `@location(${i}) ${attr}: ${attributeWgslType(attr)},\n`;\n }\n wgsl += instanceAttrs;\n wgsl += `};\n`;\n return wgsl;\n}\n\nfunction formatDefineValue(value: boolean | number): string {\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Number.isInteger(value)) {\n return `${value}.0`;\n }\n return String(value);\n}\n\nfunction attributeWgslType(name: ShaderAttributeName): string {\n switch (name) {\n case \"position\":\n case \"normal\":\n return \"vec3<f32>\";\n case \"uv\":\n case \"uv2\":\n return \"vec2<f32>\";\n case \"tangent\":\n case \"color\":\n return \"vec4<f32>\";\n }\n}\n","import type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { MeshGroupBuildResult, Renderable, DrawUpdateContext } from \"../../render/renderable.js\";\nimport type { Material } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport { createEmptyUniformBuffer } from \"../../resource/gpu-buffers.js\";\nimport { acquireTexture, releaseTexture } from \"../../resource/gpu-pool.js\";\nimport { getEffectiveAspectRatio, getProjectionMatrix, getViewMatrix, getViewProjectionMatrix } from \"../../camera/camera.js\";\nimport type { Camera } from \"../../camera/camera.js\";\nimport { mat4MultiplyInto } from \"../../math/mat4-multiply-into.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { ShaderAttributeName, ShaderMaterial, ShaderUniformType } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport { _isShaderSystemUniform } from \"./shader-material.js\";\nimport { getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings } from \"./shader-pipeline.js\";\n\n/** @internal Exported as a type only (zero runtime bytes) for the dynamically-imported\n * thin-instance builder. */\nexport interface ShaderPacket {\n readonly mesh: Mesh;\n readonly systemUBO: GPUBuffer;\n readonly systemData: Float32Array;\n /** @internal */\n _bindGroup: GPUBindGroup;\n /** @internal */\n _lastResourceVersion: number;\n /** @internal */\n _boundTextures: Texture2D[];\n /** @internal Set when the owning mesh is removed and this packet's GPU resources are\n * destroyed. A combined (multi-mesh) renderable keeps every packet in its\n * closure, so update()/draw() must skip disposed packets to avoid writing to\n * or submitting an already-destroyed systemUBO / vertex buffer. */\n _disposed?: boolean;\n /** @internal Back-reference to the combined renderable's packet array, so disposal can\n * splice this packet out and stop retaining/iterating dead chunk state every\n * frame (set only for merged opaque renderables). */\n _owner?: ShaderPacket[];\n}\n\ninterface ShaderMaterialRenderState extends ShaderMaterial {\n _shaderBindings?: ShaderPipelineBindings;\n _shaderCustomUbo?: GPUBuffer | null;\n _shaderCustomSpec?: UboSpec | null;\n _shaderCustomData?: ArrayBuffer | null;\n _shaderCustomVersion?: number;\n}\n\n/** @internal */\nexport type ShaderRenderPass = GPURenderPassEncoder | GPURenderBundleEncoder;\n\nexport function buildShaderMaterialRenderables(scene: SceneContext, meshes: Mesh[]): MeshGroupBuildResult {\n const renderables: Renderable[] = [];\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable =>\n buildSingleShaderRenderable(s, mesh, (materialOverride ?? mesh.material) as ShaderMaterial, materialOverride != null);\n\n const byMaterial = new Map<ShaderMaterial, Mesh[]>();\n for (const mesh of meshes) {\n const material = mesh.material as ShaderMaterial;\n let list = byMaterial.get(material);\n if (!list) {\n list = [];\n byMaterial.set(material, list);\n }\n list.push(mesh);\n }\n\n for (const [material, matMeshes] of byMaterial) {\n const built = buildMaterialRenderables(scene, material, matMeshes);\n renderables.push(...built);\n }\n\n return { renderables, rebuildSingle };\n}\n\n/** Async group entry point. Non-instanced ShaderMaterial scenes (the common case)\n * take the synchronous fast path and pull in zero instancing code. When at least\n * one mesh uses thin instances, the instancing module is dynamically imported and\n * the renderable helpers it needs are handed to it as positional arguments — NOT\n * module exports — so those helpers keep their mangled names in this chunk (an\n * export would de-mangle them, growing every ShaderMaterial scene's bundle). */\nexport async function buildShaderGroup(scene: SceneContext, meshes: Mesh[]): Promise<MeshGroupBuildResult> {\n if (!meshes.some((m) => !!m.thinInstances)) {\n return buildShaderMaterialRenderables(scene, meshes);\n }\n const mod = await import(\"./shader-thin-instance.js\");\n const cull = meshes.some((m) => !!m.thinInstances?._gpuCullingEnabled) ? await import(\"../../mesh/thin-instance-cull-binding.js\") : undefined;\n return mod.buildShaderRenderablesWithInstancing(\n scene,\n meshes,\n buildShaderMaterialRenderables,\n createPacket,\n updatePacket,\n updateCustomUbo,\n getAttrBuffer,\n getOrCreateShaderPipeline,\n getOrCreateShaderPipelineBindings,\n cull\n );\n}\n\nfunction buildSingleShaderRenderable(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean): Renderable {\n return buildMaterialRenderables(scene, material, [mesh], isOverride)[0]!;\n}\n\nfunction buildMaterialRenderables(scene: SceneContext, material: ShaderMaterial, meshes: readonly Mesh[], isOverride = false): Renderable[] {\n const engine = scene.engine;\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n ensureCustomUbo(engine, material, bindings.customSpec);\n const packets = meshes.map((mesh) => createPacket(scene, material, bindings.systemSpec, mesh));\n const isTransparent = material.needAlphaBlending;\n if (isTransparent) {\n return packets.map((packet) => createTransparentRenderable(scene, material, packet, isOverride));\n }\n return [createOpaqueRenderable(scene, material, packets, isOverride)];\n}\n\nfunction createPacket(scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh): ShaderPacket {\n const engine = scene.engine;\n const systemUBO = createEmptyUniformBuffer(engine, systemSpec._totalBytes, \"shader-system-ubo\");\n const systemData = new Float32Array(systemSpec._totalBytes / 4);\n writeSystemUniforms(systemData, systemSpec, material, mesh, scene.camera, engine.canvas.width || 1, engine.canvas.height || 1);\n engine._device.queue.writeBuffer(systemUBO, 0, systemData);\n const packet: ShaderPacket = {\n mesh,\n systemUBO,\n systemData,\n _bindGroup: createShaderBindGroup(engine, material, systemUBO),\n _lastResourceVersion: material._resourceVersion,\n _boundTextures: collectShaderTextures(material),\n };\n for (const tex of packet._boundTextures) {\n acquireTexture(tex);\n }\n registerMeshTextureDisposer(scene, mesh, packet);\n return packet;\n}\n\nfunction createOpaqueRenderable(scene: SceneContext, material: ShaderMaterial, packets: readonly ShaderPacket[], isOverride: boolean): Renderable {\n // Only merged renderables (>1 mesh) can outlive an individual packet's mesh,\n // so give those packets a back-reference enabling disposal-time compaction.\n if (packets.length > 1) {\n for (const packet of packets) {\n packet._owner = packets as ShaderPacket[];\n }\n }\n const update = (context: DrawUpdateContext): void => {\n updateCustomUbo(scene.engine, material);\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n updatePacket(scene, material, packet, context);\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n let draws = 0;\n for (const packet of packets) {\n if (packet._disposed) {\n continue;\n }\n if (!isOverride && packet.mesh.material !== material) {\n continue;\n }\n drawPacket(pass, engine, material, packet);\n draws++;\n }\n return draws;\n };\n const r: Renderable = {\n order: packets.length === 1 ? (packets[0]!.mesh.renderOrder ?? 100) : Math.min(...packets.map((p) => p.mesh.renderOrder ?? 100)),\n isTransparent: false,\n mesh: packets.length === 1 ? packets[0]!.mesh : undefined,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction createTransparentRenderable(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, isOverride: boolean): Renderable {\n const wm = packet.mesh.worldMatrix as unknown as ArrayLike<number>;\n const sortCenter: [number, number, number] = [wm[12]!, wm[13]!, wm[14]!];\n const update = (context: DrawUpdateContext): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return;\n }\n updateCustomUbo(scene.engine, material);\n updatePacket(scene, material, packet, context);\n const m = packet.mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && packet.mesh.material !== material) {\n return 0;\n }\n drawPacket(pass, engine, material, packet);\n return 1;\n };\n const r: Renderable = {\n order: packet.mesh.renderOrder ?? 200,\n isTransparent: true,\n _transmissive: material.transmissive,\n mesh: packet.mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = getOrCreateShaderPipelineBindings(eng, material);\n return { renderable: r, pipeline: getOrCreateShaderPipeline(eng, sig, material, bindings), update, draw: (pass) => draw(pass, eng) };\n },\n };\n return r;\n}\n\nfunction updatePacket(scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext): void {\n const engine = scene.engine;\n const state = material as ShaderMaterialRenderState;\n writeSystemUniforms(packet.systemData, state._shaderBindings!.systemSpec, material, packet.mesh, context._camera ?? scene.camera, context.targetWidth, context.targetHeight);\n engine._device.queue.writeBuffer(packet.systemUBO, 0, packet.systemData as Float32Array<ArrayBuffer>);\n if (packet._lastResourceVersion !== material._resourceVersion) {\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._bindGroup = createShaderBindGroup(engine, material, packet.systemUBO);\n packet._boundTextures = collectShaderTextures(material);\n for (const tex of packet._boundTextures) {\n acquireTexture(tex);\n }\n packet._lastResourceVersion = material._resourceVersion;\n }\n}\n\nfunction drawPacket(pass: ShaderRenderPass, engine: EngineContext, material: ShaderMaterial, packet: ShaderPacket): void {\n const gpu = packet.mesh._gpu;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(i, getAttrBuffer(engine, gpu, material.attributes[i]!));\n }\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n pass.drawIndexed(gpu.indexCount);\n}\n\nfunction ensureCustomUbo(engine: EngineContext, material: ShaderMaterial, customSpec: UboSpec | null): void {\n const state = material as ShaderMaterialRenderState;\n if (!customSpec) {\n state._shaderCustomUbo = null;\n state._shaderCustomData = null;\n state._shaderCustomVersion = material._uniformVersion;\n return;\n }\n if (state._shaderCustomUbo && state._shaderCustomData) {\n updateCustomUbo(engine, material);\n return;\n }\n state._shaderCustomUbo = createEmptyUniformBuffer(engine, customSpec._totalBytes, \"shader-custom-ubo\");\n state._shaderCustomData = new ArrayBuffer(customSpec._totalBytes);\n state._shaderCustomVersion = -1;\n updateCustomUbo(engine, material);\n}\n\nfunction updateCustomUbo(engine: EngineContext, material: ShaderMaterial): void {\n const state = material as ShaderMaterialRenderState;\n const customSpec = state._shaderCustomSpec;\n const customUbo = state._shaderCustomUbo;\n const customData = state._shaderCustomData;\n if (!customSpec || !customUbo || !customData || state._shaderCustomVersion === material._uniformVersion) {\n return;\n }\n const bytes = new Uint8Array(customData);\n bytes.fill(0);\n for (const [name, slot] of material._uniformValues) {\n if (_isShaderSystemUniform(name)) {\n continue;\n }\n const offset = customSpec._offsets.get(name);\n if (offset !== undefined) {\n writeTypedValue(customData, offset, slot.decl.type, slot.value);\n }\n }\n engine._device.queue.writeBuffer(customUbo, 0, bytes);\n state._shaderCustomVersion = material._uniformVersion;\n}\n\nfunction writeTypedValue(data: ArrayBuffer, offset: number, type: ShaderUniformType, value: Float32Array): void {\n if (type === \"u32\") {\n new Uint32Array(data, offset, 1)[0] = value[0]!;\n return;\n }\n if (type === \"i32\") {\n new Int32Array(data, offset, 1)[0] = value[0]!;\n return;\n }\n new Float32Array(data, offset, value.length).set(value);\n}\n\nfunction createShaderBindGroup(engine: EngineContext, material: ShaderMaterial, systemUBO: GPUBuffer): GPUBindGroup {\n const bindings = getOrCreateShaderPipelineBindings(engine, material);\n const entries: GPUBindGroupEntry[] = [{ binding: 0, resource: { buffer: systemUBO } }];\n let nextBinding = 1;\n if (bindings.customSpec) {\n ensureCustomUbo(engine, material, bindings.customSpec);\n entries.push({ binding: nextBinding++, resource: { buffer: (material as ShaderMaterialRenderState)._shaderCustomUbo! } });\n }\n for (const sampler of material.samplerDecls) {\n const slot = material._textureSlots.get(sampler.name);\n const tex = slot?.current;\n if (!tex) {\n throw new Error(`ShaderMaterial: sampler \"${sampler.name}\" has no Texture2D. Call setShaderTexture() before rendering.`);\n }\n entries.push({ binding: nextBinding++, resource: tex.view }, { binding: nextBinding++, resource: tex.sampler });\n }\n return engine._device.createBindGroup({ label: \"shader-material-bg\", layout: bindings.group1BGL, entries });\n}\n\nfunction collectShaderTextures(material: ShaderMaterial): Texture2D[] {\n const textures: Texture2D[] = [];\n for (const slot of material._textureSlots.values()) {\n if (slot.current) {\n textures.push(slot.current);\n }\n }\n return textures;\n}\n\nfunction registerMeshTextureDisposer(scene: SceneContext, mesh: Mesh, packet: ShaderPacket): void {\n const list = scene._meshDisposables.get(mesh) ?? [];\n list.push(() => {\n packet._disposed = true;\n if (packet._owner) {\n const oi = packet._owner.indexOf(packet);\n if (oi >= 0) {\n packet._owner.splice(oi, 1);\n }\n packet._owner = undefined;\n }\n packet.systemUBO.destroy();\n for (const tex of packet._boundTextures) {\n releaseTexture(tex);\n }\n packet._boundTextures = [];\n });\n scene._meshDisposables.set(mesh, list);\n}\n\nfunction writeSystemUniforms(data: Float32Array, spec: UboSpec, material: ShaderMaterial, mesh: Mesh, camera: Camera | null, targetWidth: number, targetHeight: number): void {\n data.fill(0);\n const world = mesh.worldMatrix as unknown as Float32Array;\n const aspect = camera ? getEffectiveAspectRatio(camera, targetWidth, targetHeight) : 1;\n const view = camera ? (getViewMatrix(camera) as unknown as Float32Array) : null;\n const projection = camera ? (getProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n const viewProjection = camera ? (getViewProjectionMatrix(camera, aspect) as unknown as Float32Array) : null;\n for (const uniform of material.uniformDecls) {\n if (!_isShaderSystemUniform(uniform.name)) {\n continue;\n }\n const offset = spec._offsets.get(uniform.name);\n if (offset === undefined) {\n continue;\n }\n const f = offset / 4;\n switch (uniform.name) {\n case \"world\":\n data.set(world, f);\n break;\n case \"view\":\n if (view) {\n data.set(view, f);\n }\n break;\n case \"projection\":\n if (projection) {\n data.set(projection, f);\n }\n break;\n case \"viewProjection\":\n if (viewProjection) {\n data.set(viewProjection, f);\n }\n break;\n case \"worldView\":\n if (view) {\n mat4MultiplyInto(data, f, view, 0, world, 0);\n }\n break;\n case \"worldViewProjection\":\n if (viewProjection) {\n mat4MultiplyInto(data, f, viewProjection, 0, world, 0);\n }\n break;\n case \"cameraPosition\":\n if (camera) {\n const wm = camera.worldMatrix as unknown as ArrayLike<number>;\n data[f] = wm[12]!;\n data[f + 1] = wm[13]!;\n data[f + 2] = wm[14]!;\n }\n break;\n case \"screenSize\":\n data[f] = targetWidth;\n data[f + 1] = targetHeight;\n break;\n case \"alphaCutoff\":\n data[f] = material._uniformValues.get(\"alphaCutoff\")?.value[0] ?? 0.4;\n break;\n }\n }\n}\n\nlet zeroAttrCache: WeakMap<object, Map<string, GPUBuffer>> | null = null;\n\nfunction getZeroAttrBuffer(engine: EngineContext, gpu: MeshGPU, name: string): GPUBuffer {\n if (!zeroAttrCache) {\n zeroAttrCache = new WeakMap();\n }\n let cache = zeroAttrCache.get(gpu as unknown as object);\n if (!cache) {\n cache = new Map();\n zeroAttrCache.set(gpu as unknown as object, cache);\n }\n const existing = cache.get(name);\n if (existing) {\n return existing;\n }\n const vertexCount = gpu.positionBuffer.size / 12;\n const stride = name === \"uv\" || name === \"uv2\" ? 8 : name === \"normal\" ? 12 : 16;\n const buffer = engine._device.createBuffer({ label: `shader-zero-${name}`, size: vertexCount * stride, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n cache.set(name, buffer);\n return buffer;\n}\n\nfunction getAttrBuffer(engine: EngineContext, gpu: MeshGPU, name: ShaderAttributeName): GPUBuffer {\n switch (name) {\n case \"position\":\n return gpu.positionBuffer;\n case \"normal\":\n return gpu.normalBuffer ?? getZeroAttrBuffer(engine, gpu, \"normal\");\n case \"uv\":\n return gpu.uvBuffer ?? getZeroAttrBuffer(engine, gpu, \"uv\");\n case \"uv2\":\n return gpu.uv2Buffer ?? getZeroAttrBuffer(engine, gpu, \"uv2\");\n case \"tangent\":\n return gpu.tangentBuffer ?? getZeroAttrBuffer(engine, gpu, \"tangent\");\n case \"color\":\n return gpu.colorBuffer ?? getZeroAttrBuffer(engine, gpu, \"color\");\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { syncThinInstanceBuffers } from "./thin-instance-gpu-E8DBd8XL.js";
|
|
2
|
+
function instanceVertexLayouts(baseLocation, hasColor) {
|
|
3
|
+
const layouts = [
|
|
4
|
+
{
|
|
5
|
+
arrayStride: 64,
|
|
6
|
+
stepMode: "instance",
|
|
7
|
+
attributes: [
|
|
8
|
+
{ shaderLocation: baseLocation, offset: 0, format: "float32x4" },
|
|
9
|
+
{ shaderLocation: baseLocation + 1, offset: 16, format: "float32x4" },
|
|
10
|
+
{ shaderLocation: baseLocation + 2, offset: 32, format: "float32x4" },
|
|
11
|
+
{ shaderLocation: baseLocation + 3, offset: 48, format: "float32x4" }
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
];
|
|
15
|
+
if (hasColor) {
|
|
16
|
+
layouts.push({
|
|
17
|
+
arrayStride: 16,
|
|
18
|
+
stepMode: "instance",
|
|
19
|
+
attributes: [{ shaderLocation: baseLocation + 4, offset: 0, format: "float32x4" }]
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return layouts;
|
|
23
|
+
}
|
|
24
|
+
function instancePreludeAttributes(baseLocation, hasColor) {
|
|
25
|
+
let wgsl = `@location(${baseLocation}) world0: vec4<f32>,
|
|
26
|
+
@location(${baseLocation + 1}) world1: vec4<f32>,
|
|
27
|
+
@location(${baseLocation + 2}) world2: vec4<f32>,
|
|
28
|
+
@location(${baseLocation + 3}) world3: vec4<f32>,
|
|
29
|
+
`;
|
|
30
|
+
if (hasColor) {
|
|
31
|
+
wgsl += `@location(${baseLocation + 4}) instanceColor: vec4<f32>,
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
return wgsl;
|
|
35
|
+
}
|
|
36
|
+
function createShaderInstancedRenderable(scene, material, packet, isOverride, h, cull) {
|
|
37
|
+
const isTransparent = material.needAlphaBlending;
|
|
38
|
+
const mesh = packet.mesh;
|
|
39
|
+
const ti = mesh.thinInstances;
|
|
40
|
+
const hasColor = !!ti.colors;
|
|
41
|
+
const baseLocation = material.attributes.length;
|
|
42
|
+
const instanceLayouts = instanceVertexLayouts(baseLocation, hasColor);
|
|
43
|
+
const instanceAttrs = instancePreludeAttributes(baseLocation, hasColor);
|
|
44
|
+
const variantKey = `|ti1c${hasColor ? 1 : 0}`;
|
|
45
|
+
const wm = mesh.worldMatrix;
|
|
46
|
+
const sortCenter = [wm[12], wm[13], wm[14]];
|
|
47
|
+
const update = (context) => {
|
|
48
|
+
if (packet._disposed) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!isOverride && mesh.material !== material) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
h.updateCustomUbo(scene.engine, material);
|
|
55
|
+
h.updatePacket(scene, material, packet, context);
|
|
56
|
+
if (isTransparent) {
|
|
57
|
+
const m = mesh.worldMatrix;
|
|
58
|
+
sortCenter[0] = m[12];
|
|
59
|
+
sortCenter[1] = m[13];
|
|
60
|
+
sortCenter[2] = m[14];
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const draw = (pass, engine, cullBinding) => {
|
|
64
|
+
if (packet._disposed) {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
if (!isOverride && mesh.material !== material) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (ti.count <= 0) {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
const gpu = mesh._gpu;
|
|
74
|
+
let slot = 0;
|
|
75
|
+
for (let i = 0; i < material.attributes.length; i++) {
|
|
76
|
+
pass.setVertexBuffer(slot++, h.getAttrBuffer(engine, gpu, material.attributes[i]));
|
|
77
|
+
}
|
|
78
|
+
slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, cullBinding == null ? void 0 : cullBinding.cullDrawBufs);
|
|
79
|
+
pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);
|
|
80
|
+
pass.setBindGroup(1, packet._bindGroup);
|
|
81
|
+
if (cullBinding) {
|
|
82
|
+
cullBinding.draw(pass, gpu.indexCount, ti.count);
|
|
83
|
+
} else {
|
|
84
|
+
pass.drawIndexed(gpu.indexCount, ti.count);
|
|
85
|
+
}
|
|
86
|
+
return 1;
|
|
87
|
+
};
|
|
88
|
+
const r = {
|
|
89
|
+
order: mesh.renderOrder ?? (isTransparent ? 200 : 100),
|
|
90
|
+
isTransparent,
|
|
91
|
+
mesh,
|
|
92
|
+
_worldCenter: sortCenter,
|
|
93
|
+
bind(eng, sig) {
|
|
94
|
+
const bindings = h.getOrCreateShaderPipelineBindings(eng, material);
|
|
95
|
+
const vertexBuffers = [...bindings.vertexBuffers, ...instanceLayouts];
|
|
96
|
+
const pipeline = h.getOrCreateShaderPipeline(eng, sig, material, bindings, variantKey, vertexBuffers, instanceAttrs);
|
|
97
|
+
const cb = cull == null ? void 0 : cull.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update);
|
|
98
|
+
return {
|
|
99
|
+
renderable: r,
|
|
100
|
+
pipeline,
|
|
101
|
+
update: cb ? cb.update : update,
|
|
102
|
+
draw: (pass) => draw(pass, eng, cb)
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
r._direct = true;
|
|
107
|
+
return r;
|
|
108
|
+
}
|
|
109
|
+
function buildInstancedSingle(scene, mesh, material, isOverride, h, cull) {
|
|
110
|
+
const bindings = h.getOrCreateShaderPipelineBindings(scene.engine, material);
|
|
111
|
+
const packet = h.createPacket(scene, material, bindings.systemSpec, mesh);
|
|
112
|
+
return createShaderInstancedRenderable(scene, material, packet, isOverride, h, cull);
|
|
113
|
+
}
|
|
114
|
+
function buildShaderRenderablesWithInstancing(scene, meshes, buildPlain, createPacket, updatePacket, updateCustomUbo, getAttrBuffer, getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings, cull) {
|
|
115
|
+
const h = { buildPlain, createPacket, updatePacket, updateCustomUbo, getAttrBuffer, getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings };
|
|
116
|
+
const instanced = [];
|
|
117
|
+
const plain = [];
|
|
118
|
+
for (const mesh of meshes) {
|
|
119
|
+
if (mesh.thinInstances) {
|
|
120
|
+
instanced.push(mesh);
|
|
121
|
+
} else {
|
|
122
|
+
plain.push(mesh);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const renderables = [];
|
|
126
|
+
let plainRebuild;
|
|
127
|
+
if (plain.length > 0) {
|
|
128
|
+
const plainResult = buildPlain(scene, plain);
|
|
129
|
+
renderables.push(...plainResult.renderables);
|
|
130
|
+
plainRebuild = plainResult.rebuildSingle;
|
|
131
|
+
}
|
|
132
|
+
for (const mesh of instanced) {
|
|
133
|
+
renderables.push(buildInstancedSingle(scene, mesh, mesh.material, false, h, cull));
|
|
134
|
+
}
|
|
135
|
+
const rebuildSingle = (s, mesh, materialOverride) => {
|
|
136
|
+
const material = materialOverride ?? mesh.material;
|
|
137
|
+
if (mesh.thinInstances) {
|
|
138
|
+
return buildInstancedSingle(s, mesh, material, materialOverride != null, h, cull);
|
|
139
|
+
}
|
|
140
|
+
if (plainRebuild) {
|
|
141
|
+
return plainRebuild(s, mesh, materialOverride);
|
|
142
|
+
}
|
|
143
|
+
return buildPlain(s, [mesh]).rebuildSingle(s, mesh, materialOverride);
|
|
144
|
+
};
|
|
145
|
+
return { renderables, rebuildSingle };
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
buildShaderRenderablesWithInstancing
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=shader-thin-instance-5_WUfi3m.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader-thin-instance-5_WUfi3m.js","sources":["../src/material/shader/shader-thin-instance.ts"],"sourcesContent":["/** ShaderMaterial thin-instance support — dynamically imported ONLY when a\n * ShaderMaterial scene actually uses thin instances, so non-instanced scenes pull\n * in zero extra bytes and the shared `shader-renderable.ts` / `shader-pipeline.ts`\n * chunks stay identical to their non-instanced form.\n *\n * The renderable helpers this module needs (packet create/update, attribute\n * buffers, pipeline builders, the plain-mesh builder) are passed in as positional\n * arguments by `buildShaderGroup`, NOT imported. Importing them would force the\n * shared chunk to export them, which de-mangles their names and grows every\n * ShaderMaterial scene's bundle. As parameters they keep their mangled identity in\n * the shared chunk and are only named here, in this culling/instancing-only chunk.\n *\n * The instance buffer layout MUST match the buffers produced by\n * `thin-instance-gpu.ts` (matrix buffer arrayStride 64, 4x float32x4 at offsets\n * 0/16/32/48; color buffer arrayStride 16, float32x4 at offset 0). */\n\nimport type { EngineContext } from \"../../engine/engine.js\";\nimport type { SceneContext } from \"../../scene/scene.js\";\nimport type { Material } from \"../material.js\";\nimport type { Mesh, MeshGPU } from \"../../mesh/mesh.js\";\nimport type { RenderTargetSignature } from \"../../engine/render-target.js\";\nimport type { UboSpec } from \"../../shader/fragment-types.js\";\nimport type { DrawUpdateContext, MeshGroupBuildResult, Renderable } from \"../../render/renderable.js\";\nimport type { ShaderAttributeName, ShaderMaterial } from \"./shader-material.js\";\nimport type { ShaderPipelineBindings } from \"./shader-pipeline.js\";\nimport type { ShaderPacket, ShaderRenderPass } from \"./shader-renderable.js\";\nimport { syncThinInstanceBuffers } from \"../../mesh/thin-instance-gpu.js\";\n\ntype CullModule = typeof import(\"../../mesh/thin-instance-cull-binding.js\");\n\n/** The shader-renderable helpers handed in positionally by `buildShaderGroup`. */\ninterface ShaderHelpers {\n buildPlain: (scene: SceneContext, meshes: Mesh[]) => MeshGroupBuildResult;\n createPacket: (scene: SceneContext, material: ShaderMaterial, systemSpec: UboSpec, mesh: Mesh) => ShaderPacket;\n updatePacket: (scene: SceneContext, material: ShaderMaterial, packet: ShaderPacket, context: DrawUpdateContext) => void;\n updateCustomUbo: (engine: EngineContext, material: ShaderMaterial) => void;\n getAttrBuffer: (engine: EngineContext, gpu: MeshGPU, name: ShaderAttributeName) => GPUBuffer;\n getOrCreateShaderPipeline: (\n engine: EngineContext,\n sig: RenderTargetSignature,\n material: ShaderMaterial,\n bindings: ShaderPipelineBindings,\n variantKey?: string,\n vertexBuffers?: readonly GPUVertexBufferLayout[],\n instanceAttrs?: string\n ) => GPURenderPipeline;\n getOrCreateShaderPipelineBindings: (engine: EngineContext, material: ShaderMaterial) => ShaderPipelineBindings;\n}\n\n/** Instance vertex buffer layouts. `baseLocation` is the first free shader\n * location after the material's own attributes. */\nfunction instanceVertexLayouts(baseLocation: number, hasColor: boolean): GPUVertexBufferLayout[] {\n const layouts: GPUVertexBufferLayout[] = [\n {\n arrayStride: 64,\n stepMode: \"instance\",\n attributes: [\n { shaderLocation: baseLocation, offset: 0, format: \"float32x4\" },\n { shaderLocation: baseLocation + 1, offset: 16, format: \"float32x4\" },\n { shaderLocation: baseLocation + 2, offset: 32, format: \"float32x4\" },\n { shaderLocation: baseLocation + 3, offset: 48, format: \"float32x4\" },\n ],\n },\n ];\n if (hasColor) {\n layouts.push({\n arrayStride: 16,\n stepMode: \"instance\",\n attributes: [{ shaderLocation: baseLocation + 4, offset: 0, format: \"float32x4\" }],\n });\n }\n return layouts;\n}\n\n/** WGSL lines appended inside `VertexInput` for instanced variants. */\nfunction instancePreludeAttributes(baseLocation: number, hasColor: boolean): string {\n let wgsl = `@location(${baseLocation}) world0: vec4<f32>,\n@location(${baseLocation + 1}) world1: vec4<f32>,\n@location(${baseLocation + 2}) world2: vec4<f32>,\n@location(${baseLocation + 3}) world3: vec4<f32>,\n`;\n if (hasColor) {\n wgsl += `@location(${baseLocation + 4}) instanceColor: vec4<f32>,\n`;\n }\n return wgsl;\n}\n\n/** Build ONE thin-instance renderable for a ShaderMaterial mesh (opaque or\n * transparent). Marked `_direct` so instance buffers are re-bound fresh each\n * frame; this also prepares the renderable for opaque-only GPU culling. */\nfunction createShaderInstancedRenderable(\n scene: SceneContext,\n material: ShaderMaterial,\n packet: ShaderPacket,\n isOverride: boolean,\n h: ShaderHelpers,\n cull?: CullModule\n): Renderable {\n const isTransparent = material.needAlphaBlending;\n const mesh = packet.mesh;\n const ti = mesh.thinInstances!;\n const hasColor = !!ti.colors;\n const baseLocation = material.attributes.length;\n const instanceLayouts = instanceVertexLayouts(baseLocation, hasColor);\n const instanceAttrs = instancePreludeAttributes(baseLocation, hasColor);\n const variantKey = `|ti1c${hasColor ? 1 : 0}`;\n const wm = mesh.worldMatrix as unknown as ArrayLike<number>;\n const sortCenter: [number, number, number] = [wm[12]!, wm[13]!, wm[14]!];\n const update = (context: DrawUpdateContext): void => {\n if (packet._disposed) {\n return;\n }\n if (!isOverride && mesh.material !== material) {\n return;\n }\n h.updateCustomUbo(scene.engine, material);\n h.updatePacket(scene, material, packet, context);\n if (isTransparent) {\n const m = mesh.worldMatrix as unknown as ArrayLike<number>;\n sortCenter[0] = m[12]!;\n sortCenter[1] = m[13]!;\n sortCenter[2] = m[14]!;\n }\n };\n const draw = (pass: ShaderRenderPass, engine: EngineContext, cullBinding?: import(\"../../mesh/thin-instance-cull-binding.js\").TiCullBinding): number => {\n if (packet._disposed) {\n return 0;\n }\n if (!isOverride && mesh.material !== material) {\n return 0;\n }\n if (ti.count <= 0) {\n return 0;\n }\n const gpu = mesh._gpu;\n let slot = 0;\n for (let i = 0; i < material.attributes.length; i++) {\n pass.setVertexBuffer(slot++, h.getAttrBuffer(engine, gpu, material.attributes[i]!));\n }\n slot = syncThinInstanceBuffers(engine, ti, pass, slot, hasColor, cullBinding?.cullDrawBufs);\n pass.setIndexBuffer(gpu.indexBuffer, gpu.indexFormat);\n pass.setBindGroup(1, packet._bindGroup);\n if (cullBinding) {\n cullBinding.draw(pass, gpu.indexCount, ti.count);\n } else {\n pass.drawIndexed(gpu.indexCount, ti.count);\n }\n return 1;\n };\n const r: Renderable = {\n order: mesh.renderOrder ?? (isTransparent ? 200 : 100),\n isTransparent,\n mesh,\n _worldCenter: sortCenter,\n bind(eng, sig) {\n const bindings = h.getOrCreateShaderPipelineBindings(eng, material);\n const vertexBuffers = [...bindings.vertexBuffers, ...instanceLayouts];\n const pipeline = h.getOrCreateShaderPipeline(eng, sig, material, bindings, variantKey, vertexBuffers, instanceAttrs);\n const cb = cull?.tryBind(r, scene, mesh, eng, hasColor, isTransparent, update);\n return {\n renderable: r,\n pipeline,\n update: cb ? cb.update : update,\n draw: (pass) => draw(pass, eng, cb),\n };\n },\n };\n (r as { _direct?: boolean })._direct = true;\n return r;\n}\n\n/** Build one instanced renderable for `mesh` (used by the combined `rebuildSingle`). */\nfunction buildInstancedSingle(scene: SceneContext, mesh: Mesh, material: ShaderMaterial, isOverride: boolean, h: ShaderHelpers, cull?: CullModule): Renderable {\n const bindings = h.getOrCreateShaderPipelineBindings(scene.engine, material);\n const packet = h.createPacket(scene, material, bindings.systemSpec, mesh);\n return createShaderInstancedRenderable(scene, material, packet, isOverride, h, cull);\n}\n\n/** Group entry point used whenever a ShaderMaterial scene has at least one\n * thin-instanced mesh. Plain meshes flow through the passed-in `buildPlain`\n * (`buildShaderMaterialRenderables`); instanced meshes get a dedicated renderable. */\nexport function buildShaderRenderablesWithInstancing(\n scene: SceneContext,\n meshes: Mesh[],\n buildPlain: ShaderHelpers[\"buildPlain\"],\n createPacket: ShaderHelpers[\"createPacket\"],\n updatePacket: ShaderHelpers[\"updatePacket\"],\n updateCustomUbo: ShaderHelpers[\"updateCustomUbo\"],\n getAttrBuffer: ShaderHelpers[\"getAttrBuffer\"],\n getOrCreateShaderPipeline: ShaderHelpers[\"getOrCreateShaderPipeline\"],\n getOrCreateShaderPipelineBindings: ShaderHelpers[\"getOrCreateShaderPipelineBindings\"],\n cull?: CullModule\n): MeshGroupBuildResult {\n const h: ShaderHelpers = { buildPlain, createPacket, updatePacket, updateCustomUbo, getAttrBuffer, getOrCreateShaderPipeline, getOrCreateShaderPipelineBindings };\n const instanced: Mesh[] = [];\n const plain: Mesh[] = [];\n for (const mesh of meshes) {\n if (mesh.thinInstances) {\n instanced.push(mesh);\n } else {\n plain.push(mesh);\n }\n }\n\n const renderables: Renderable[] = [];\n let plainRebuild: MeshGroupBuildResult[\"rebuildSingle\"] | undefined;\n if (plain.length > 0) {\n const plainResult = buildPlain(scene, plain);\n renderables.push(...plainResult.renderables);\n plainRebuild = plainResult.rebuildSingle;\n }\n for (const mesh of instanced) {\n renderables.push(buildInstancedSingle(scene, mesh, mesh.material as ShaderMaterial, false, h, cull));\n }\n\n const rebuildSingle = (s: SceneContext, mesh: Mesh, materialOverride?: Material): Renderable => {\n const material = (materialOverride ?? mesh.material) as ShaderMaterial;\n if (mesh.thinInstances) {\n return buildInstancedSingle(s, mesh, material, materialOverride != null, h, cull);\n }\n if (plainRebuild) {\n return plainRebuild(s, mesh, materialOverride);\n }\n return buildPlain(s, [mesh]).rebuildSingle(s, mesh, materialOverride);\n };\n\n return { renderables, rebuildSingle };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-fragment-core-DHN2G6FI.js","sources":["../src/shader/fragments/shadow-fragment-core.ts"],"sourcesContent":["/**\n * Shadow Fragment Core — Shared WGSL Generation for Shadows\n *\n * Contains the shadow sampling WGSL codegen shared by both Standard and PBR\n * materials. Each material wrapper calls `createShadowFragment` with its own\n * fragment ID (\"std-shadow\" / \"pbr-shadow\"), keeping the generated shader\n * code byte-for-byte identical.\n *\n * Zero module-level side effects — safe for tree-shaking.\n */\n\nimport type { ShaderFragment, BindingDecl, Varying } from \"../fragment-types.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst STAGE_VERTEX = 0x1;\n\n/** Describes one shadow-casting light for the fragment generator. */\nexport interface ShadowLightSlot {\n /** Index of this light in the scene.lights array (0-based). */\n lightIndex: number;\n /** Shadow type for this light. */\n shadowType: \"esm\" | \"pcf\";\n}\n\n/**\n * Create a per-light shadow fragment.\n * Each shadow-casting light gets its own varying, bindings, and sampling code.\n * The shadow factor for each light is stored in shadowFactors[lightIndex].\n */\nexport function createShadowFragment(id: string, shadowLights: ShadowLightSlot[]): ShaderFragment {\n const varyings: Varying[] = [];\n const bindings: BindingDecl[] = [];\n const vertexLines: string[] = [];\n const fragmentLines: string[] = [];\n const helperParts: string[] = [];\n\n for (const slot of shadowLights) {\n const li = slot.lightIndex;\n const suffix = `_${li}`;\n\n varyings.push({ _name: `vPosFromLight${suffix}`, _type: \"vec4<f32>\" }, { _name: `vDepthMetric${suffix}`, _type: \"f32\" });\n\n if (slot.shadowType === \"pcf\") {\n bindings.push(\n { _name: `shadowTex${suffix}`, _type: { _kind: \"texture\", _textureType: \"texture_depth_2d\", _sampleType: \"depth\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT },\n { _name: `shadowComp${suffix}`, _type: { _kind: \"sampler\", _samplerType: \"sampler_comparison\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT }\n );\n } else {\n bindings.push(\n { _name: `shadowTex${suffix}`, _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT },\n { _name: `shadowSamp${suffix}`, _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT }\n );\n }\n bindings.push({ _name: `shadowInfo${suffix}`, _type: { _kind: \"uniform-buffer\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT | STAGE_VERTEX });\n\n vertexLines.push(\n `out.vPosFromLight${suffix} = shadowInfo${suffix}.lightMatrix * worldPos4;`,\n `out.vDepthMetric${suffix} = (out.vPosFromLight${suffix}.z + shadowInfo${suffix}.depthValues.x) / shadowInfo${suffix}.depthValues.y;`\n );\n\n if (slot.shadowType === \"pcf\") {\n fragmentLines.push(\n `shadowFactors[${li}] = computeShadowPCF${suffix}(input.vPosFromLight${suffix}, input.vDepthMetric${suffix}, shadowInfo${suffix}.shadowsInfo.x, shadowInfo${suffix}.shadowsInfo.y, shadowInfo${suffix}.shadowsInfo.z);`\n );\n } else {\n fragmentLines.push(\n `shadowFactors[${li}] = computeShadowESM${suffix}(input.vPosFromLight${suffix}, input.vDepthMetric${suffix}, shadowInfo${suffix}.shadowsInfo.x, shadowInfo${suffix}.shadowsInfo.z, shadowInfo${suffix}.shadowsInfo.w);`\n );\n }\n }\n\n // Helper structs + sampling functions\n for (const slot of shadowLights) {\n const li = slot.lightIndex;\n const suffix = `_${li}`;\n helperParts.push(`struct shadowInfo${suffix}Uniforms { lightMatrix: mat4x4<f32>, depthValues: vec4<f32>, shadowsInfo: vec4<f32> };`);\n\n if (slot.shadowType === \"pcf\") {\n helperParts.push(`\nfn computeShadowPCF${suffix}(posFromLight: vec4<f32>, depthMetric: f32, darkness: f32, mapSz: f32, invMapSz: f32) -> f32 {\nlet clipSpace = posFromLight.xyz / posFromLight.w;\nlet uv = vec2<f32>(0.5 * clipSpace.x + 0.5, 0.5 - 0.5 * clipSpace.y);\nif (depthMetric < 0.0 || depthMetric > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return 1.0; }\nlet depthRef = clamp(clipSpace.z, 0.0, 1.0);\nvar tc = uv * mapSz + 0.5;\nlet st = fract(tc);\nlet base = (floor(tc) - 0.5) * invMapSz;\nlet uvw0 = 4.0 - 3.0 * st;\nlet uvw1 = vec2<f32>(7.0);\nlet uvw2 = 1.0 + 3.0 * st;\nlet u = vec3<f32>((3.0 - 2.0 * st.x) / uvw0.x - 2.0, (3.0 + st.x) / uvw1.x, st.x / uvw2.x + 2.0) * invMapSz;\nlet v = vec3<f32>((3.0 - 2.0 * st.y) / uvw0.y - 2.0, (3.0 + st.y) / uvw1.y, st.y / uvw2.y + 2.0) * invMapSz;\nvar sh = 0.0;\nsh += uvw0.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[0]), depthRef);\nsh += uvw1.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[0]), depthRef);\nsh += uvw2.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[0]), depthRef);\nsh += uvw0.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[1]), depthRef);\nsh += uvw1.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[1]), depthRef);\nsh += uvw2.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[1]), depthRef);\nsh += uvw0.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[2]), depthRef);\nsh += uvw1.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[2]), depthRef);\nsh += uvw2.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[2]), depthRef);\nsh /= 144.0;\nreturn mix(darkness, 1.0, sh);\n}`);\n } else {\n helperParts.push(`\nfn computeFallOff${suffix}(value: f32, clipSpace: vec2<f32>, frustumEdgeFalloff: f32) -> f32 {\nlet mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpace, clipSpace), 0.0, 1.0));\nreturn mix(value, 1.0, mask);\n}\nfn computeShadowESM${suffix}(posFromLight: vec4<f32>, depthMetric: f32, darkness: f32, depthScale: f32, frustumEdgeFalloff: f32) -> f32 {\nlet clipSpace = posFromLight.xyz / posFromLight.w;\nlet uv = vec2<f32>(0.5 * clipSpace.x + 0.5, 0.5 - 0.5 * clipSpace.y);\nif (depthMetric < 0.0 || depthMetric > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return 1.0; }\nlet shadowPixelDepth = clamp(depthMetric, 0.0, 1.0);\nlet shadowMapSample = textureSampleLevel(shadowTex${suffix}, shadowSamp${suffix}, uv, 0.0).x;\nlet esm = 1.0 - clamp(exp(min(87.0, depthScale * shadowPixelDepth)) * shadowMapSample, 0.0, 1.0 - darkness);\nreturn computeFallOff${suffix}(esm, clipSpace.xy, frustumEdgeFalloff);\n}`);\n }\n }\n\n // Vertex helper: UBO struct declarations (needed for lightMatrix access in vertex shader)\n const vertexHelperParts: string[] = [];\n for (const slot of shadowLights) {\n const suffix = `_${slot.lightIndex}`;\n vertexHelperParts.push(`struct shadowInfo${suffix}Uniforms { lightMatrix: mat4x4<f32>, depthValues: vec4<f32>, shadowsInfo: vec4<f32> };`);\n }\n\n return {\n _id: id,\n _varyings: varyings,\n _bindings: bindings,\n _helperFunctions: helperParts.join(\"\\n\"),\n _vertexHelperFunctions: vertexHelperParts.join(\"\\n\"),\n _vertexSlots: {\n VB: vertexLines.join(\"\\n\"),\n },\n _fragmentSlots: {\n AD: fragmentLines.join(\"\\n\"),\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-fragment-core-DHN2G6FI.js","sources":["../src/shader/fragments/shadow-fragment-core.ts"],"sourcesContent":["/**\n * Shadow Fragment Core — Shared WGSL Generation for Shadows\n *\n * Contains the shadow sampling WGSL codegen shared by both Standard and PBR\n * materials. Each material wrapper calls `createShadowFragment` with its own\n * fragment ID (\"std-shadow\" / \"pbr-shadow\"), keeping the generated shader\n * code byte-for-byte identical.\n *\n * Zero module-level side effects — safe for tree-shaking.\n */\n\nimport type { ShaderFragment, BindingDecl, Varying } from \"../fragment-types.js\";\n\nconst STAGE_FRAGMENT = 0x2;\nconst STAGE_VERTEX = 0x1;\n\n/** Describes one shadow-casting light for the fragment generator. */\nexport interface ShadowLightSlot {\n /** Index of this light in the scene.lights array (0-based). */\n lightIndex: number;\n /** Shadow type for this light. */\n shadowType: \"esm\" | \"pcf\" | \"csm\";\n}\n\n/**\n * Create a per-light shadow fragment.\n * Each shadow-casting light gets its own varying, bindings, and sampling code.\n * The shadow factor for each light is stored in shadowFactors[lightIndex].\n */\nexport function createShadowFragment(id: string, shadowLights: ShadowLightSlot[]): ShaderFragment {\n const varyings: Varying[] = [];\n const bindings: BindingDecl[] = [];\n const vertexLines: string[] = [];\n const fragmentLines: string[] = [];\n const helperParts: string[] = [];\n\n for (const slot of shadowLights) {\n const li = slot.lightIndex;\n const suffix = `_${li}`;\n\n varyings.push({ _name: `vPosFromLight${suffix}`, _type: \"vec4<f32>\" }, { _name: `vDepthMetric${suffix}`, _type: \"f32\" });\n\n if (slot.shadowType === \"pcf\") {\n bindings.push(\n { _name: `shadowTex${suffix}`, _type: { _kind: \"texture\", _textureType: \"texture_depth_2d\", _sampleType: \"depth\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT },\n { _name: `shadowComp${suffix}`, _type: { _kind: \"sampler\", _samplerType: \"sampler_comparison\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT }\n );\n } else {\n bindings.push(\n { _name: `shadowTex${suffix}`, _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT },\n { _name: `shadowSamp${suffix}`, _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT }\n );\n }\n bindings.push({ _name: `shadowInfo${suffix}`, _type: { _kind: \"uniform-buffer\" }, _group: \"shadow\", _visibility: STAGE_FRAGMENT | STAGE_VERTEX });\n\n vertexLines.push(\n `out.vPosFromLight${suffix} = shadowInfo${suffix}.lightMatrix * worldPos4;`,\n `out.vDepthMetric${suffix} = (out.vPosFromLight${suffix}.z + shadowInfo${suffix}.depthValues.x) / shadowInfo${suffix}.depthValues.y;`\n );\n\n if (slot.shadowType === \"pcf\") {\n fragmentLines.push(\n `shadowFactors[${li}] = computeShadowPCF${suffix}(input.vPosFromLight${suffix}, input.vDepthMetric${suffix}, shadowInfo${suffix}.shadowsInfo.x, shadowInfo${suffix}.shadowsInfo.y, shadowInfo${suffix}.shadowsInfo.z);`\n );\n } else {\n fragmentLines.push(\n `shadowFactors[${li}] = computeShadowESM${suffix}(input.vPosFromLight${suffix}, input.vDepthMetric${suffix}, shadowInfo${suffix}.shadowsInfo.x, shadowInfo${suffix}.shadowsInfo.z, shadowInfo${suffix}.shadowsInfo.w);`\n );\n }\n }\n\n // Helper structs + sampling functions\n for (const slot of shadowLights) {\n const li = slot.lightIndex;\n const suffix = `_${li}`;\n helperParts.push(`struct shadowInfo${suffix}Uniforms { lightMatrix: mat4x4<f32>, depthValues: vec4<f32>, shadowsInfo: vec4<f32> };`);\n\n if (slot.shadowType === \"pcf\") {\n helperParts.push(`\nfn computeShadowPCF${suffix}(posFromLight: vec4<f32>, depthMetric: f32, darkness: f32, mapSz: f32, invMapSz: f32) -> f32 {\nlet clipSpace = posFromLight.xyz / posFromLight.w;\nlet uv = vec2<f32>(0.5 * clipSpace.x + 0.5, 0.5 - 0.5 * clipSpace.y);\nif (depthMetric < 0.0 || depthMetric > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return 1.0; }\nlet depthRef = clamp(clipSpace.z, 0.0, 1.0);\nvar tc = uv * mapSz + 0.5;\nlet st = fract(tc);\nlet base = (floor(tc) - 0.5) * invMapSz;\nlet uvw0 = 4.0 - 3.0 * st;\nlet uvw1 = vec2<f32>(7.0);\nlet uvw2 = 1.0 + 3.0 * st;\nlet u = vec3<f32>((3.0 - 2.0 * st.x) / uvw0.x - 2.0, (3.0 + st.x) / uvw1.x, st.x / uvw2.x + 2.0) * invMapSz;\nlet v = vec3<f32>((3.0 - 2.0 * st.y) / uvw0.y - 2.0, (3.0 + st.y) / uvw1.y, st.y / uvw2.y + 2.0) * invMapSz;\nvar sh = 0.0;\nsh += uvw0.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[0]), depthRef);\nsh += uvw1.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[0]), depthRef);\nsh += uvw2.x * uvw0.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[0]), depthRef);\nsh += uvw0.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[1]), depthRef);\nsh += uvw1.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[1]), depthRef);\nsh += uvw2.x * uvw1.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[1]), depthRef);\nsh += uvw0.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[0], v[2]), depthRef);\nsh += uvw1.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[1], v[2]), depthRef);\nsh += uvw2.x * uvw2.y * textureSampleCompareLevel(shadowTex${suffix}, shadowComp${suffix}, base + vec2<f32>(u[2], v[2]), depthRef);\nsh /= 144.0;\nreturn mix(darkness, 1.0, sh);\n}`);\n } else {\n helperParts.push(`\nfn computeFallOff${suffix}(value: f32, clipSpace: vec2<f32>, frustumEdgeFalloff: f32) -> f32 {\nlet mask = smoothstep(1.0 - frustumEdgeFalloff, 1.00000012, clamp(dot(clipSpace, clipSpace), 0.0, 1.0));\nreturn mix(value, 1.0, mask);\n}\nfn computeShadowESM${suffix}(posFromLight: vec4<f32>, depthMetric: f32, darkness: f32, depthScale: f32, frustumEdgeFalloff: f32) -> f32 {\nlet clipSpace = posFromLight.xyz / posFromLight.w;\nlet uv = vec2<f32>(0.5 * clipSpace.x + 0.5, 0.5 - 0.5 * clipSpace.y);\nif (depthMetric < 0.0 || depthMetric > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { return 1.0; }\nlet shadowPixelDepth = clamp(depthMetric, 0.0, 1.0);\nlet shadowMapSample = textureSampleLevel(shadowTex${suffix}, shadowSamp${suffix}, uv, 0.0).x;\nlet esm = 1.0 - clamp(exp(min(87.0, depthScale * shadowPixelDepth)) * shadowMapSample, 0.0, 1.0 - darkness);\nreturn computeFallOff${suffix}(esm, clipSpace.xy, frustumEdgeFalloff);\n}`);\n }\n }\n\n // Vertex helper: UBO struct declarations (needed for lightMatrix access in vertex shader)\n const vertexHelperParts: string[] = [];\n for (const slot of shadowLights) {\n const suffix = `_${slot.lightIndex}`;\n vertexHelperParts.push(`struct shadowInfo${suffix}Uniforms { lightMatrix: mat4x4<f32>, depthValues: vec4<f32>, shadowsInfo: vec4<f32> };`);\n }\n\n return {\n _id: id,\n _varyings: varyings,\n _bindings: bindings,\n _helperFunctions: helperParts.join(\"\\n\"),\n _vertexHelperFunctions: vertexHelperParts.join(\"\\n\"),\n _vertexSlots: {\n VB: vertexLines.join(\"\\n\"),\n },\n _fragmentSlots: {\n AD: fragmentLines.join(\"\\n\"),\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ao as PBR_HAS_SHEEN_TEXTURE, ap as PBR_HAS_SHEEN, aq as PBR2_HAS_SHEEN_UV_TX, ar as PBR_HAS_SHEEN_ALBEDO_SCALING } from "./index-B7Qhw0xL.js";
|
|
2
2
|
const STAGE_FRAGMENT = 2;
|
|
3
3
|
const SHEEN_HELPERS = `
|
|
4
4
|
fn normalDistributionFunction_CharlieSheen(NdotH_sh: f32, alphaG_sh: f32) -> f32 {
|
|
@@ -212,4 +212,4 @@ export {
|
|
|
212
212
|
pbrExt,
|
|
213
213
|
writeSheenUBO
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=sheen-fragment-
|
|
215
|
+
//# sourceMappingURL=sheen-fragment-CS6z29Fs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheen-fragment-Dze2f7XJ.js","sources":["../src/material/pbr/fragments/sheen-fragment.ts"],"sourcesContent":["/**\n * Sheen Fragment\n *\n * Adds a soft velvet-like sheen layer (fabric, cloth).\n * Only bundled when a scene uses PbrMaterialProps.sheen.\n *\n * Math follows BJS PBRSheenConfiguration:\n * - Charlie NDF (sheen distribution)\n * - Ashikhmin visibility\n * - IBL: environment sampled at sheen roughness, BRDF LUT blue channel\n * - Energy conservation: albedo scaled by (1 - maxSheenColor * brdf.b)\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SheenProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_SHEEN, PBR_HAS_SHEEN_TEXTURE, PBR_HAS_SHEEN_ALBEDO_SCALING, PBR2_HAS_SHEEN_UV_TX } from \"../pbr-flag-bits.js\";\n\nconst STAGE_FRAGMENT = 0x2;\n\nconst SHEEN_HELPERS = `\nfn normalDistributionFunction_CharlieSheen(NdotH_sh: f32, alphaG_sh: f32) -> f32 {\nlet invR = 1.0 / alphaG_sh;\nlet cos2h = NdotH_sh * NdotH_sh;\nlet sin2h = 1.0 - cos2h;\nreturn (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * 3.141592653589793);\n}\nfn visibility_Ashikhmin(NdotL_sh: f32, NdotV_sh: f32) -> f32 {\nreturn 1.0 / (4.0 * (NdotL_sh + NdotV_sh - NdotL_sh * NdotV_sh));\n}\n`;\n\nconst SHEEN_DIRECT_MOD = (intensityExpr: string): string => `\n{\nlet shIntensity = ${intensityExpr};\nlet shColorScaled = sheenColorFinal * shIntensity;\nlet shRoughness_clamped = max(sheenRoughnessAdjusted, AA_factor_x);\nlet shAlphaG = shRoughness_clamped * shRoughness_clamped + 0.0005;\nlet shD = normalDistributionFunction_CharlieSheen(NdotH, shAlphaG);\nlet shV = visibility_Ashikhmin(NdotL, NdotV);\nsheenDirectTerm = shColorScaled * shD * shV * NdotL * lightColor * lightAtten * material.directIntensity;\n}\n`;\n\nconst SHEEN_IBL_MOD = (intensityExpr: string, albedoScaling: boolean): string => `\n{\nlet shIntensity_ibl = ${intensityExpr};\nlet shColorScaled = sheenColorFinal * shIntensity_ibl;\nlet shRoughness_ibl = sheenRoughnessAdjusted;\nlet shAlphaG_ibl = shRoughness_ibl * shRoughness_ibl + 0.0005 + AA_factor_y;\nvar shSpecLod = log2(cubemapDim * shAlphaG_ibl) * scene.vImageInfos.z;\nlet shEnvRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(shSpecLod, 0.0, maxLod)).rgb * material.environmentIntensity;\nlet shBrdf = textureSampleLevel(brdfLUT, brdfSampler_, vec2<f32>(NdotV, shRoughness_ibl), 0.0);\nlet shEnvReflectance = shColorScaled * shBrdf.b${albedoScaling ? \" * seo * eho\" : \"\"};\nsheenIblTerm = shEnvRadiance * shEnvReflectance;\n${albedoScaling ? \"let shMax = max(shColorScaled.r, max(shColorScaled.g, shColorScaled.b));\\nsheenAlbedoScaling = 1.0 - shMax * shBrdf.b;\" : \"\"}\n}\n`;\n\nconst SHEEN_IBL_COLOR_MOD = (albedoScaling: boolean): string =>\n albedoScaling\n ? `\n{\ncolor = (finalIrradiance\n + finalRadianceScaled\n + finalSpecularScaled\n + directDiffuse) * sheenAlbedoScaling\n + sheenDirectTerm\n + sheenIblTerm\n + emissive;\n}\n`\n : `\n{\ncolor = finalIrradiance\n + finalRadianceScaled\n + finalSpecularScaled\n + directDiffuse\n + sheenDirectTerm\n + sheenIblTerm\n + emissive;\n}\n`;\n\nconst SHEEN_NON_IBL_MOD = `\n{\ncolor = color + sheenDirectTerm;\n}\n`;\n\n/**\n * Create a sheen fragment.\n * @param hasSheenTexture - Whether the material has a sheen texture.\n * @param hasIbl - Whether IBL is active for this pipeline.\n * @param hasAlbedoScaling - When true, uses BJS-spec sheen math (no F0 attenuation,\n * proper base-layer albedo scaling, treats sheen texture as linear — upload\n * as sRGB so the sampler does the conversion). When false (legacy), applies\n * pow(rgb, 2.2) to the texture and uses (1-F0) as the sheen intensity scalar.\n */\nexport function createSheenFragment(hasSheenTexture: boolean, hasIbl: boolean = false, hasAlbedoScaling: boolean = false, hasSheenUvTx: boolean = false): ShaderFragment {\n let scopeVars = `var sheenDirectTerm = vec3<f32>(0.0);\nvar sheenIblTerm = vec3<f32>(0.0);\nvar sheenAlbedoScaling = 1.0;\nvar sheenColorFinal = material.sheenParams.rgb;\nvar sheenRoughnessAdjusted = material.sheenParams2.x;`;\n if (hasSheenTexture) {\n const gammaStmt = hasAlbedoScaling ? \"sheenMapData.rgb\" : \"pow(sheenMapData.rgb, vec3<f32>(2.2))\";\n const sheenUvDecl = hasSheenUvTx\n ? \"let sheenUV = vec2<f32>(dot(material.sheenUVm.xy, input.uv), dot(material.sheenUVm.zw, input.uv)) + material.sheenUVt.xy;\"\n : \"let sheenUV = input.uv;\";\n scopeVars += `\n{\n${sheenUvDecl}\nlet sheenMapData = textureSample(sheenTexture_, sheenSampler_, sheenUV);\nsheenColorFinal *= ${gammaStmt};\nsheenRoughnessAdjusted *= sheenMapData.a;\n}`;\n }\n\n const intensityExpr = hasAlbedoScaling ? \"material.sheenParams.a\" : \"material.sheenParams.a * (1.0 - dielectricF0)\";\n const slots: Partial<Record<string, string>> = {\n SV: scopeVars,\n AD: SHEEN_DIRECT_MOD(intensityExpr),\n };\n // AI and NI are mutually exclusive — only one path runs\n if (hasIbl) {\n slots.AI = SHEEN_IBL_MOD(intensityExpr, hasAlbedoScaling) + SHEEN_IBL_COLOR_MOD(hasAlbedoScaling);\n } else {\n slots.NI = SHEEN_NON_IBL_MOD;\n }\n\n const bindings: BindingDecl[] = [];\n if (hasSheenTexture) {\n bindings.push(\n { _name: \"sheenTexture_\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"sheenSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const uboFields: UboField[] = [\n { _name: \"sheenParams\", _type: \"vec4<f32>\" },\n { _name: \"sheenParams2\", _type: \"vec4<f32>\" },\n ];\n if (hasSheenUvTx) {\n uboFields.push({ _name: \"sheenUVm\", _type: \"vec4<f32>\" }, { _name: \"sheenUVt\", _type: \"vec4<f32>\" });\n }\n\n return {\n _id: \"sheen\",\n _dependencies: hasIbl ? [\"ibl\"] : undefined,\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _helperFunctions: SHEEN_HELPERS,\n\n _fragmentSlots: slots,\n };\n}\n\n/** Write the sheen material-UBO slice (sheenParams, sheenParams2, optional UV transform). */\nexport function writeSheenUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const sh = material.sheen as SheenProps | undefined;\n if (!sh?.isEnabled || !offsets.has(\"sheenParams\")) {\n return;\n }\n const off = offsets.get(\"sheenParams\")! / 4;\n const color = sh.color ?? [1, 1, 1];\n data[off] = color[0]!;\n data[off + 1] = color[1]!;\n data[off + 2] = color[2]!;\n data[off + 3] = sh.intensity ?? 1.0;\n data[off + 4] = sh.roughness ?? 0.0;\n data[off + 5] = sh.texture ? 1.0 : 0.0;\n\n // Optional per-texture UV transform (KHR_texture_transform on sheenColorTexture).\n const mOff = offsets.get(\"sheenUVm\");\n const tOff = offsets.get(\"sheenUVt\");\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const tex = sh.texture;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const ox = tex?.uOffset ?? 0;\n const oy = tex?.vOffset ?? 0;\n const mi = mOff / 4;\n const ti = tOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = -s * sy;\n data[mi + 2] = s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = ox;\n data[ti + 1] = oy;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nexport const pbrExt: PbrExt = {\n id: \"sheen\",\n phase: \"base-tex\",\n detect(mat) {\n const sh = (mat as PbrMaterialProps).sheen as SheenProps | undefined;\n if (!sh?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f = PBR_HAS_SHEEN;\n let f2 = 0;\n if (sh.texture) {\n f |= PBR_HAS_SHEEN_TEXTURE;\n if ((sh.texture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_SHEEN_UV_TX;\n }\n }\n if (sh.albedoScaling) {\n f |= PBR_HAS_SHEEN_ALBEDO_SCALING;\n }\n return { f, f2 };\n },\n frag(ctx) {\n if (!(ctx._features & PBR_HAS_SHEEN)) {\n return null;\n }\n return createSheenFragment(\n (ctx._features & PBR_HAS_SHEEN_TEXTURE) !== 0,\n ctx._hasIbl,\n (ctx._features & PBR_HAS_SHEEN_ALBEDO_SCALING) !== 0,\n (ctx._features2 & PBR2_HAS_SHEEN_UV_TX) !== 0\n );\n },\n writeUbo: writeSheenUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n if ((ctx._features & PBR_HAS_SHEEN_TEXTURE) === 0) {\n return b;\n }\n const sh = (ctx._material as PbrMaterialProps).sheen as SheenProps | undefined;\n if (sh?.texture) {\n entries.push({ binding: b++, resource: sh.texture.view });\n entries.push({ binding: b++, resource: sh.texture.sampler });\n }\n return b;\n },\n textures(mat, out) {\n const sh = (mat as PbrMaterialProps).sheen;\n if (sh?.texture) {\n out.push(sh.texture);\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sheen-fragment-CS6z29Fs.js","sources":["../src/material/pbr/fragments/sheen-fragment.ts"],"sourcesContent":["/**\n * Sheen Fragment\n *\n * Adds a soft velvet-like sheen layer (fabric, cloth).\n * Only bundled when a scene uses PbrMaterialProps.sheen.\n *\n * Math follows BJS PBRSheenConfiguration:\n * - Charlie NDF (sheen distribution)\n * - Ashikhmin visibility\n * - IBL: environment sampled at sheen roughness, BRDF LUT blue channel\n * - Energy conservation: albedo scaled by (1 - maxSheenColor * brdf.b)\n */\n\nimport type { ShaderFragment, BindingDecl, UboField } from \"../../../shader/fragment-types.js\";\nimport type { PbrMaterialProps, SheenProps } from \"../pbr-material.js\";\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { PBR_HAS_SHEEN, PBR_HAS_SHEEN_TEXTURE, PBR_HAS_SHEEN_ALBEDO_SCALING, PBR2_HAS_SHEEN_UV_TX } from \"../pbr-flag-bits.js\";\n\nconst STAGE_FRAGMENT = 0x2;\n\nconst SHEEN_HELPERS = `\nfn normalDistributionFunction_CharlieSheen(NdotH_sh: f32, alphaG_sh: f32) -> f32 {\nlet invR = 1.0 / alphaG_sh;\nlet cos2h = NdotH_sh * NdotH_sh;\nlet sin2h = 1.0 - cos2h;\nreturn (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * 3.141592653589793);\n}\nfn visibility_Ashikhmin(NdotL_sh: f32, NdotV_sh: f32) -> f32 {\nreturn 1.0 / (4.0 * (NdotL_sh + NdotV_sh - NdotL_sh * NdotV_sh));\n}\n`;\n\nconst SHEEN_DIRECT_MOD = (intensityExpr: string): string => `\n{\nlet shIntensity = ${intensityExpr};\nlet shColorScaled = sheenColorFinal * shIntensity;\nlet shRoughness_clamped = max(sheenRoughnessAdjusted, AA_factor_x);\nlet shAlphaG = shRoughness_clamped * shRoughness_clamped + 0.0005;\nlet shD = normalDistributionFunction_CharlieSheen(NdotH, shAlphaG);\nlet shV = visibility_Ashikhmin(NdotL, NdotV);\nsheenDirectTerm = shColorScaled * shD * shV * NdotL * lightColor * lightAtten * material.directIntensity;\n}\n`;\n\nconst SHEEN_IBL_MOD = (intensityExpr: string, albedoScaling: boolean): string => `\n{\nlet shIntensity_ibl = ${intensityExpr};\nlet shColorScaled = sheenColorFinal * shIntensity_ibl;\nlet shRoughness_ibl = sheenRoughnessAdjusted;\nlet shAlphaG_ibl = shRoughness_ibl * shRoughness_ibl + 0.0005 + AA_factor_y;\nvar shSpecLod = log2(cubemapDim * shAlphaG_ibl) * scene.vImageInfos.z;\nlet shEnvRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(shSpecLod, 0.0, maxLod)).rgb * material.environmentIntensity;\nlet shBrdf = textureSampleLevel(brdfLUT, brdfSampler_, vec2<f32>(NdotV, shRoughness_ibl), 0.0);\nlet shEnvReflectance = shColorScaled * shBrdf.b${albedoScaling ? \" * seo * eho\" : \"\"};\nsheenIblTerm = shEnvRadiance * shEnvReflectance;\n${albedoScaling ? \"let shMax = max(shColorScaled.r, max(shColorScaled.g, shColorScaled.b));\\nsheenAlbedoScaling = 1.0 - shMax * shBrdf.b;\" : \"\"}\n}\n`;\n\nconst SHEEN_IBL_COLOR_MOD = (albedoScaling: boolean): string =>\n albedoScaling\n ? `\n{\ncolor = (finalIrradiance\n + finalRadianceScaled\n + finalSpecularScaled\n + directDiffuse) * sheenAlbedoScaling\n + sheenDirectTerm\n + sheenIblTerm\n + emissive;\n}\n`\n : `\n{\ncolor = finalIrradiance\n + finalRadianceScaled\n + finalSpecularScaled\n + directDiffuse\n + sheenDirectTerm\n + sheenIblTerm\n + emissive;\n}\n`;\n\nconst SHEEN_NON_IBL_MOD = `\n{\ncolor = color + sheenDirectTerm;\n}\n`;\n\n/**\n * Create a sheen fragment.\n * @param hasSheenTexture - Whether the material has a sheen texture.\n * @param hasIbl - Whether IBL is active for this pipeline.\n * @param hasAlbedoScaling - When true, uses BJS-spec sheen math (no F0 attenuation,\n * proper base-layer albedo scaling, treats sheen texture as linear — upload\n * as sRGB so the sampler does the conversion). When false (legacy), applies\n * pow(rgb, 2.2) to the texture and uses (1-F0) as the sheen intensity scalar.\n */\nexport function createSheenFragment(hasSheenTexture: boolean, hasIbl: boolean = false, hasAlbedoScaling: boolean = false, hasSheenUvTx: boolean = false): ShaderFragment {\n let scopeVars = `var sheenDirectTerm = vec3<f32>(0.0);\nvar sheenIblTerm = vec3<f32>(0.0);\nvar sheenAlbedoScaling = 1.0;\nvar sheenColorFinal = material.sheenParams.rgb;\nvar sheenRoughnessAdjusted = material.sheenParams2.x;`;\n if (hasSheenTexture) {\n const gammaStmt = hasAlbedoScaling ? \"sheenMapData.rgb\" : \"pow(sheenMapData.rgb, vec3<f32>(2.2))\";\n const sheenUvDecl = hasSheenUvTx\n ? \"let sheenUV = vec2<f32>(dot(material.sheenUVm.xy, input.uv), dot(material.sheenUVm.zw, input.uv)) + material.sheenUVt.xy;\"\n : \"let sheenUV = input.uv;\";\n scopeVars += `\n{\n${sheenUvDecl}\nlet sheenMapData = textureSample(sheenTexture_, sheenSampler_, sheenUV);\nsheenColorFinal *= ${gammaStmt};\nsheenRoughnessAdjusted *= sheenMapData.a;\n}`;\n }\n\n const intensityExpr = hasAlbedoScaling ? \"material.sheenParams.a\" : \"material.sheenParams.a * (1.0 - dielectricF0)\";\n const slots: Partial<Record<string, string>> = {\n SV: scopeVars,\n AD: SHEEN_DIRECT_MOD(intensityExpr),\n };\n // AI and NI are mutually exclusive — only one path runs\n if (hasIbl) {\n slots.AI = SHEEN_IBL_MOD(intensityExpr, hasAlbedoScaling) + SHEEN_IBL_COLOR_MOD(hasAlbedoScaling);\n } else {\n slots.NI = SHEEN_NON_IBL_MOD;\n }\n\n const bindings: BindingDecl[] = [];\n if (hasSheenTexture) {\n bindings.push(\n { _name: \"sheenTexture_\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" }, _visibility: STAGE_FRAGMENT },\n { _name: \"sheenSampler_\", _type: { _kind: \"sampler\", _samplerType: \"sampler\" }, _visibility: STAGE_FRAGMENT }\n );\n }\n\n const uboFields: UboField[] = [\n { _name: \"sheenParams\", _type: \"vec4<f32>\" },\n { _name: \"sheenParams2\", _type: \"vec4<f32>\" },\n ];\n if (hasSheenUvTx) {\n uboFields.push({ _name: \"sheenUVm\", _type: \"vec4<f32>\" }, { _name: \"sheenUVt\", _type: \"vec4<f32>\" });\n }\n\n return {\n _id: \"sheen\",\n _dependencies: hasIbl ? [\"ibl\"] : undefined,\n\n _uboFields: uboFields,\n\n _bindings: bindings,\n\n _helperFunctions: SHEEN_HELPERS,\n\n _fragmentSlots: slots,\n };\n}\n\n/** Write the sheen material-UBO slice (sheenParams, sheenParams2, optional UV transform). */\nexport function writeSheenUBO(data: Float32Array, material: PbrMaterialProps, offsets: ReadonlyMap<string, number>): void {\n const sh = material.sheen as SheenProps | undefined;\n if (!sh?.isEnabled || !offsets.has(\"sheenParams\")) {\n return;\n }\n const off = offsets.get(\"sheenParams\")! / 4;\n const color = sh.color ?? [1, 1, 1];\n data[off] = color[0]!;\n data[off + 1] = color[1]!;\n data[off + 2] = color[2]!;\n data[off + 3] = sh.intensity ?? 1.0;\n data[off + 4] = sh.roughness ?? 0.0;\n data[off + 5] = sh.texture ? 1.0 : 0.0;\n\n // Optional per-texture UV transform (KHR_texture_transform on sheenColorTexture).\n const mOff = offsets.get(\"sheenUVm\");\n const tOff = offsets.get(\"sheenUVt\");\n if (mOff === undefined || tOff === undefined) {\n return;\n }\n const tex = sh.texture;\n const sx = tex?.uScale ?? 1;\n const sy = tex?.vScale ?? 1;\n const ang = tex?.uAng ?? 0;\n const ox = tex?.uOffset ?? 0;\n const oy = tex?.vOffset ?? 0;\n const mi = mOff / 4;\n const ti = tOff / 4;\n if (ang === 0) {\n data[mi] = sx;\n data[mi + 1] = 0;\n data[mi + 2] = 0;\n data[mi + 3] = sy;\n } else {\n const c = Math.cos(ang);\n const s = Math.sin(ang);\n data[mi] = c * sx;\n data[mi + 1] = -s * sy;\n data[mi + 2] = s * sx;\n data[mi + 3] = c * sy;\n }\n data[ti] = ox;\n data[ti + 1] = oy;\n data[ti + 2] = 0;\n data[ti + 3] = 0;\n}\n\nexport const pbrExt: PbrExt = {\n id: \"sheen\",\n phase: \"base-tex\",\n detect(mat) {\n const sh = (mat as PbrMaterialProps).sheen as SheenProps | undefined;\n if (!sh?.isEnabled) {\n return { f: 0, f2: 0 };\n }\n let f = PBR_HAS_SHEEN;\n let f2 = 0;\n if (sh.texture) {\n f |= PBR_HAS_SHEEN_TEXTURE;\n if ((sh.texture as { _hasTx?: boolean })._hasTx) {\n f2 |= PBR2_HAS_SHEEN_UV_TX;\n }\n }\n if (sh.albedoScaling) {\n f |= PBR_HAS_SHEEN_ALBEDO_SCALING;\n }\n return { f, f2 };\n },\n frag(ctx) {\n if (!(ctx._features & PBR_HAS_SHEEN)) {\n return null;\n }\n return createSheenFragment(\n (ctx._features & PBR_HAS_SHEEN_TEXTURE) !== 0,\n ctx._hasIbl,\n (ctx._features & PBR_HAS_SHEEN_ALBEDO_SCALING) !== 0,\n (ctx._features2 & PBR2_HAS_SHEEN_UV_TX) !== 0\n );\n },\n writeUbo: writeSheenUBO as PbrExt[\"writeUbo\"],\n bind(ctx, entries, b) {\n if ((ctx._features & PBR_HAS_SHEEN_TEXTURE) === 0) {\n return b;\n }\n const sh = (ctx._material as PbrMaterialProps).sheen as SheenProps | undefined;\n if (sh?.texture) {\n entries.push({ binding: b++, resource: sh.texture.view });\n entries.push({ binding: b++, resource: sh.texture.sampler });\n }\n return b;\n },\n textures(mat, out) {\n const sh = (mat as PbrMaterialProps).sheen;\n if (sh?.texture) {\n out.push(sh.texture);\n }\n },\n};\n"],"names":[],"mappings":"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"}
|
package/{singlelight-directional-wgsl-CmUDZxwz.js → singlelight-directional-wgsl-4MIgZMeC.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MAX_LIGHTS } from "./index-
|
|
1
|
+
import { M as MAX_LIGHTS } from "./index-B7Qhw0xL.js";
|
|
2
2
|
const SINGLE_LIGHT_STRUCTS = `
|
|
3
3
|
struct LightEntry {
|
|
4
4
|
vLightData: vec4<f32>,
|
|
@@ -36,4 +36,4 @@ export {
|
|
|
36
36
|
SINGLE_LIGHT_STRUCTS,
|
|
37
37
|
getSingleLightBlock
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=singlelight-directional-wgsl-
|
|
39
|
+
//# sourceMappingURL=singlelight-directional-wgsl-4MIgZMeC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singlelight-directional-wgsl-
|
|
1
|
+
{"version":3,"file":"singlelight-directional-wgsl-4MIgZMeC.js","sources":["../src/material/pbr/fragments/singlelight-directional-wgsl.ts"],"sourcesContent":["/** Single directional-light WGSL helpers for the PBR template. */\n\nimport { MAX_LIGHTS } from \"../../../light/types.js\";\n\nexport const SINGLE_LIGHT_STRUCTS = `\nstruct LightEntry {\nvLightData: vec4<f32>,\nvLightDiffuse: vec4<f32>,\nvLightSpecular: vec4<f32>,\nvLightDirection: vec4<f32>,\n};\nstruct lightsUniforms {\ncount: u32, _p0: u32, _p1: u32, _p2: u32,\n lights: array<LightEntry, ${MAX_LIGHTS}>,\n};\n`;\n\nfunction specularBlock(): string {\n return `let H = normalize(V + L);\nlet NdotH = clamp(dot(N, H), 0.0000001, 1.0);\nlet VdotH = saturate(dot(V, H));\nlet directRoughness = max(roughness, AA_factor_x);\nlet directAlphaG = directRoughness * directRoughness + 0.0005;\nlet D = distributionGGX(NdotH, directAlphaG);\nlet G = geometrySmithGGX(NdotL, NdotV, directAlphaG);\nlet coloredFresnel = fresnelSchlick(VdotH, colorF0, colorF90);\nvar directSpecular = coloredFresnel * D * G * NdotL * lightColor * lightAtten * material.directIntensity;`;\n}\n\nexport function getSingleLightBlock(): string {\n return `let entry = lights.lights[mli(0u)];\nlet L = normalize(-entry.vLightData.xyz);\nlet NdotL = max(dot(N, L), 0.0);\nlet lightAtten = 1.0;\nlet lightColor = entry.vLightDiffuse.rgb;\nvar directDiffuse = surfaceAlbedo * (1.0 / PI) * NdotL * lightColor * material.directIntensity;\n${specularBlock()}\n/*AD*/`;\n}\n"],"names":[],"mappings":";AAIO,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCASJ,UAAU;AAAA;AAAA;AAI1C,SAAS,gBAAwB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASX;AAEO,SAAS,sBAA8B;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,eAAe;AAAA;AAEjB;"}
|
package/{singlelight-hemispheric-wgsl-t-83IP_s.js → singlelight-hemispheric-wgsl-CK-GUYWe.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MAX_LIGHTS } from "./index-
|
|
1
|
+
import { M as MAX_LIGHTS } from "./index-B7Qhw0xL.js";
|
|
2
2
|
const SINGLE_LIGHT_STRUCTS = `
|
|
3
3
|
struct LightEntry {
|
|
4
4
|
vLightData: vec4<f32>,
|
|
@@ -37,4 +37,4 @@ export {
|
|
|
37
37
|
SINGLE_LIGHT_STRUCTS,
|
|
38
38
|
getSingleLightBlock
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=singlelight-hemispheric-wgsl-
|
|
40
|
+
//# sourceMappingURL=singlelight-hemispheric-wgsl-CK-GUYWe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singlelight-hemispheric-wgsl-
|
|
1
|
+
{"version":3,"file":"singlelight-hemispheric-wgsl-CK-GUYWe.js","sources":["../src/material/pbr/fragments/singlelight-hemispheric-wgsl.ts"],"sourcesContent":["/** Single hemispheric-light WGSL helpers for the PBR template. */\n\nimport { MAX_LIGHTS } from \"../../../light/types.js\";\n\nexport const SINGLE_LIGHT_STRUCTS = `\nstruct LightEntry {\nvLightData: vec4<f32>,\nvLightDiffuse: vec4<f32>,\nvLightSpecular: vec4<f32>,\nvLightDirection: vec4<f32>,\n};\nstruct lightsUniforms {\ncount: u32, _p0: u32, _p1: u32, _p2: u32,\n lights: array<LightEntry, ${MAX_LIGHTS}>,\n};\n`;\n\nfunction specularBlock(): string {\n return `let H = normalize(V + L);\nlet NdotH = clamp(dot(N, H), 0.0000001, 1.0);\nlet VdotH = saturate(dot(V, H));\nlet directRoughness = max(roughness, AA_factor_x);\nlet directAlphaG = directRoughness * directRoughness + 0.0005;\nlet D = distributionGGX(NdotH, directAlphaG);\nlet G = geometrySmithGGX(NdotL, NdotV, directAlphaG);\nlet coloredFresnel = fresnelSchlick(VdotH, colorF0, colorF90);\nvar directSpecular = coloredFresnel * D * G * NdotL * lightColor * lightAtten * material.directIntensity;`;\n}\n\nexport function getSingleLightBlock(): string {\n return `let entry = lights.lights[mli(0u)];\nlet L = normalize(entry.vLightData.xyz);\nlet NdotL = dot(N, L) * 0.5 + 0.5;\nlet lightAtten = 1.0;\nlet lightColor = entry.vLightDiffuse.rgb;\nlet hemiDiffuse = mix(entry.vLightDirection.xyz, lightColor, NdotL);\nvar directDiffuse = hemiDiffuse * surfaceAlbedo * material.directIntensity;\n${specularBlock()}\n/*AD*/`;\n}\n"],"names":[],"mappings":";AAIO,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCASJ,UAAU;AAAA;AAAA;AAI1C,SAAS,gBAAwB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASX;AAEO,SAAS,sBAA8B;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOT,eAAe;AAAA;AAEjB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MAX_LIGHTS } from "./index-
|
|
1
|
+
import { M as MAX_LIGHTS } from "./index-B7Qhw0xL.js";
|
|
2
2
|
const SINGLE_LIGHT_STRUCTS = `
|
|
3
3
|
struct LightEntry {
|
|
4
4
|
vLightData: vec4<f32>,
|
|
@@ -42,4 +42,4 @@ export {
|
|
|
42
42
|
SINGLE_LIGHT_STRUCTS,
|
|
43
43
|
getSingleLightBlock
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=singlelight-point-wgsl-
|
|
45
|
+
//# sourceMappingURL=singlelight-point-wgsl-CYtzqCbP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singlelight-point-wgsl-
|
|
1
|
+
{"version":3,"file":"singlelight-point-wgsl-CYtzqCbP.js","sources":["../src/material/pbr/fragments/singlelight-point-wgsl.ts"],"sourcesContent":["/** Single point-light WGSL helpers for the PBR template. */\n\nimport { MAX_LIGHTS } from \"../../../light/types.js\";\n\nexport const SINGLE_LIGHT_STRUCTS = `\nstruct LightEntry {\nvLightData: vec4<f32>,\nvLightDiffuse: vec4<f32>,\nvLightSpecular: vec4<f32>,\nvLightDirection: vec4<f32>,\n};\nstruct lightsUniforms {\ncount: u32, _p0: u32, _p1: u32, _p2: u32,\n lights: array<LightEntry, ${MAX_LIGHTS}>,\n};\n`;\n\nfunction specularBlock(): string {\n return `let H = normalize(V + L);\nlet NdotH = clamp(dot(N, H), 0.0000001, 1.0);\nlet VdotH = saturate(dot(V, H));\nlet directRoughness = max(roughness, AA_factor_x);\nlet directAlphaG = directRoughness * directRoughness + 0.0005;\nlet D = distributionGGX(NdotH, directAlphaG);\nlet G = geometrySmithGGX(NdotL, NdotV, directAlphaG);\nlet coloredFresnel = fresnelSchlick(VdotH, colorF0, colorF90);\nvar directSpecular = coloredFresnel * D * G * NdotL * lightColor * lightAtten * material.directIntensity;`;\n}\n\nexport function getSingleLightBlock(): string {\n return `let entry = lights.lights[mli(0u)];\nlet lightToFrag = entry.vLightData.xyz - input.worldPos;\nlet lightDist2 = dot(lightToFrag, lightToFrag);\nlet L = normalize(lightToFrag);\nlet NdotL = max(dot(N, L), 0.0);\nlet range = entry.vLightDiffuse.a;\nlet physicalFalloff = material.lightFalloffMode >= 0.5;\nlet physicalAtten = 1.0 / max(lightDist2, 0.0001);\nlet standardAtten = max(0.0, 1.0 - sqrt(lightDist2) / range);\nlet lightAtten = select(standardAtten, physicalAtten, physicalFalloff);\nlet lightColor = entry.vLightDiffuse.rgb;\nvar directDiffuse = surfaceAlbedo * (1.0 / PI) * NdotL * lightColor * lightAtten * material.directIntensity;\n${specularBlock()}\n/*AD*/`;\n}\n"],"names":[],"mappings":";AAIO,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCASJ,UAAU;AAAA;AAAA;AAI1C,SAAS,gBAAwB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASX;AAEO,SAAS,sBAA8B;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYT,eAAe;AAAA;AAEjB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MAX_LIGHTS } from "./index-
|
|
1
|
+
import { M as MAX_LIGHTS } from "./index-B7Qhw0xL.js";
|
|
2
2
|
const SINGLE_LIGHT_STRUCTS = `
|
|
3
3
|
struct LightEntry {
|
|
4
4
|
vLightData: vec4<f32>,
|
|
@@ -44,4 +44,4 @@ export {
|
|
|
44
44
|
SINGLE_LIGHT_STRUCTS,
|
|
45
45
|
getSingleLightBlock
|
|
46
46
|
};
|
|
47
|
-
//# sourceMappingURL=singlelight-spot-wgsl-
|
|
47
|
+
//# sourceMappingURL=singlelight-spot-wgsl-DVbaVufF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singlelight-spot-wgsl-
|
|
1
|
+
{"version":3,"file":"singlelight-spot-wgsl-DVbaVufF.js","sources":["../src/material/pbr/fragments/singlelight-spot-wgsl.ts"],"sourcesContent":["/** Single spot-light WGSL helpers for the PBR template. */\n\nimport { MAX_LIGHTS } from \"../../../light/types.js\";\n\nexport const SINGLE_LIGHT_STRUCTS = `\nstruct LightEntry {\nvLightData: vec4<f32>,\nvLightDiffuse: vec4<f32>,\nvLightSpecular: vec4<f32>,\nvLightDirection: vec4<f32>,\n};\nstruct lightsUniforms {\ncount: u32, _p0: u32, _p1: u32, _p2: u32,\n lights: array<LightEntry, ${MAX_LIGHTS}>,\n};\n`;\n\nfunction specularBlock(): string {\n return `let H = normalize(V + L);\nlet NdotH = clamp(dot(N, H), 0.0000001, 1.0);\nlet VdotH = saturate(dot(V, H));\nlet directRoughness = max(roughness, AA_factor_x);\nlet directAlphaG = directRoughness * directRoughness + 0.0005;\nlet D = distributionGGX(NdotH, directAlphaG);\nlet G = geometrySmithGGX(NdotL, NdotV, directAlphaG);\nlet coloredFresnel = fresnelSchlick(VdotH, colorF0, colorF90);\nvar directSpecular = coloredFresnel * D * G * NdotL * lightColor * lightAtten * material.directIntensity;`;\n}\n\nexport function getSingleLightBlock(): string {\n return `let entry = lights.lights[mli(0u)];\nlet lightToFrag = entry.vLightData.xyz - input.worldPos;\nlet lightDist = length(lightToFrag);\nlet L = lightToFrag / max(lightDist, 0.0001);\nlet NdotL = max(dot(N, L), 0.0);\nlet spotC = dot(entry.vLightDirection.xyz, -L);\nlet physicalFalloff = material.lightFalloffMode >= 0.5;\nlet rangeAtt = select(max(0.0, 1.0 - lightDist / entry.vLightDiffuse.a), 1.0 / max(dot(lightToFrag, lightToFrag), 0.0000001), physicalFalloff);\nlet standardDirFalloff = select(0.0, max(0.0, pow(max(spotC, 0.0), entry.vLightSpecular.a)), spotC >= entry.vLightDirection.w);\nlet kappa = 6.64385618977 / max(1.0 - entry.vLightDirection.w, 0.0001);\nlet physicalDirFalloff = exp2(kappa * (spotC - 1.0));\nlet lightAtten = rangeAtt * select(standardDirFalloff, physicalDirFalloff, physicalFalloff);\nlet lightColor = entry.vLightDiffuse.rgb;\nvar directDiffuse = surfaceAlbedo * (1.0 / PI) * NdotL * lightColor * lightAtten * material.directIntensity;\n${specularBlock()}\n/*AD*/`;\n}\n"],"names":[],"mappings":";AAIO,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCASJ,UAAU;AAAA;AAAA;AAI1C,SAAS,gBAAwB;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASX;AAEO,SAAS,sBAA8B;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcT,eAAe;AAAA;AAEjB;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MSH_HAS_SKELETON, a as MSH_HAS_SKELETON_8 } from "./mesh-features-
|
|
1
|
+
import { M as MSH_HAS_SKELETON, a as MSH_HAS_SKELETON_8 } from "./mesh-features-BAJpbMog.js";
|
|
2
2
|
const STAGE_VERTEX = 1;
|
|
3
3
|
const SKELETON_HELPERS = `
|
|
4
4
|
fn readMatrixFromRawSampler(smp: texture_2d<f32>, index: f32) -> mat4x4<f32> {
|
|
@@ -68,4 +68,4 @@ export {
|
|
|
68
68
|
createSkeletonFragment,
|
|
69
69
|
pbrExt
|
|
70
70
|
};
|
|
71
|
-
//# sourceMappingURL=skeleton-fragment-
|
|
71
|
+
//# sourceMappingURL=skeleton-fragment-BOVmc8YS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton-fragment-
|
|
1
|
+
{"version":3,"file":"skeleton-fragment-BOVmc8YS.js","sources":["../src/material/pbr/fragments/skeleton-fragment.ts"],"sourcesContent":["/**\n * Skeleton Fragment\n *\n * Vertex-stage skeletal animation: bone texture sampling + skinning matrix.\n * Only bundled when a scene has skeletal animation.\n * Supports 4-bone and 8-bone skinning.\n */\n\nimport type { ShaderFragment, VertexAttribute } from \"../../../shader/fragment-types.js\";\n\n// WebGPU shader stage constants\nconst STAGE_VERTEX = 0x1;\n\nconst SKELETON_HELPERS = `\nfn readMatrixFromRawSampler(smp: texture_2d<f32>, index: f32) -> mat4x4<f32> {\nlet offset = i32(index) * 4;\nlet m0 = textureLoad(smp, vec2<i32>(offset + 0, 0), 0);\nlet m1 = textureLoad(smp, vec2<i32>(offset + 1, 0), 0);\nlet m2 = textureLoad(smp, vec2<i32>(offset + 2, 0), 0);\nlet m3 = textureLoad(smp, vec2<i32>(offset + 3, 0), 0);\nreturn mat4x4f(m0, m1, m2, m3);\n}\n`;\n\nfunction makeSkinningCode(has8Bones: boolean): string {\n let code = `var influence: mat4x4<f32> = readMatrixFromRawSampler(boneSampler, f32(joints[0])) * weights[0];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints[1])) * weights[1];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints[2])) * weights[2];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints[3])) * weights[3];`;\n if (has8Bones) {\n code += `\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints1[0])) * weights1[0];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints1[1])) * weights1[1];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints1[2])) * weights1[2];\ninfluence = influence + readMatrixFromRawSampler(boneSampler, f32(joints1[3])) * weights1[3];`;\n }\n code += `\\nfinalWorld = mesh.world * influence;`;\n return code;\n}\n\n/**\n * Create a skeleton fragment.\n * @param has8Bones - Whether to use 8-bone skinning (joints1/weights1).\n */\nexport function createSkeletonFragment(has8Bones: boolean): ShaderFragment {\n return {\n _id: \"skeleton\",\n\n _vertexAttributes: [\n { _name: \"joints\", _type: \"vec4<u32>\", _gpuFormat: \"uint32x4\" as GPUVertexFormat, _arrayStride: 16 },\n { _name: \"weights\", _type: \"vec4<f32>\", _gpuFormat: \"float32x4\" as GPUVertexFormat, _arrayStride: 16 },\n ...(has8Bones\n ? [\n { _name: \"joints1\", _type: \"vec4<u32>\", _gpuFormat: \"uint32x4\" as GPUVertexFormat, _arrayStride: 16 },\n { _name: \"weights1\", _type: \"vec4<f32>\", _gpuFormat: \"float32x4\" as GPUVertexFormat, _arrayStride: 16 },\n ]\n : []),\n ] as VertexAttribute[],\n\n _vertexBindings: [\n { _name: \"boneSampler\", _type: { _kind: \"texture\", _textureType: \"texture_2d<f32>\" as const, _sampleType: \"unfilterable-float\" as const }, _visibility: STAGE_VERTEX },\n ],\n\n _vertexHelperFunctions: SKELETON_HELPERS,\n\n _vertexSlots: {\n VW: makeSkinningCode(has8Bones),\n },\n };\n}\n\nimport type { PbrExt } from \"../pbr-flags.js\";\nimport { MSH_HAS_SKELETON, MSH_HAS_SKELETON_8 } from \"../../mesh-features.js\";\n\nexport const pbrExt: PbrExt = {\n id: \"skeleton\",\n phase: \"vertex\",\n frag(ctx) {\n if (!(ctx._meshFeatures & MSH_HAS_SKELETON)) {\n return null;\n }\n return createSkeletonFragment((ctx._meshFeatures & MSH_HAS_SKELETON_8) !== 0);\n },\n bind(ctx, entries, b) {\n const mesh = ctx._mesh as { skeleton?: { boneTexture: GPUTexture } } | undefined;\n if (!(ctx._meshFeatures & MSH_HAS_SKELETON) || !mesh?.skeleton) {\n return b;\n }\n entries.push({ binding: b++, resource: mesh.skeleton.boneTexture.createView() });\n return b;\n },\n};\n"],"names":[],"mappings":";AAWA,MAAM,eAAe;AAErB,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWzB,SAAS,iBAAiB,WAA4B;AAClD,MAAI,OAAO;AAAA;AAAA;AAAA;AAIX,MAAI,WAAW;AACX,YAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ;AACA,UAAQ;AAAA;AACR,SAAO;AACX;AAMO,SAAS,uBAAuB,WAAoC;AACvE,SAAO;AAAA,IACH,KAAK;AAAA,IAEL,mBAAmB;AAAA,MACf,EAAE,OAAO,UAAU,OAAO,aAAa,YAAY,YAA+B,cAAc,GAAA;AAAA,MAChG,EAAE,OAAO,WAAW,OAAO,aAAa,YAAY,aAAgC,cAAc,GAAA;AAAA,MAClG,GAAI,YACE;AAAA,QACI,EAAE,OAAO,WAAW,OAAO,aAAa,YAAY,YAA+B,cAAc,GAAA;AAAA,QACjG,EAAE,OAAO,YAAY,OAAO,aAAa,YAAY,aAAgC,cAAc,GAAA;AAAA,MAAG,IAE1G,CAAA;AAAA,IAAC;AAAA,IAGX,iBAAiB;AAAA,MACb,EAAE,OAAO,eAAe,OAAO,EAAE,OAAO,WAAW,cAAc,mBAA4B,aAAa,qBAAA,GAAiC,aAAa,aAAA;AAAA,IAAa;AAAA,IAGzK,wBAAwB;AAAA,IAExB,cAAc;AAAA,MACV,IAAI,iBAAiB,SAAS;AAAA,IAAA;AAAA,EAClC;AAER;AAKO,MAAM,SAAiB;AAAA,EAC1B,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK,KAAK;AACN,QAAI,EAAE,IAAI,gBAAgB,mBAAmB;AACzC,aAAO;AAAA,IACX;AACA,WAAO,wBAAwB,IAAI,gBAAgB,wBAAwB,CAAC;AAAA,EAChF;AAAA,EACA,KAAK,KAAK,SAAS,GAAG;AAClB,UAAM,OAAO,IAAI;AACjB,QAAI,EAAE,IAAI,gBAAgB,qBAAqB,EAAC,6BAAM,WAAU;AAC5D,aAAO;AAAA,IACX;AACA,YAAQ,KAAK,EAAE,SAAS,KAAK,UAAU,KAAK,SAAS,YAAY,WAAA,EAAW,CAAG;AAC/E,WAAO;AAAA,EACX;AACJ;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { a_ as createUniformBuffer, a$ as SCENE_UBO_WGSL, t as targetSignatureKey, h as createDefaultPipelineDescriptor, j as getSceneBindGroupLayout } from "./index-B7Qhw0xL.js";
|
|
2
|
+
import { a as WGSL_FOG } from "./wgsl-helpers-D8sl1VVA.js";
|
|
3
3
|
const skyVertSrc = "// Skybox CubeMap Vertex Shader\n// Passes object-space position (for cube texture lookup) and world-space position.\n\nstruct MeshUniforms {\n world: mat4x4<f32>,\n};\n@group(1) @binding(0) var<uniform> mesh: MeshUniforms;\n\nstruct VertexOutput {\n @builtin(position) clipPos: vec4<f32>,\n @location(0) vPositionW: vec3<f32>,\n @location(1) vPositionLocal: vec3<f32>,\n @location(2) vFogDistance: vec3<f32>,\n};\n\n@vertex\nfn main(\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n) -> VertexOutput {\n var out: VertexOutput;\n let worldPos = mesh.world * vec4<f32>(position, 1.0);\n out.vPositionW = worldPos.xyz;\n out.vPositionLocal = position;\n out.clipPos = scene.viewProjection * worldPos;\n out.vFogDistance = (scene.view * worldPos).xyz;\n return out;\n}\n";
|
|
4
4
|
const skyFragSrc = "// Skybox CubeMap Fragment Shader\n// Samples cube texture using object-space position as lookup direction.\n// Matches Babylon StandardMaterial with REFLECTION + REFLECTIONMAP_SKYBOX.\n\n@group(1) @binding(1) var cubeTexture: texture_cube<f32>;\n@group(1) @binding(2) var cubeSampler: sampler;\n\nstruct FragmentInput {\n @location(0) vPositionW: vec3<f32>,\n @location(1) vPositionLocal: vec3<f32>,\n @location(2) vFogDistance: vec3<f32>,\n};\n\n@fragment\nfn main(input: FragmentInput) -> @location(0) vec4<f32> {\n // SKYBOX_MODE: use object-space position as cube lookup direction\n let lookupDir = normalize(input.vPositionLocal);\n var color = textureSample(cubeTexture, cubeSampler, lookupDir);\n\n // Apply fog\n if (scene.vFogInfos.x > 0.0) {\n let fog = calcFogFactor(input.vFogDistance);\n color = vec4<f32>(mix(scene.vFogColor.rgb, color.rgb, fog), color.a);\n }\n\n return color;\n}\n";
|
|
5
5
|
function buildSkyboxCubeMapGPU(engine, worldMatrix, cubeView, cubeSampler) {
|
|
@@ -89,4 +89,4 @@ function buildSkyboxRenderable(scene, skybox) {
|
|
|
89
89
|
export {
|
|
90
90
|
buildSkyboxRenderable
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=skybox-renderable-
|
|
92
|
+
//# sourceMappingURL=skybox-renderable-DDcCPSly.js.map
|