UNPKG

@babylonjs/viewer

Version:

The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.

197 lines (194 loc) 7.94 kB
import { Z as PBR_HAS_METALLIC_REFLECTANCE_MAP, $ as PBR_HAS_REFLECTANCE_MAP, a0 as PBR2_HAS_REFLECTANCE_FACTORS, ay as PBR_HAS_USE_ALPHA_ONLY_MR } from './index-By0tcgYN.esm.js'; const PBR2_REFL_UV_TX = 1 << 26; const STAGE_FRAGMENT = 2; const reflUvExpr = (name) => `(vec2<f32>(dot(material.${name}m.xy, input.uv), dot(material.${name}m.zw, input.uv)) + material.${name}t.xy)`; function writeReflUvTransform(data, offsets, name, tex) { const mOff = offsets.get(`${name}m`); const tOff = offsets.get(`${name}t`); if (mOff === void 0 || tOff === void 0) { return; } const sx = tex?.uScale ?? 1; const sy = tex?.vScale ?? 1; const ang = tex?.uAng ?? 0; const mi = mOff / 4; if (ang === 0) { data[mi] = sx; data[mi + 1] = 0; data[mi + 2] = 0; data[mi + 3] = sy; } else { const c = Math.cos(ang); const s = Math.sin(ang); data[mi] = c * sx; data[mi + 1] = s * sy; data[mi + 2] = -s * sx; data[mi + 3] = c * sy; } const ti = tOff / 4; data[ti] = tex?.uOffset ?? 0; data[ti + 1] = tex?.vOffset ?? 0; } function writeReflectanceUBO(data, material, offsets) { if (!offsets.has("occlusionStrength")) { return; } const off = offsets.get("occlusionStrength") / 4; data[off] = material.occlusionStrength ?? 1; data[off + 1] = material.metallicF0Factor ?? 1; data[off + 2] = material.specularWeight ?? material.metallicF0Factor ?? 1; const mrc = material.metallicReflectanceColor; data[off + 4] = mrc ? mrc[0] : 1; data[off + 5] = mrc ? mrc[1] : 1; data[off + 6] = mrc ? mrc[2] : 1; writeReflUvTransform(data, offsets, "reflUV", material.reflectanceTexture); writeReflUvTransform(data, offsets, "mrReflUV", material.metallicReflectanceTexture); } function createReflectanceFragment(hasMetallicReflectanceMap, hasReflectanceMap, useAlphaOnlyMR, hasOcclusionUv2 = false, hasUvTx = false) { const bindings = []; if (hasMetallicReflectanceMap) { bindings.push( { _name: "metallicReflectanceMap", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT }, { _name: "metallicReflectanceMapSampler", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT } ); } if (hasReflectanceMap) { bindings.push( { _name: "reflectanceMap", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT }, { _name: "reflectanceMapSampler", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT } ); } const reflUv = hasUvTx ? reflUvExpr("reflUV") : "input.uv"; const mrReflUv = hasUvTx ? reflUvExpr("mrReflUV") : "input.uv"; let f0Code = `var mrFactors = vec4<f32>(material.metallicReflectanceColor, material.metallicF0Factor); var specularWeight = material.specularWeight;`; if (hasReflectanceMap) { f0Code += ` { let rSample = textureSample(reflectanceMap, reflectanceMapSampler, ${reflUv}); let rLinear = pow(rSample.rgb, vec3<f32>(2.2)); mrFactors = vec4<f32>(mrFactors.rgb * rLinear, mrFactors.a); }`; } if (hasMetallicReflectanceMap) { if (!useAlphaOnlyMR) { f0Code += ` { let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv}); let mrLinear = pow(mrSample.rgb, vec3<f32>(2.2)); mrFactors = vec4<f32>(mrFactors.rgb * mrLinear, mrFactors.a * mrSample.a); specularWeight *= mrSample.a; }`; } else { f0Code += ` { let mrSample = textureSample(metallicReflectanceMap, metallicReflectanceMapSampler, ${mrReflUv}); mrFactors = vec4<f32>(mrFactors.rgb, mrFactors.a * mrSample.a); specularWeight *= mrSample.a; }`; } } f0Code += ` let dielectricF0 = material.reflectance * mrFactors.a; let surfaceReflectivityColor = mrFactors.rgb; let dielectricColorF0 = vec3<f32>(dielectricF0) * surfaceReflectivityColor; let metallicColorF0 = baseColor; var colorF0 = mix(dielectricColorF0, metallicColorF0, metallic); let colorF90 = vec3<f32>(mix(specularWeight, 1.0, metallic)); let surfaceAlbedo = baseColor * (vec3<f32>(1.0) - vec3<f32>(dielectricF0) * surfaceReflectivityColor) * (1.0 - metallic);`; const uboFields = [ { _name: "occlusionStrength", _type: "f32" }, { _name: "metallicF0Factor", _type: "f32" }, { _name: "specularWeight", _type: "f32" }, { _name: "_mrPad1", _type: "f32" }, { _name: "metallicReflectanceColor", _type: "vec3<f32>" }, { _name: "_mrPad2", _type: "f32" } ]; if (hasUvTx) { if (hasReflectanceMap) { uboFields.push({ _name: "reflUVm", _type: "vec4<f32>" }, { _name: "reflUVt", _type: "vec4<f32>" }); } if (hasMetallicReflectanceMap) { uboFields.push({ _name: "mrReflUVm", _type: "vec4<f32>" }, { _name: "mrReflUVt", _type: "vec4<f32>" }); } } return { _id: hasUvTx ? "reflectance-U" : "reflectance", _uboFields: uboFields, _bindings: bindings, _fragmentSlots: { MF: f0Code, AT: hasOcclusionUv2 ? `let occlusion = mix(1.0, textureSample(occlusionTexture, occlusionSampler_, input.uv2).r, material.occlusionStrength);` : `let occlusion = mix(1.0, orm.r, material.occlusionStrength);` } }; } const pbrExt = { id: "reflectance", phase: "fragment", detect(mat) { const m = mat; let f = 0; let f2 = 0; if (m.metallicReflectanceTexture) { f |= PBR_HAS_METALLIC_REFLECTANCE_MAP; } if (m.reflectanceTexture) { f |= PBR_HAS_REFLECTANCE_MAP; } if (f === 0) { const hasNonDefaultF0 = m.metallicF0Factor != null && Math.abs(m.metallicF0Factor - 1) > 1e-6; const mrc = m.metallicReflectanceColor; const hasNonDefaultColor = mrc != null && (mrc[0] !== 1 || mrc[1] !== 1 || mrc[2] !== 1); if (hasNonDefaultF0 || hasNonDefaultColor || m._occlStrengthAnimated) { f2 |= PBR2_HAS_REFLECTANCE_FACTORS; } } if ((f !== 0 || f2 & PBR2_HAS_REFLECTANCE_FACTORS) && m.useOnlyMetallicFromMetallicReflectanceTexture) { f |= PBR_HAS_USE_ALPHA_ONLY_MR; } const refHasTx = (t) => !!t?._hasTx; if (f !== 0 && (refHasTx(m.reflectanceTexture) || refHasTx(m.metallicReflectanceTexture))) { f2 |= PBR2_REFL_UV_TX; } return { f, f2 }; }, frag(ctx) { const hasMR = (ctx._features & PBR_HAS_METALLIC_REFLECTANCE_MAP) !== 0; const hasR = (ctx._features & PBR_HAS_REFLECTANCE_MAP) !== 0; const hasFactors = (ctx._features2 & PBR2_HAS_REFLECTANCE_FACTORS) !== 0; if (!hasMR && !hasR && !hasFactors) { return null; } return createReflectanceFragment( hasMR, hasR, (ctx._features & PBR_HAS_USE_ALPHA_ONLY_MR) !== 0, // Occlusion-on-UV1 specifically (mask bit 1<<5), not any channel. Must match // createPbrTemplateExt's _hasOcclusionUv2 so the occlusionTexture binding it declares // and this sample agree. ctx._uv2Mask is already zeroed when uv2 isn't present. ((ctx._uv2Mask ?? 0) & 1 << 5) !== 0, (ctx._features2 & PBR2_REFL_UV_TX) !== 0 ); }, writeUbo: writeReflectanceUBO, bind(ctx, entries, b) { if ((ctx._features & (PBR_HAS_METALLIC_REFLECTANCE_MAP | PBR_HAS_REFLECTANCE_MAP)) === 0) { return b; } const m = ctx._material; if (m.metallicReflectanceTexture) { entries.push({ binding: b++, resource: m.metallicReflectanceTexture.view }); entries.push({ binding: b++, resource: m.metallicReflectanceTexture.sampler }); } if (m.reflectanceTexture) { entries.push({ binding: b++, resource: m.reflectanceTexture.view }); entries.push({ binding: b++, resource: m.reflectanceTexture.sampler }); } return b; }, textures(mat, t) { const m = mat; if (m.metallicReflectanceTexture) { t.push(m.metallicReflectanceTexture); } if (m.reflectanceTexture) { t.push(m.reflectanceTexture); } } }; export { createReflectanceFragment, pbrExt, writeReflectanceUBO }; //# sourceMappingURL=reflectance-fragment-BPVyxyKG.esm.js.map