Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion packages/dev/core/src/Materials/PBR/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export * from "./pbrBRDFConfiguration";
export * from "./pbrClearCoatConfiguration";
export * from "./pbrIridescenceConfiguration";
export * from "./pbrMaterial";
export * from "./openPbrMaterial";
export * from "./openpbrMaterial";
export * from "./pbrMetallicRoughnessMaterial";
export * from "./pbrSpecularGlossinessMaterial";
export * from "./pbrSheenConfiguration";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { serialize, expandToProperty, addAccessorsForMaterialProperty } from "../../Misc/decorators";
import { GetEnvironmentBRDFTexture } from "../../Misc/brdfTextureTools";
import { GetEnvironmentBRDFTexture, GetEnvironmentFuzzBRDFTexture } from "../../Misc/brdfTextureTools";
import type { Nullable } from "../../types";
import { Scene } from "../../scene";
import type { Color4 } from "../../Maths/math.color";
import { Color3 } from "../../Maths/math.color";
import { ImageProcessingConfiguration } from "../imageProcessingConfiguration";
import type { BaseTexture } from "../../Materials/Textures/baseTexture";
import { Texture } from "../../Materials/Textures/texture";
import { Texture } from "../Textures/texture";
import { RegisterClass } from "../../Misc/typeStore";
import { Material } from "../material";
import { SerializationHelper } from "../../Misc/decorators.serialization";
Expand Down Expand Up @@ -236,6 +236,7 @@ export class OpenPBRMaterialDefines extends ImageProcessingDefinesMixin(OpenPBRM

public ENVIRONMENTBRDF = false;
public ENVIRONMENTBRDF_RGBD = false;
public FUZZENVIRONMENTBRDF = false;

public NORMAL = false;
public TANGENT = false;
Expand All @@ -244,12 +245,43 @@ export class OpenPBRMaterialDefines extends ImageProcessingDefinesMixin(OpenPBRM
public PARALLAX_RHS = false;
public PARALLAXOCCLUSION = false;
public NORMALXYSCALE = true;
public ANISOTROPIC = false; // Enables anisotropic logic. Still needed because it's used in pbrHelperFunctions
public ANISOTROPIC_OPENPBR = true; // Tells the shader to use OpenPBR's anisotropic roughness remapping
public ANISOTROPIC_BASE = false; // Tells the shader to apply anisotropy to the base layer
public ANISOTROPIC_COAT = false; // Tells the shader to apply anisotropy to the coat layer
public THIN_FILM = false; // Enables thin film layer
public IRIDESCENCE = false; // Enables iridescence layer
/**
* Enables anisotropic logic. Still needed because it's used in pbrHelperFunctions
*/
public ANISOTROPIC = false;
/**
* Tells the shader to use OpenPBR's anisotropic roughness remapping
*/
public ANISOTROPIC_OPENPBR = true;
/**
* Tells the shader to apply anisotropy to the base layer
*/
public ANISOTROPIC_BASE = false;
/**
* Tells the shader to apply anisotropy to the coat layer
*/
public ANISOTROPIC_COAT = false;

/**
* Number of samples to use for the fuzz IBL lighting calculations
*/
public FUZZ_IBL_SAMPLES = 6;

/**
* Tells the shader to enable the fuzz layer
*/
public FUZZ = false;

/**
* Tells the shader to enable the thin film layer
*/
public THIN_FILM = false;

/**
* Tells the shader to enable the legacy iridescence code
* Iridescence is the name of thin film interference in the PBR material.
*/
public IRIDESCENCE = false;

public REFLECTION = false;
public REFLECTIONMAP_3D = false;
Expand Down Expand Up @@ -665,6 +697,60 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
*/
public useCoatRoughnessFromWeightTexture: boolean = false;

/**
* Defines the weight of the fuzz layer on the surface.
* See OpenPBR's specs for fuzz_weight
*/
public fuzzWeight: number;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzWeight")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzWeight: Property<number> = new Property<number>("fuzz_weight", 0.0, "vFuzzWeight", 1, 0);

/**
* Weight texture of the fuzz layer.
* See OpenPBR's specs for fuzz_weight
*/
public fuzzWeightTexture: Nullable<BaseTexture>;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzWeightTexture")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzWeightTexture: Sampler = new Sampler("fuzz_weight", "fuzzWeight", "FUZZ_WEIGHT");

/**
* Defines the color of the fuzz layer on the surface.
* See OpenPBR's specs for fuzz_color
*/
public fuzzColor: Color3;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzColor")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzColor: Property<Color3> = new Property<Color3>("fuzz_color", Color3.White(), "vFuzzColor", 3, 0);

/**
* Color texture of the fuzz layer.
* See OpenPBR's specs for fuzz_color
*/
public fuzzColorTexture: Nullable<BaseTexture>;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzColorTexture")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzColorTexture: Sampler = new Sampler("fuzz_color", "fuzzColor", "FUZZ_COLOR");

/**
* Defines the roughness of the fuzz layer on the surface.
* See OpenPBR's specs for fuzz_roughness
*/
public fuzzRoughness: number;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzRoughness")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzRoughness: Property<number> = new Property<number>("fuzz_roughness", 0.5, "vFuzzRoughness", 1, 0);

/**
* Roughness texture of the fuzz layer.
* See OpenPBR's specs for fuzz_roughness
*/
public fuzzRoughnessTexture: Nullable<BaseTexture>;
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzRoughnessTexture")
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _fuzzRoughnessTexture: Sampler = new Sampler("fuzz_roughness", "fuzzRoughness", "FUZZ_ROUGHNESS");

/**
* Defines the normal of the material's geometry.
* See OpenPBR's specs for geometry_normal
Expand Down Expand Up @@ -1291,6 +1377,14 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
*/
public _environmentBRDFTexture: Nullable<BaseTexture> = null;

/**
* Specifies the environment BRDF texture used to compute the scale and offset roughness values
* from cos theta and roughness for the fuzz layer:
* https://github.com/tizian/ltc-sheen?tab=readme-ov-file
* @internal
*/
public _environmentFuzzBRDFTexture: Nullable<BaseTexture> = null;

/**
* Force the shader to compute irradiance in the fragment shader in order to take normal mapping into account.
* @internal
Expand Down Expand Up @@ -1321,6 +1415,19 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);
}

private _fuzzSampleNumber: number = 4;

/**
* The number of samples used to compute the fuzz IBL lighting.
*/
public get fuzzSampleNumber(): number {
return this._fuzzSampleNumber;
}
public set fuzzSampleNumber(n: number) {
this._fuzzSampleNumber = n;
this.markAsDirty(Constants.MATERIAL_TextureDirtyFlag);
}

/**
* Can this material render to several textures at once
*/
Expand Down Expand Up @@ -1441,6 +1548,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
};

this._environmentBRDFTexture = GetEnvironmentBRDFTexture(this.getScene());
this._environmentFuzzBRDFTexture = GetEnvironmentFuzzBRDFTexture(this.getScene());
this.prePassConfiguration = new PrePassConfiguration();

// Build the internal property list that can be used to generate and update the uniform buffer
Expand Down Expand Up @@ -1513,6 +1621,12 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
this._coatIor;
this._coatDarkening;
this._coatDarkeningTexture;
this._fuzzWeight;
this._fuzzWeightTexture;
this._fuzzColor;
this._fuzzColorTexture;
this._fuzzRoughness;
this._fuzzRoughnessTexture;
this._geometryNormalTexture;
this._geometryTangent;
this._geometryTangentTexture;
Expand Down Expand Up @@ -1763,6 +1877,13 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
}
}

