@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.
109 lines (107 loc) • 4.33 kB
JavaScript
const ext = {
id: "KHR_materials_dielectric",
async applyMaterial(mat, ctx) {
const exts = mat._rawMatDef?.extensions;
if (!exts) {
return null;
}
const eIor = exts.KHR_materials_ior;
const eSp = exts.KHR_materials_specular;
const eVol = exts.KHR_materials_volume;
const eTx = exts.KHR_materials_transmission;
const eDisp = exts.KHR_materials_dispersion;
if (!eIor && !eSp && !eVol && !eTx && !eDisp) {
return null;
}
const [specTex, specColTex, thickTex, transTex] = await Promise.all([
ctx._texture(eSp?.specularTexture, false),
// specularColorTexture is sRGB-encoded, but the reflectance shader applies its
// own pow(2.2) (matching BJS toLinearSpace on a gammaSpace texture). Load it as
// a LINEAR-format texture so the GPU does NOT also sRGB-decode on sample — else
// the dielectric tint is gamma-decoded twice (too dark/saturated), as seen on
// AnimationPointerUVs col4 specularColorTexture spheres.
ctx._texture(eSp?.specularColorTexture, false),
ctx._texture(eVol?.thicknessTexture, false),
ctx._texture(eTx?.transmissionTexture, false)
]);
const out = {};
const subsurface = {};
if (eIor) {
const ior = typeof eIor.ior === "number" ? eIor.ior : 1.5;
if (ior !== 1.5) {
out.metallicF0Factor = ((ior - 1) / (ior + 1)) ** 2 / 0.04;
out.specularWeight = 1;
out._hasReflExt = true;
}
subsurface.refraction = { indexOfRefraction: ior };
}
if (eSp) {
if (typeof eSp.specularFactor === "number") {
if (Math.abs(eSp.specularFactor - 1) > 1e-6) {
out.metallicF0Factor = eSp.specularFactor;
out.specularWeight = eSp.specularFactor;
out._hasReflExt = true;
} else {
delete out.metallicF0Factor;
delete out.specularWeight;
}
}
if (Array.isArray(eSp.specularColorFactor) && eSp.specularColorFactor.length === 3) {
if (eSp.specularColorFactor[0] !== 1 || eSp.specularColorFactor[1] !== 1 || eSp.specularColorFactor[2] !== 1) {
out.metallicReflectanceColor = [eSp.specularColorFactor[0], eSp.specularColorFactor[1], eSp.specularColorFactor[2]];
out._hasReflExt = true;
}
}
if (specTex) {
out.metallicReflectanceTexture = specTex;
out.useOnlyMetallicFromMetallicReflectanceTexture = true;
}
if (specColTex) {
out.reflectanceTexture = specColTex;
}
}
if (eVol) {
const thicknessFactor = typeof eVol.thicknessFactor === "number" ? eVol.thicknessFactor : 0;
if (thicknessFactor > 0 || thickTex) {
subsurface.thickness = {
min: 0,
max: thicknessFactor || 1,
useGlTFChannel: true,
...thickTex ? { texture: thickTex } : void 0
};
}
const color = Array.isArray(eVol.attenuationColor) && eVol.attenuationColor.length === 3 ? eVol.attenuationColor : void 0;
const atDistance = typeof eVol.attenuationDistance === "number" ? eVol.attenuationDistance : void 0;
if (color || atDistance !== void 0) {
subsurface.tint = {
...color ? { color } : void 0,
...atDistance !== void 0 ? { atDistance } : void 0
};
} else if (subsurface.thickness) {
subsurface.tint = { color: [1, 1, 1], atDistance: 1 };
}
}
if (eTx) {
const intensity = typeof eTx.transmissionFactor === "number" ? eTx.transmissionFactor : 0;
if (intensity > 0 || transTex) {
out.transmissive = true;
const refraction = {
...subsurface.refraction ?? {},
intensity,
useThicknessAsDepth: !!subsurface.thickness,
...transTex ? { texture: transTex } : void 0
};
subsurface.refraction = refraction;
}
}
if (eDisp && typeof eDisp.dispersion === "number" && eDisp.dispersion > 0 && subsurface.refraction && subsurface.thickness) {
subsurface.refraction = { ...subsurface.refraction, dispersion: 20 / eDisp.dispersion };
}
if (Object.keys(subsurface).length > 0) {
out.subsurface = subsurface;
}
return Object.keys(out).length > 0 ? out : null;
}
};
export { ext as default };
//# sourceMappingURL=gltf-ext-dielectric-BKGcH-t4.esm.js.map