@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.
241 lines (238 loc) • 8.41 kB
JavaScript
import { aA as PBR_HAS_SHEEN_TEXTURE, aB as PBR_HAS_SHEEN, aC as PBR_HAS_SHEEN_ALBEDO_SCALING } from './index-By0tcgYN.esm.js';
const STAGE_FRAGMENT = 2;
const PBR2_HAS_SHEEN_UV_TX = 1 << 13;
const PBR2_HAS_SHEEN_ROUGH_TEX = 1 << 29;
const SHEEN_HELPERS = `
fn normalDistributionFunction_CharlieSheen(NdotH_sh: f32, alphaG_sh: f32) -> f32 {
let invR = 1.0 / alphaG_sh;
let cos2h = NdotH_sh * NdotH_sh;
let sin2h = 1.0 - cos2h;
return (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * 3.141592653589793);
}
fn visibility_Ashikhmin(NdotL_sh: f32, NdotV_sh: f32) -> f32 {
return 1.0 / (4.0 * (NdotL_sh + NdotV_sh - NdotL_sh * NdotV_sh));
}
`;
const SHEEN_DIRECT_MOD = (intensityExpr) => `
{
let shIntensity = ${intensityExpr};
let shColorScaled = sheenColorFinal * shIntensity;
let shRoughness_clamped = max(sheenRoughnessAdjusted, AA_factor_x);
let shAlphaG = shRoughness_clamped * shRoughness_clamped + 0.0005;
let shD = normalDistributionFunction_CharlieSheen(NdotH, shAlphaG);
let shV = visibility_Ashikhmin(NdotL, NdotV);
sheenDirectTerm = shColorScaled * shD * shV * NdotL * lightColor * lightAtten * material.directIntensity;
}
`;
const SHEEN_IBL_MOD = (intensityExpr, albedoScaling) => `
{
let shIntensity_ibl = ${intensityExpr};
let shColorScaled = sheenColorFinal * shIntensity_ibl;
let shRoughness_ibl = sheenRoughnessAdjusted;
let shAlphaG_ibl = shRoughness_ibl * shRoughness_ibl + 0.0005 + AA_factor_y;
var shSpecLod = log2(cubemapDim * shAlphaG_ibl) * scene.vImageInfos.z;
let shEnvRadiance = textureSampleLevel(iblTexture, iblSampler, R, clamp(shSpecLod, 0.0, maxLod)).rgb * material.environmentIntensity;
let shBrdf = textureSampleLevel(brdfLUT, brdfSampler_, vec2<f32>(NdotV, shRoughness_ibl), 0.0);
let shEnvReflectance = shColorScaled * shBrdf.b${albedoScaling ? " * seo * eho" : ""};
sheenIblTerm = shEnvRadiance * shEnvReflectance;
${albedoScaling ? "let shMax = max(shColorScaled.r, max(shColorScaled.g, shColorScaled.b));\nsheenAlbedoScaling = 1.0 - shMax * shBrdf.b;" : ""}
}
`;
const SHEEN_IBL_COLOR_MOD = (albedoScaling) => albedoScaling ? `
{
color = (finalIrradiance
+ finalRadianceScaled
+ finalSpecularScaled
+ directDiffuse) * sheenAlbedoScaling
+ sheenDirectTerm
+ sheenIblTerm
+ emissive;
}
` : `
{
color = finalIrradiance
+ finalRadianceScaled
+ finalSpecularScaled
+ directDiffuse
+ sheenDirectTerm
+ sheenIblTerm
+ emissive;
}
`;
const SHEEN_NON_IBL_MOD = `
{
color = color + sheenDirectTerm;
}
`;
function createSheenFragment(hasSheenTexture, hasIbl = false, hasAlbedoScaling = false, hasSheenUvTx = false, hasSheenRoughTex = false) {
let scopeVars = `var sheenDirectTerm = vec3<f32>(0.0);
var sheenIblTerm = vec3<f32>(0.0);
var sheenAlbedoScaling = 1.0;
var sheenColorFinal = material.sheenParams.rgb;
var sheenRoughnessAdjusted = material.sheenParams2.x;`;
if (hasSheenTexture) {
const gammaStmt = hasAlbedoScaling ? "sheenMapData.rgb" : "pow(sheenMapData.rgb, vec3<f32>(2.2))";
const sheenUvDecl = hasSheenUvTx ? "let sheenUV = vec2<f32>(dot(material.sheenUVm.xy, input.uv), dot(material.sheenUVm.zw, input.uv)) + material.sheenUVt.xy;" : "let sheenUV = input.uv;";
const roughFromColor = hasSheenRoughTex ? "" : "\nsheenRoughnessAdjusted *= sheenMapData.a;";
scopeVars += `
{
${sheenUvDecl}
let sheenMapData = textureSample(sheenTexture_, sheenSampler_, sheenUV);
sheenColorFinal *= ${gammaStmt};${roughFromColor}
}`;
}
if (hasSheenRoughTex) {
scopeVars += `
{
let sheenRoughUV = vec2<f32>(dot(material.sheenRoughUVm.xy, input.uv), dot(material.sheenRoughUVm.zw, input.uv)) + material.sheenRoughUVt.xy;
sheenRoughnessAdjusted *= textureSample(sheenRoughTexture_, sheenRoughSampler_, sheenRoughUV).a;
}`;
}
const intensityExpr = hasAlbedoScaling ? "material.sheenParams.a" : "material.sheenParams.a * (1.0 - dielectricF0)";
const slots = {
SV: scopeVars,
AD: SHEEN_DIRECT_MOD(intensityExpr)
};
if (hasIbl) {
slots.AI = SHEEN_IBL_MOD(intensityExpr, hasAlbedoScaling) + SHEEN_IBL_COLOR_MOD(hasAlbedoScaling);
} else {
slots.NI = SHEEN_NON_IBL_MOD;
}
const bindings = [];
if (hasSheenTexture) {
bindings.push(
{ _name: "sheenTexture_", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT },
{ _name: "sheenSampler_", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT }
);
}
if (hasSheenRoughTex) {
bindings.push(
{ _name: "sheenRoughTexture_", _type: { _kind: "texture", _textureType: "texture_2d<f32>" }, _visibility: STAGE_FRAGMENT },
{ _name: "sheenRoughSampler_", _type: { _kind: "sampler", _samplerType: "sampler" }, _visibility: STAGE_FRAGMENT }
);
}
const uboFields = [
{ _name: "sheenParams", _type: "vec4<f32>" },
{ _name: "sheenParams2", _type: "vec4<f32>" }
];
if (hasSheenUvTx) {
uboFields.push({ _name: "sheenUVm", _type: "vec4<f32>" }, { _name: "sheenUVt", _type: "vec4<f32>" });
}
if (hasSheenRoughTex) {
uboFields.push({ _name: "sheenRoughUVm", _type: "vec4<f32>" }, { _name: "sheenRoughUVt", _type: "vec4<f32>" });
}
return {
_id: "sheen",
_dependencies: hasIbl ? ["ibl"] : void 0,
_uboFields: uboFields,
_bindings: bindings,
_helperFunctions: SHEEN_HELPERS,
_fragmentSlots: slots
};
}
function writeSheenUBO(data, material, offsets) {
const sh = material.sheen;
if (!sh?.isEnabled || !offsets.has("sheenParams")) {
return;
}
const off = offsets.get("sheenParams") / 4;
const color = sh.color ?? [1, 1, 1];
data[off] = color[0];
data[off + 1] = color[1];
data[off + 2] = color[2];
data[off + 3] = sh.intensity ?? 1;
data[off + 4] = sh.roughness ?? 0;
data[off + 5] = sh.texture ? 1 : 0;
writeSheenUvTransform(data, offsets, "sheenUVm", "sheenUVt", sh.texture);
writeSheenUvTransform(data, offsets, "sheenRoughUVm", "sheenRoughUVt", sh.roughnessTexture);
}
function writeSheenUvTransform(data, offsets, mName, tName, tex) {
const mOff = offsets.get(mName);
const tOff = offsets.get(tName);
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;
const ti = tOff / 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;
}
data[ti] = tex?.uOffset ?? 0;
data[ti + 1] = tex?.vOffset ?? 0;
data[ti + 2] = 0;
data[ti + 3] = 0;
}
const pbrExt = {
id: "sheen",
phase: "base-tex",
detect(mat) {
const sh = mat.sheen;
if (!sh?.isEnabled) {
return { f: 0, f2: 0 };
}
let f = PBR_HAS_SHEEN;
let f2 = 0;
if (sh.texture) {
f |= PBR_HAS_SHEEN_TEXTURE;
if (sh.texture._hasTx) {
f2 |= PBR2_HAS_SHEEN_UV_TX;
}
}
if (sh.roughnessTexture) {
f2 |= PBR2_HAS_SHEEN_ROUGH_TEX;
}
if (sh.albedoScaling) {
f |= PBR_HAS_SHEEN_ALBEDO_SCALING;
}
return { f, f2 };
},
frag(ctx) {
if (!(ctx._features & PBR_HAS_SHEEN)) {
return null;
}
return createSheenFragment(
(ctx._features & PBR_HAS_SHEEN_TEXTURE) !== 0,
ctx._hasIbl,
(ctx._features & PBR_HAS_SHEEN_ALBEDO_SCALING) !== 0,
(ctx._features2 & PBR2_HAS_SHEEN_UV_TX) !== 0,
(ctx._features2 & PBR2_HAS_SHEEN_ROUGH_TEX) !== 0
);
},
writeUbo: writeSheenUBO,
bind(ctx, entries, b) {
const sh = ctx._material.sheen;
if ((ctx._features & PBR_HAS_SHEEN_TEXTURE) !== 0 && sh?.texture) {
entries.push({ binding: b++, resource: sh.texture.view });
entries.push({ binding: b++, resource: sh.texture.sampler });
}
if ((ctx._features2 & PBR2_HAS_SHEEN_ROUGH_TEX) !== 0 && sh?.roughnessTexture) {
entries.push({ binding: b++, resource: sh.roughnessTexture.view });
entries.push({ binding: b++, resource: sh.roughnessTexture.sampler });
}
return b;
},
textures(mat, out) {
const sh = mat.sheen;
if (sh?.texture) {
out.push(sh.texture);
}
if (sh?.roughnessTexture) {
out.push(sh.roughnessTexture);
}
}
};
export { createSheenFragment, pbrExt, writeSheenUBO };
//# sourceMappingURL=sheen-fragment-BXKqQYuO.esm.js.map