@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.
260 lines (257 loc) • 8.91 kB
JavaScript
import { _ as _appendPointerHandlers } from './gltf-feature-animation-pointer-C-4at_Z4.esm.js';
import './index-DMbDahsc.esm.js';
import './visibility-C1lTwkPL.esm.js';
import './gltf-animation-BT6DhHCC.esm.js';
function animatedTargets(json) {
const occlusionStrength = /* @__PURE__ */ new Set();
const transmission = /* @__PURE__ */ new Set();
const ior = /* @__PURE__ */ new Set();
const volumeThickness = /* @__PURE__ */ new Set();
const volumeTint = /* @__PURE__ */ new Set();
for (const anim of json.animations ?? []) {
for (const ch of anim.channels ?? []) {
const ptr = ch.target?.extensions?.KHR_animation_pointer?.pointer;
if (!ptr) {
continue;
}
const os = /^\/materials\/(\d+)\/occlusionTexture\/strength$/.exec(ptr);
if (os) {
occlusionStrength.add(+os[1]);
}
const tr = /^\/materials\/(\d+)\/extensions\/KHR_materials_transmission\/transmissionFactor$/.exec(ptr);
if (tr) {
transmission.add(+tr[1]);
}
const io = /^\/materials\/(\d+)\/extensions\/KHR_materials_ior\/ior$/.exec(ptr);
if (io) {
ior.add(+io[1]);
}
const vt = /^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/thicknessFactor$/.exec(ptr);
if (vt) {
volumeThickness.add(+vt[1]);
}
const vc = /^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/(attenuationColor|attenuationDistance)$/.exec(ptr);
if (vc) {
volumeTint.add(+vc[1]);
}
}
}
return { occlusionStrength, transmission, ior, volumeThickness, volumeTint };
}
async function prepareExtMaterials(json) {
const animated = animatedTargets(json);
const needsReflectance = animated.occlusionStrength.size > 0 || animated.ior.size > 0;
const setReflectance = needsReflectance ? (await import('./set-metallic-reflectance-Dy2tXW29.esm.js')).setPbrMetallicReflectance : null;
return (map) => seedExtMaterials(json, map, animated, setReflectance);
}
function asPbrProps(m) {
return m;
}
function iorToF0Factor(ior) {
return ((ior - 1) / (ior + 1)) ** 2 / 0.04;
}
function bump(mat) {
mat._uboVersion++;
}
const _extHandlers = [
// BJS 9.5 registers the glTF metallicFactor pointer twice, with the second
// entry overwriting the first to animate PBRMaterial.roughness. Match that
// behavior for parity; roughnessFactor itself is not registered by BJS.
[
/^\/materials\/(\d+)\/pbrMetallicRoughness\/metallicFactor$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
if (!mat) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
mat.roughnessFactor = out[off];
mat._uboVersion++;
}
};
}
],
// /materials/{m}/normalTexture/scale — scalar glTF normal-map strength. The
// shader scale mod is provided by the lazy pbr-template-ext (loaded for materials
// that already carry a UV transform / vertex colour / UV2), so this writer only
// updates the existing `normalScale` UBO slot — no core shader path is added.
[
/^\/materials\/(\d+)\/normalTexture\/scale$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
if (!mat) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
mat.normalTextureScale = out[off];
mat._uboVersion++;
}
};
}
],
// /materials/{m}/extensions/KHR_materials_transmission/transmissionFactor
[
/^\/materials\/(\d+)\/extensions\/KHR_materials_transmission\/transmissionFactor$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
const refr = mat?._subsurface?.refraction;
if (!mat || !refr) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
mat._transmissive = true;
refr.intensity = out[off];
bump(mat);
}
};
}
],
// /materials/{m}/extensions/KHR_materials_ior/ior
[
/^\/materials\/(\d+)\/extensions\/KHR_materials_ior\/ior$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
if (!mat) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
const ior = out[off];
if (mat._subsurface?.refraction) {
mat._subsurface.refraction.indexOfRefraction = ior;
}
mat._metallicF0Factor = iorToF0Factor(ior);
mat._specularWeight = 1;
bump(mat);
}
};
}
],
// /materials/{m}/extensions/KHR_materials_volume/{thicknessFactor|attenuationDistance|attenuationColor}
[
/^\/materials\/(\d+)\/extensions\/KHR_materials_volume\/(thicknessFactor|attenuationDistance|attenuationColor)$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
if (!mat?._subsurface) {
return null;
}
return {
arity: m[2] === "attenuationColor" ? 3 : 1,
writer: (out, off) => {
const ss = mat._subsurface;
if (m[2] === "thicknessFactor") {
ss.thickness ??= { min: 0, max: 0, useGlTFChannel: true };
ss.thickness.max = out[off];
if (ss.refraction) {
ss.refraction.useThicknessAsDepth = true;
}
} else {
ss.tint ??= { color: [1, 1, 1], atDistance: 1 };
if (m[2] === "attenuationDistance") {
ss.tint.atDistance = out[off];
} else {
ss.tint.color = [out[off], out[off + 1], out[off + 2]];
}
}
bump(mat);
}
};
}
],
// /materials/{m}/extensions/KHR_materials_iridescence/{iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum}
[
/^\/materials\/(\d+)\/extensions\/KHR_materials_iridescence\/(iridescenceFactor|iridescenceIor|iridescenceThicknessMaximum)$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
const iri = mat?._iridescence;
if (!mat || !iri) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
const v = out[off];
if (m[2] === "iridescenceFactor") {
iri.intensity = v;
} else if (m[2] === "iridescenceIor") {
iri.indexOfRefraction = v;
} else {
iri.maximumThickness = v;
}
bump(mat);
}
};
}
],
// /materials/{m}/occlusionTexture/strength — scalar ambient-occlusion strength.
// The occlusion mix (mix(1, orm.r, strength)) is supplied by the lazy reflectance
// ext, which the seeding path below registers; this writer only updates the
// `occlusionStrength` UBO slot that ext owns — zero core shader cost.
[
/^\/materials\/(\d+)\/occlusionTexture\/strength$/,
(m, ctx) => {
const mat = ctx.materials?.[+m[1]];
if (!mat) {
return null;
}
return {
arity: 1,
writer: (out, off) => {
mat.occlusionStrength = out[off];
mat._uboVersion++;
}
};
}
]
];
_appendPointerHandlers(_extHandlers);
function seedExtMaterials(json, map, animated, setReflectance) {
for (let matIdx = 0; matIdx < map.length; matIdx++) {
const pm = map[matIdx];
if (!pm) {
continue;
}
const def = json.materials?.[matIdx];
if (animated.occlusionStrength.has(matIdx)) {
pm.occlusionStrength = def?.occlusionTexture?.strength ?? 1;
setReflectance?.(asPbrProps(pm), {});
pm._occlStrengthAnimated = true;
}
if (animated.transmission.has(matIdx)) {
pm._transmissive = true;
pm._subsurface ??= {};
pm._subsurface.refraction ??= {
intensity: def?.extensions?.KHR_materials_transmission?.transmissionFactor ?? 0,
indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5
};
}
if (animated.ior.has(matIdx)) {
pm._subsurface ??= {};
pm._subsurface.refraction ??= { intensity: 0, indexOfRefraction: def?.extensions?.KHR_materials_ior?.ior ?? 1.5 };
const ior = def?.extensions?.KHR_materials_ior?.ior ?? 1.5;
setReflectance?.(asPbrProps(pm), { f0Factor: iorToF0Factor(ior), specularWeight: 1 });
}
if (animated.volumeThickness.has(matIdx) || animated.volumeTint.has(matIdx)) {
pm._subsurface ??= {};
const eVol = def?.extensions?.KHR_materials_volume;
if (animated.volumeThickness.has(matIdx)) {
pm._subsurface.thickness ??= { min: 0, max: eVol?.thicknessFactor ?? 0, useGlTFChannel: true };
if (pm._subsurface.refraction) {
pm._subsurface.refraction.useThicknessAsDepth = true;
}
}
if (animated.volumeTint.has(matIdx)) {
pm._subsurface.tint ??= { color: eVol?.attenuationColor ?? [1, 1, 1], atDistance: eVol?.attenuationDistance ?? 1 };
}
}
}
}
export { prepareExtMaterials };
//# sourceMappingURL=animation-pointer-ext-Cx4tnUlZ.esm.js.map