Skip to content

Commit

Permalink
Add OpenPBR's base_weight material parameter (#16085)
Browse files Browse the repository at this point in the history
* Add Base Weight uniform parameter

* Add Base Weight texture

* Use Base Weight in the shader

* Add visualization test

* Hard code base_weight=1 in NME

* Fix typo

* Add code documentation

* Follow convention of multiplying the texture value by the uniform parameter

* Address review comments

* Document shading details

* Rename float vBaseWeight to baseWeight

* Fix conditional block

* Replace // comment with /* */ to avoid a likely preprocessor bug

It seems the preprocessor removes the entire line when it finds a // comment.
  • Loading branch information
virtualzavie authored Jan 24, 2025
1 parent a453499 commit 7fa12bb
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -974,10 +974,11 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock {
,vec4${state.fSuffix}(1.)
,vec2${state.fSuffix}(1., 1.)
#endif
,1. /* Base Weight */
#ifdef OPACITY
,vec4${state.fSuffix}(${opacity})
,vec2${state.fSuffix}(1., 1.)
#endif
#endif
);
${state._declareLocalVar("surfaceAlbedo", NodeMaterialBlockConnectionPointTypes.Vector3)} = albedoOpacityOut.surfaceAlbedo;
Expand Down
59 changes: 59 additions & 0 deletions packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export class PBRMaterialDefines extends MaterialDefines implements IImageProcess
public ALBEDODIRECTUV = 0;
public VERTEXCOLOR = false;

public BASEWEIGHT = false;
public BASEWEIGHTDIRECTUV = 0;

public BAKED_VERTEX_ANIMATION_TEXTURE = false;

public AMBIENT = false;
Expand Down Expand Up @@ -418,6 +421,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
*/
public _albedoTexture: Nullable<BaseTexture> = null;

/**
* OpenPBR Base Weight (multiplier to the diffuse and metal lobes).
* @internal
*/
public _baseWeightTexture: Nullable<BaseTexture> = null;

/**
* AKA Occlusion Texture in other nomenclature.
* @internal
Expand Down Expand Up @@ -560,6 +569,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
*/
public _albedoColor = new Color3(1, 1, 1);

/**
* OpenPBR Base Weight (multiplier to the diffuse and metal lobes).
* @internal
*/
public _baseWeight = 1;

