Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/dev/core/src/Materials/PBR/openpbrMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export class OpenPBRMaterialDefines extends ImageProcessingDefinesMixin(OpenPBRM
public SPECULAR_WEIGHT_IN_ALPHA = false;
public SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE = false;
public SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = false;
public COAT_ROUGHNESS_FROM_GREEN_CHANNEL = false;
public COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = false;
public USE_GLTF_STYLE_ANISOTROPY = false;
public THIN_FILM_THICKNESS_FROM_THIN_FILM_TEXTURE = false;
Expand Down Expand Up @@ -1234,6 +1235,13 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
*/
public _useCoatRoughnessAnisotropyFromTangentTexture = false;

/**
* Specifies whether the coat roughness is taken from the green channel of the coat texture.
* This is for compatibility with glTF's KHR_materials_clearcoat and KHR_materials_coat extensions.
* @internal
*/
public _useCoatRoughnessFromGreenChannel = false;

/**
* Assume the anisotropy data is stored in the format specified by
* KHR_materials_anisotropy.
Expand Down Expand Up @@ -2620,6 +2628,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
defines.SPECULAR_WEIGHT_FROM_SPECULAR_COLOR_TEXTURE = this._useSpecularWeightFromSpecularColorTexture;
defines.SPECULAR_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = this._useSpecularRoughnessAnisotropyFromTangentTexture;
defines.COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE = this._useCoatRoughnessAnisotropyFromTangentTexture;
defines.COAT_ROUGHNESS_FROM_GREEN_CHANNEL = this._useCoatRoughnessFromGreenChannel;
defines.ROUGHNESSSTOREINMETALMAPGREEN = this._useRoughnessFromMetallicTextureGreen;
defines.METALLNESSSTOREINMETALMAPBLUE = this._useMetallicFromMetallicTextureBlue;
defines.THIN_FILM_THICKNESS_FROM_THIN_FILM_TEXTURE = this._useThinFilmThicknessFromTextureGreen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ geometry_coat_tangent = vGeometryCoatTangent.rg;
#endif

#ifdef COAT_ROUGHNESS
coat_roughness *= coatRoughnessFromTexture.r;
#ifdef COAT_ROUGHNESS_FROM_GREEN_CHANNEL
coat_roughness *= coatRoughnessFromTexture.g;
#else
coat_roughness *= coatRoughnessFromTexture.r;
#endif
#endif

#if defined(GEOMETRY_COAT_TANGENT) && defined(COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
specularColoredFresnel = specularFresnel * specular_color;
#ifdef THIN_FILM
// Scale the thin film effect based on how different the IOR is from 1.0 (no thin film effect)
float thinFilmIorScale = clamp(2.0f * abs(thin_film_ior - 1.0f), 0.0f, 1.0f);
float thinFilmIorScale = clamp(2.0 * abs(thin_film_ior - 1.0), 0.0, 1.0);
vec3 thinFilmDielectricFresnel = evalIridescence(thin_film_outside_ior, thin_film_ior, preInfo{X}.VdotH, thin_film_thickness, baseDielectricReflectance.coloredF0);
specularColoredFresnel = mix(specularColoredFresnel, thinFilmDielectricFresnel * specular_color, thin_film_weight * thinFilmIorScale);
#endif
Expand All @@ -73,7 +73,7 @@

#ifdef THIN_FILM
// Scale the thin film effect based on how different the IOR is from 1.0 (no thin film effect)
float thinFilmIorScale = clamp(2.0f * abs(thin_film_ior - 1.0f), 0.0f, 1.0f);
float thinFilmIorScale = clamp(2.0 * abs(thin_film_ior - 1.0), 0.0, 1.0);
vec3 thinFilmConductorFresnel = evalIridescence(thin_film_outside_ior, thin_film_ior, preInfo{X}.VdotH, thin_film_thickness, baseConductorReflectance.coloredF0);
coloredFresnel = mix(coloredFresnel, specular_weight * thinFilmIorScale * thinFilmConductorFresnel, thin_film_weight);
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,20 @@
vec3 dielectricIblColoredFresnel = dielectricIblFresnel * specular_color;
#ifdef THIN_FILM
// Scale the thin film effect based on how different the IOR is from 1.0 (no thin film effect)
float thinFilmIorScale = clamp(2.0f * abs(thin_film_ior - 1.0f), 0.0f, 1.0f);
float thinFilmIorScale = clamp(2.0 * abs(thin_film_ior - 1.0), 0.0, 1.0);
vec3 thinFilmDielectricFresnel = evalIridescence(thin_film_outside_ior, thin_film_ior, baseGeoInfo.NdotV, thin_film_thickness, baseDielectricReflectance.coloredF0);
// Desaturate the thin film fresnel based on thickness and angle - this brings the results much
// closer to path-tracing reference.
float thin_film_desaturation_scale = sqrt(thin_film_thickness * 0.001 * baseGeoInfo.NdotV);
thinFilmDielectricFresnel = mix(thinFilmDielectricFresnel, vec3(dot(thinFilmDielectricFresnel, vec3(0.3333))), thin_film_desaturation_scale);
dielectricIblColoredFresnel = mix(dielectricIblColoredFresnel, thinFilmDielectricFresnel * specular_color, thin_film_weight * thinFilmIorScale);
#endif

// Conductor IBL Fresnel
vec3 conductorIblFresnel = conductorIblFresnel(baseConductorReflectance, baseGeoInfo.NdotV, specular_roughness, baseGeoInfo.environmentBrdf);
#ifdef THIN_FILM
vec3 thinFilmConductorFresnel = specular_weight * evalIridescence(thin_film_outside_ior, thin_film_ior, baseGeoInfo.NdotV, thin_film_thickness, baseConductorReflectance.coloredF0);
thinFilmConductorFresnel = mix(thinFilmConductorFresnel, vec3(dot(thinFilmConductorFresnel, vec3(0.3333))), thin_film_desaturation_scale);
conductorIblFresnel = mix(conductorIblFresnel, thinFilmConductorFresnel, thin_film_weight * thinFilmIorScale);
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ geometry_coat_tangent = uniforms.vGeometryCoatTangent.rg;
#endif

#ifdef COAT_ROUGHNESS
coat_roughness *= coatRoughnessFromTexture.r;
#ifdef COAT_ROUGHNESS_FROM_GREEN_CHANNEL
coat_roughness *= coatRoughnessFromTexture.g;
#else
coat_roughness *= coatRoughnessFromTexture.r;
#endif
#endif

#if defined(GEOMETRY_COAT_TANGENT) && defined(COAT_ROUGHNESS_ANISOTROPY_FROM_TANGENT_TEXTURE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@ import type { Material } from "core/Materials/material";
import type { IMaterial, ITextureInfo } from "../glTFLoaderInterfaces";
import type { IGLTFLoaderExtension } from "../glTFLoaderExtension";
import { GLTFLoader } from "../glTFLoader";
import type {
IKHRMaterialsClearcoat,
IKHRMaterialsClearcoatDarkening,
IKHRMaterialsClearcoatIor,
IKHRMaterialsClearcoatColor,
IKHRMaterialsClearcoatAnisotropy,
} from "babylonjs-gltf2interface";
import type { IKHRMaterialsClearcoat } from "babylonjs-gltf2interface";
import { registerGLTFExtension, unregisterGLTFExtension } from "../glTFLoaderExtensionRegistry";
import { Color3 } from "core/Maths/math.color";

const NAME = "KHR_materials_clearcoat";

Expand Down Expand Up @@ -71,29 +64,6 @@ export class KHR_materials_clearcoat implements IGLTFLoaderExtension {
const promises = new Array<Promise<any>>();
promises.push(this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial));
promises.push(this._loadClearCoatPropertiesAsync(extensionContext, extension, babylonMaterial));

const adapter = this._loader._getOrCreateMaterialAdapter(babylonMaterial);
if (extension.extensions && extension.extensions.KHR_materials_clearcoat_darkening) {
const darkeningExtension = extension.extensions.KHR_materials_clearcoat_darkening as IKHRMaterialsClearcoatDarkening;
promises.push(this._loadClearCoatDarkeningPropertiesAsync(extensionContext, darkeningExtension, babylonMaterial));
}
if (extension.extensions && extension.extensions.KHR_materials_clearcoat_ior) {
const iorExtension = extension.extensions.KHR_materials_clearcoat_ior as IKHRMaterialsClearcoatIor;
let ior = 1.5;
if (iorExtension.clearcoatIor !== undefined) {
ior = iorExtension.clearcoatIor;
}
adapter.coatIor = ior;
}
if (extension.extensions && extension.extensions.KHR_materials_clearcoat_anisotropy) {
const anisotropyExtension = extension.extensions.KHR_materials_clearcoat_anisotropy as IKHRMaterialsClearcoatAnisotropy;
promises.push(this._loadClearCoatAnisotropyPropertiesAsync(extensionContext, anisotropyExtension, babylonMaterial));
}
if (extension.extensions && extension.extensions.KHR_materials_clearcoat_color) {
const colorExtension = extension.extensions.KHR_materials_clearcoat_color as IKHRMaterialsClearcoatColor;
promises.push(this._loadClearCoatColorPropertiesAsync(extensionContext, colorExtension, babylonMaterial));
}

await Promise.all(promises);
});
}
Expand Down Expand Up @@ -145,84 +115,6 @@ export class KHR_materials_clearcoat implements IGLTFLoaderExtension {
// eslint-disable-next-line github/no-then
return Promise.all(promises).then(() => {});
}

// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
private _loadClearCoatDarkeningPropertiesAsync(context: string, properties: IKHRMaterialsClearcoatDarkening, babylonMaterial: Material): Promise<void> {
const adapter = this._loader._getOrCreateMaterialAdapter(babylonMaterial);
const promises = new Array<Promise<any>>();

adapter.coatDarkening = properties.clearcoatDarkeningFactor !== undefined ? properties.clearcoatDarkeningFactor : 1;

if (properties.clearcoatDarkeningTexture) {
(properties.clearcoatDarkeningTexture as ITextureInfo).nonColorData = true;
promises.push(
this._loader.loadTextureInfoAsync(`${context}/clearcoatDarkeningTexture`, properties.clearcoatDarkeningTexture, (texture) => {
texture.name = `${babylonMaterial.name} (ClearCoat Darkening)`;
adapter.coatDarkeningTexture = texture;
})
);
}

// eslint-disable-next-line github/no-then
return Promise.all(promises).then(() => {});
}

// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
private _loadClearCoatColorPropertiesAsync(context: string, properties: IKHRMaterialsClearcoatColor, babylonMaterial: Material): Promise<void> {
const adapter = this._loader._getOrCreateMaterialAdapter(babylonMaterial);
const promises = new Array<Promise<any>>();
const colorFactor = Color3.White();
if (properties.clearcoatColorFactor !== undefined) {
colorFactor.fromArray(properties.clearcoatColorFactor);
}

adapter.coatColor = colorFactor;

if (properties.clearcoatColorTexture) {
promises.push(
this._loader.loadTextureInfoAsync(`${context}/clearcoatColorTexture`, properties.clearcoatColorTexture, (texture) => {
texture.name = `${babylonMaterial.name} (ClearCoat Color)`;
adapter.coatColorTexture = texture;
})
);
}

// eslint-disable-next-line github/no-then
return Promise.all(promises).then(() => {});
}

// eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
private _loadClearCoatAnisotropyPropertiesAsync(context: string, properties: IKHRMaterialsClearcoatAnisotropy, babylonMaterial: Material): Promise<void> {
const adapter = this._loader._getOrCreateMaterialAdapter(babylonMaterial);
const promises = new Array<Promise<any>>();

// Set non-texture properties immediately
const clearcoatAnisotropyWeight = properties.clearcoatAnisotropyStrength ?? 0;
const clearcoatAnisotropyAngle = properties.clearcoatAnisotropyRotation ?? 0;

adapter.coatRoughnessAnisotropy = clearcoatAnisotropyWeight;
adapter.geometryCoatTangentAngle = clearcoatAnisotropyAngle;

// Check if this is glTF-style anisotropy
const extensions = properties.extensions ?? {};
if (!extensions.EXT_materials_anisotropy_openpbr || !extensions.EXT_materials_anisotropy_openpbr.openPbrAnisotropyEnabled) {
adapter.configureGltfStyleAnisotropy(true);
}

// Load texture if present
if (properties.clearcoatAnisotropyTexture) {
(properties.clearcoatAnisotropyTexture as ITextureInfo).nonColorData = true;
promises.push(
this._loader.loadTextureInfoAsync(`${context}/clearcoatAnisotropyTexture`, properties.clearcoatAnisotropyTexture, (texture) => {
texture.name = `${babylonMaterial.name} (Clearcoat Anisotropy)`;
adapter.geometryCoatTangentTexture = texture;
})
);
}

// eslint-disable-next-line github/no-then
return Promise.all(promises).then(() => {});
}
}
unregisterGLTFExtension(NAME);
registerGLTFExtension(NAME, true, (loader) => new KHR_materials_clearcoat(loader));
Loading
Loading