if (this._environmentFuzzBRDFTexture && MaterialFlags.ReflectionTextureEnabled) {
// This is blocking.
if (!this._environmentFuzzBRDFTexture.isReady()) {
return false;
}
}

if (OpenPBRMaterial._noiseTextures[scene.uniqueId]) {
if (!OpenPBRMaterial._noiseTextures[scene.uniqueId].isReady()) {
return false;
Expand Down Expand Up @@ -2005,7 +2126,11 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
ubo.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
}

if (defines.ANISOTROPIC) {
if (defines.FUZZENVIRONMENTBRDF) {
ubo.setTexture("environmentFuzzBrdfSampler", this._environmentFuzzBRDFTexture);
}

if (defines.ANISOTROPIC || defines.FUZZ) {
ubo.setTexture("blueNoiseSampler", OpenPBRMaterial._noiseTextures[this.getScene().uniqueId]);
}
}
Expand Down Expand Up @@ -2152,6 +2277,9 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
if (this._environmentBRDFTexture && this.getScene().environmentBRDFTexture !== this._environmentBRDFTexture) {
this._environmentBRDFTexture.dispose();
}
if (this._environmentFuzzBRDFTexture && this.getScene().environmentFuzzBRDFTexture !== this._environmentFuzzBRDFTexture) {
this._environmentFuzzBRDFTexture.dispose();
}

// Loop through samplers and dispose the textures
for (const key in this._samplersList) {
Expand Down Expand Up @@ -2335,6 +2463,10 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
"areaLightsLTC2Sampler",
];

if (defines.FUZZENVIRONMENTBRDF) {
samplers.push("environmentFuzzBrdfSampler");
}

for (const key in this._samplersList) {
const sampler = this._samplersList[key];
samplers.push(sampler.samplerName);
Expand Down Expand Up @@ -2516,6 +2648,12 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
defines.ENVIRONMENTBRDF_RGBD = false;
}

if (this._environmentFuzzBRDFTexture) {
defines.FUZZENVIRONMENTBRDF = true;
} else {
defines.FUZZENVIRONMENTBRDF = false;
}

if (this._shouldUseAlphaFromBaseColorTexture()) {
defines.ALPHA_FROM_BASE_COLOR_TEXTURE = true;
} else {
Expand Down Expand Up @@ -2590,6 +2728,20 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
defines.THIN_FILM = this.thinFilmWeight > 0.0;
defines.IRIDESCENCE = this.thinFilmWeight > 0.0;

defines.FUZZ = this.fuzzWeight > 0 && MaterialFlags.ReflectionTextureEnabled;
if (defines.FUZZ) {
if (!mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
defines._needUVs = true;
defines.MAINUV1 = true;
}
this._environmentFuzzBRDFTexture = GetEnvironmentFuzzBRDFTexture(this.getScene());
defines.FUZZ_IBL_SAMPLES = this.fuzzSampleNumber;
} else {
this._environmentFuzzBRDFTexture = null;
defines.FUZZENVIRONMENTBRDF = false;
defines.FUZZ_IBL_SAMPLES = 0;
}

// Misc.
if (defines._areMiscDirty) {
PrepareDefinesForMisc(
Expand Down
54 changes: 41 additions & 13 deletions packages/dev/core/src/Misc/brdfTextureTools.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { expandToProperty, serialize } from "core/Misc/decorators";
import { RegisterClass } from "core/Misc/typeStore";

import { ShaderLanguage } from "core/Materials/shaderLanguage";
import { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
import { OpenPBRMaterial } from "core/Materials/PBR/openpbrMaterial";
/**
* @internal
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import type { Material } from "core/Materials/material";
import { Observable } from "core/Misc/observable";
import "../geometryBufferRendererSceneComponent";
import "../iblCdfGeneratorSceneComponent";
import { OpenPBRMaterial } from "core/Materials/PBR/openPbrMaterial";
import { OpenPBRMaterial } from "core/Materials/PBR/openpbrMaterial";

interface IIblShadowsSettings {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/core/src/Rendering/geometryBufferRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { BindMorphTargetParameters, BindSceneUniformBuffer, PrepareDefinesAndAtt

import "../Engines/Extensions/engine.multiRender";
import { ShaderLanguage } from "core/Materials/shaderLanguage";
import type { OpenPBRMaterial } from "../Materials/PBR/openPbrMaterial";
import type { OpenPBRMaterial } from "../Materials/PBR/openpbrMaterial";

/** @internal */
interface ISavedTransformationMatrix {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ vec2 geometry_tangent = vec2(1.0, 0.0);
#endif
#endif

#ifdef ANISOTROPIC
#if defined(ANISOTROPIC) || defined(FUZZ)
vec3 noise = texture2D(blueNoiseSampler, gl_FragCoord.xy / 256.0).xyz;
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
vec3 slab_coat = vec3(0., 0., 0.);
float coatFresnel = 0.0;
vec3 slab_fuzz = vec3(0., 0., 0.);
float fuzzFresnel = 0.0;

// Diffuse Lobe
#ifdef HEMILIGHT{X}
Expand All @@ -26,6 +27,11 @@

numLights += 1.0;

#ifdef FUZZ
float fuzzNdotH = max(dot(fuzzNormalW, preInfo{X}.H), 0.0);
vec3 fuzzBrdf = getFuzzBRDFLookup(fuzzNdotH, sqrt(fuzz_roughness));
#endif

// Specular Lobe
#if AREALIGHT{X}
slab_glossy = computeAreaSpecularLighting(preInfo{X}, light{X}.vLightSpecular.rgb, baseConductorReflectance.F0, baseConductorReflectance.F90);
Expand Down Expand Up @@ -134,12 +140,22 @@
coatAbsorption = mix(vec3(1.0), colored_transmission * darkened_transmission, coat_weight);
}

#ifdef FUZZ
fuzzFresnel = fuzzBrdf.z;
vec3 fuzzNormalW = mix(normalW, coatNormalW, coat_weight);
float fuzzNdotV = max(dot(fuzzNormalW, viewDirectionW.xyz), 0.0);
float fuzzNdotL = max(dot(fuzzNormalW, preInfo{X}.L), 0.0);
slab_fuzz = lightColor{X}.rgb * preInfo{X}.attenuation * evalFuzz(preInfo{X}.L, fuzzNdotL, fuzzNdotV, fuzzTangent, fuzzBitangent, fuzzBrdf);
#else
vec3 fuzz_color = vec3(0.0);
#endif

slab_diffuse *= base_color.rgb;
vec3 material_opaque_base = mix(slab_diffuse, slab_subsurface, subsurface_weight);
vec3 material_dielectric_base = mix(material_opaque_base, slab_translucent, transmission_weight);
vec3 material_dielectric_gloss = material_dielectric_base * (1.0 - specularFresnel) + slab_glossy * specularColoredFresnel;
vec3 material_base_substrate = mix(material_dielectric_gloss, slab_metal, base_metalness);
vec3 material_coated_base = layer(material_base_substrate, slab_coat, coatFresnel, coatAbsorption, vec3(1.0));
material_surface_direct += mix(material_coated_base, slab_fuzz, fuzz_weight);
material_surface_direct += layer(material_coated_base, slab_fuzz, fuzzFresnel * fuzz_weight, vec3(1.0), fuzz_color);
}
#endif
Loading