/**
* AKA Specular Color in other nomenclature.
* @internal
Expand Down Expand Up @@ -1112,6 +1127,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
}
}

if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {
if (!this._baseWeightTexture.isReadyOrNotBlocking()) {
return false;
}
}

if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
if (!this._ambientTexture.isReadyOrNotBlocking()) {
return false;
Expand Down Expand Up @@ -1423,6 +1444,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
"vLightsType",
"vAmbientColor",
"vAlbedoColor",
"baseWeight",
"vReflectivityColor",
"vMetallicReflectanceFactors",
"vEmissiveColor",
Expand All @@ -1432,6 +1454,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
"vFogColor",
"pointSize",
"vAlbedoInfos",
"vBaseWeightInfos",
"vAmbientInfos",
"vOpacityInfos",
"vReflectionInfos",
Expand All @@ -1447,6 +1470,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
"vLightmapInfos",
"mBones",
"albedoMatrix",
"baseWeightMatrix",
"ambientMatrix",
"opacityMatrix",
"reflectionMatrix",
Expand Down Expand Up @@ -1488,6 +1512,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {

const samplers = [
"albedoSampler",
"baseWeightSampler",
"reflectivitySampler",
"ambientSampler",
"emissiveSampler",
Expand Down Expand Up @@ -1624,6 +1649,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
}
if (scene.texturesEnabled) {
defines.ALBEDODIRECTUV = 0;
defines.BASEWEIGHTDIRECTUV = 0;
defines.AMBIENTDIRECTUV = 0;
defines.OPACITYDIRECTUV = 0;
defines.EMISSIVEDIRECTUV = 0;
Expand All @@ -1645,6 +1671,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
defines.ALBEDO = false;
}

if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {
PrepareDefinesForMergedUV(this._baseWeightTexture, defines, "BASEWEIGHT");
} else {
defines.BASEWEIGHT = false;
}

if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
PrepareDefinesForMergedUV(this._ambientTexture, defines, "AMBIENT");
defines.AMBIENTINGRAYSCALE = this._useAmbientInGrayScale;
Expand Down Expand Up @@ -1993,6 +2025,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
// Order is important !
const ubo = this._uniformBuffer;
ubo.addUniform("vAlbedoInfos", 2);
ubo.addUniform("vBaseWeightInfos", 2);
ubo.addUniform("vAmbientInfos", 4);
ubo.addUniform("vOpacityInfos", 2);
ubo.addUniform("vEmissiveInfos", 2);
Expand All @@ -2005,6 +2038,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
ubo.addUniform("vReflectionSize", 3);
ubo.addUniform("vBumpInfos", 3);
ubo.addUniform("albedoMatrix", 16);
ubo.addUniform("baseWeightMatrix", 16);
ubo.addUniform("ambientMatrix", 16);
ubo.addUniform("opacityMatrix", 16);
ubo.addUniform("emissiveMatrix", 16);
Expand All @@ -2017,6 +2051,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {

ubo.addUniform("vReflectionColor", 3);
ubo.addUniform("vAlbedoColor", 4);
ubo.addUniform("baseWeight", 1);
ubo.addUniform("vLightingIntensity", 4);

ubo.addUniform("vReflectionMicrosurfaceInfos", 3);
Expand Down Expand Up @@ -2119,6 +2154,11 @@ export abstract class PBRBaseMaterial extends PushMaterial {
BindTextureMatrix(this._albedoTexture, ubo, "albedo");
}

if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {
ubo.updateFloat2("vBaseWeightInfos", this._baseWeightTexture.coordinatesIndex, this._baseWeightTexture.level);
BindTextureMatrix(this._baseWeightTexture, ubo, "baseWeight");
}

if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
ubo.updateFloat4(
"vAmbientInfos",
Expand Down Expand Up @@ -2280,6 +2320,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
ubo.updateColor4("vAlbedoColor", this._albedoColor, this.alpha);
}

ubo.updateFloat("baseWeight", this._baseWeight);

// Misc
this._lightingInfos.x = this._directIntensity;
this._lightingInfos.y = this._emissiveIntensity;
Expand All @@ -2302,6 +2344,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
ubo.setTexture("albedoSampler", this._albedoTexture);
}

if (this._baseWeightTexture && MaterialFlags.BaseWeightTextureEnabled) {
ubo.setTexture("baseWeightSampler", this._baseWeightTexture);
}

if (this._ambientTexture && MaterialFlags.AmbientTextureEnabled) {
ubo.setTexture("ambientSampler", this._ambientTexture);
}
Expand Down Expand Up @@ -2436,6 +2482,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
results.push(this._albedoTexture);
}

if (this._baseWeightTexture && this._baseWeightTexture.animations && this._baseWeightTexture.animations.length > 0) {
results.push(this._baseWeightTexture);
}

if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
results.push(this._ambientTexture);
}
Expand Down Expand Up @@ -2504,6 +2554,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
activeTextures.push(this._albedoTexture);
}

if (this._baseWeightTexture) {
activeTextures.push(this._baseWeightTexture);
}

if (this._ambientTexture) {
activeTextures.push(this._ambientTexture);
}
Expand Down Expand Up @@ -2565,6 +2619,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
return true;
}

if (this._baseWeightTexture === texture) {
return true;
}

if (this._ambientTexture === texture) {
return true;
}
Expand Down Expand Up @@ -2644,6 +2702,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
}

this._albedoTexture?.dispose();
this._baseWeightTexture?.dispose();
this._ambientTexture?.dispose();
this._opacityTexture?.dispose();
this._reflectionTexture?.dispose();
Expand Down
14 changes: 14 additions & 0 deletions packages/dev/core/src/Materials/PBR/pbrMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ export class PBRMaterial extends PBRBaseMaterial {
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public albedoTexture: Nullable<BaseTexture>;

/**
* OpenPBR Base Weight (multiplier to the diffuse and metal lobes).
*/
@serializeAsTexture()
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public baseWeightTexture: Nullable<BaseTexture>;

/**
* AKA Occlusion Texture in other nomenclature.
*/
Expand Down Expand Up @@ -270,6 +277,13 @@ export class PBRMaterial extends PBRBaseMaterial {
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public albedoColor = new Color3(1, 1, 1);

/**
* OpenPBR Base Weight (multiplier to the diffuse and metal lobes).
*/
@serialize("baseWeight")
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public baseWeight = 1;

/**
* AKA Specular Color in other nomenclature.
*/
Expand Down
16 changes: 16 additions & 0 deletions packages/dev/core/src/Materials/materialFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@ export class MaterialFlags {
AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);
}

private static _BaseWeightTextureEnabled = true;
/**
* Is the OpenPBR Base Weight texture enabled in the application.
*/
public static get BaseWeightTextureEnabled(): boolean {
return this._BaseWeightTextureEnabled;
}
public static set BaseWeightTextureEnabled(value: boolean) {
if (this._BaseWeightTextureEnabled === value) {
return;
}

this._BaseWeightTextureEnabled = value;
AbstractEngine.MarkAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);
}

private static _DetailTextureEnabled = true;
/**
* Are detail textures enabled in the application.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ albedoOpacityOutParams albedoOpacityBlock(
#ifdef ALBEDO
,in vec4 albedoTexture
,in vec2 albedoInfos
#endif
, in float baseWeight
#ifdef BASEWEIGHT
, in vec4 baseWeightTexture
, in vec2 vBaseWeightInfos
#endif
#ifdef OPACITY
,in vec4 opacityMap
Expand All @@ -22,7 +27,7 @@ albedoOpacityOutParams albedoOpacityBlock(
#ifdef DECAL
,in vec4 decalColor
,in vec4 vDecalInfos
#endif
#endif
)
{
albedoOpacityOutParams outParams;
Expand Down Expand Up @@ -63,6 +68,17 @@ albedoOpacityOutParams albedoOpacityBlock(

#define CUSTOM_FRAGMENT_UPDATE_ALBEDO

// According to OpenPBR:
// - for metals, base_weight is a factor to the base_color (F0, thus surfaceAlbedo in
// Babylons.js).
// - for dielectrics, base_weight is a factor to the diffuse BRDF (i.e. it should be
// applied in computeDiffuseLighting), but with the diffuse model *currently* used
// in Babylon.js, factoring it into the surfaceAlbedo is equivalent.
surfaceAlbedo *= baseWeight;
#ifdef BASEWEIGHT
surfaceAlbedo *= baseWeightTexture.r;
#endif

// _____________________________ Alpha Information _______________________________
#ifdef OPACITY
#ifdef OPACITYRGB
Expand All @@ -79,7 +95,7 @@ albedoOpacityOutParams albedoOpacityBlock(
#endif

#if !defined(SS_LINKREFRACTIONTOTRANSPARENCY) && !defined(ALPHAFRESNEL)
#ifdef ALPHATEST
#ifdef ALPHATEST
#if DEBUGMODE != 88
if (alpha < ALPHATESTVALUE)
discard;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ uniform vec4 vEyePosition;

uniform vec3 vReflectionColor;
uniform vec4 vAlbedoColor;
uniform float baseWeight;

// CUSTOM CONTROLS
uniform vec4 vLightingIntensity;
Expand All @@ -19,6 +20,10 @@ uniform vec3 vAmbientColor;
uniform vec2 vAlbedoInfos;
#endif

#ifdef BASEWEIGHT
uniform vec2 vBaseWeightInfos;
#endif

#ifdef AMBIENT
uniform vec4 vAmbientInfos;
#endif
Expand Down Expand Up @@ -65,14 +70,14 @@ uniform mat4 view;

#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)
uniform vec3 vReflectionPosition;
uniform vec3 vReflectionSize;
uniform vec3 vReflectionSize;
#endif
#endif

// Refraction
#if defined(SS_REFRACTION) && defined(SS_USE_LOCAL_REFRACTIONMAP_CUBIC)
uniform vec3 vRefractionPosition;
uniform vec3 vRefractionSize;
uniform vec3 vRefractionSize;
#endif

// Clear Coat
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include<samplerFragmentDeclaration>(_DEFINENAME_,ALBEDO,_VARYINGNAME_,Albedo,_SAMPLERNAME_,albedo)
#include<samplerFragmentDeclaration>(_DEFINENAME_,BASEWEIGHT,_VARYINGNAME_,BaseWeight,_SAMPLERNAME_,baseWeight)
#include<samplerFragmentDeclaration>(_DEFINENAME_,AMBIENT,_VARYINGNAME_,Ambient,_SAMPLERNAME_,ambient)
#include<samplerFragmentDeclaration>(_DEFINENAME_,OPACITY,_VARYINGNAME_,Opacity,_SAMPLERNAME_,opacity)
#include<samplerFragmentDeclaration>(_DEFINENAME_,EMISSIVE,_VARYINGNAME_,Emissive,_SAMPLERNAME_,emissive)
Expand Down Expand Up @@ -42,7 +43,7 @@
#define sampleReflection(s, c) textureCube(s, c)

uniform samplerCube reflectionSampler;

#ifdef LODBASEDMICROSFURACE
#define sampleReflectionLod(s, c, l) textureCubeLodEXT(s, c, l)
#else
Expand Down Expand Up @@ -93,7 +94,7 @@
#ifdef SS_REFRACTION
#ifdef SS_REFRACTIONMAP_3D
#define sampleRefraction(s, c) textureCube(s, c)

uniform samplerCube refractionSampler;

#ifdef LODBASEDMICROSFURACE
Expand All @@ -104,7 +105,7 @@
#endif
#else
#define sampleRefraction(s, c) texture2D(s, c)

uniform sampler2D refractionSampler;

#ifdef LODBASEDMICROSFURACE
Expand Down
Loading

0 comments on commit 7fa12bb

Please sign in to comment.