Skip to content

Commit 58ea859

Browse files
author
Mike Bond
committed
Updates for coat darkening
1 parent b8718d8 commit 58ea859

File tree

9 files changed

+31
-18
lines changed

9 files changed

+31
-18
lines changed

packages/dev/core/src/Materials/PBR/openPbrMaterial.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
622622
public coatDarkening: number;
623623
@addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatDarkening")
624624
// eslint-disable-next-line @typescript-eslint/no-unused-vars
625-
private _coatDarkening: Property<number> = new Property<number>("coat_darkening", 0.0, "vCoatDarkening", 1, 0);
625+
private _coatDarkening: Property<number> = new Property<number>("coat_darkening", 1.0, "vCoatDarkening", 1, 0);
626626

627627
/**
628628
* Defines the amount that interreflections within the coat allow the underlying surface
@@ -1344,6 +1344,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase {
13441344
this._coatRoughness;
13451345
this._coatRoughnessTexture;
13461346
this._coatIor;
1347+
this._coatDarkening;
1348+
this._coatDarkeningTexture;
13471349
this._geometryNormalTexture;
13481350
this._geometryCoatNormalTexture;
13491351
this._geometryOpacity;

packages/dev/core/src/Shaders/ShadersInclude/openpbrEnvironmentLighting.fx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
// This uses the geometric series for infinite reflections:
125125
// T = (1-R) / (1 + R + R² + R³ + ...) = (1-R) / (1/(1-R)) = (1-R)²
126126
float effectiveReflectance = averageReflectance * coat_weight;
127-
float transmission = (1.0 - effectiveReflectance) / (1.0 + effectiveReflectance);
127+
float transmission = (1.0 - effectiveReflectance) * (1.0 - effectiveReflectance);
128128
coatAbsorption = coat_color * mix(1.0, transmission, coat_darkening);
129129
}
130130

packages/dev/core/src/Shaders/ShadersInclude/openpbrIblFunctions.fx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,10 @@
205205
vec3 conductorIblFresnel(in ReflectanceParams reflectance, in float NdotV, in float roughness, in vec3 environmentBrdf)
206206
{
207207
#if (CONDUCTOR_SPECULAR_MODEL == CONDUCTOR_SPECULAR_MODEL_OPENPBR)
208-
// For OpenPBR, we use a different specular lobe for metallic materials and then blend based on metalness. However,
209-
// to do this correctly, we really need reflectivityOut to contain separate F0 and F90 values for purely dielectric
210-
// and purely metal. Instead, the values are already a mix of dielectric and metallic values.
211-
// So, for intermediate metallic values, the result isn't 100% correct but it seems to work well enough in practice.
212-
// Because specular weight in OpenPBR removes the specular lobe entirely for metals, we do need the actual dielectric
213-
// F0 value to pickup the weight from the dielectric lobe.
214-
return getF82Specular(NdotV, reflectance.coloredF0, reflectance.coloredF90, roughness);
215-
208+
// This is an empirical hack to modify the F0 albedo based on roughness. It's not based on any paper
209+
// or anything. Just trying to match results of rough metals in a pathtracer.
210+
vec3 albedoF0 = mix(reflectance.coloredF0, pow(reflectance.coloredF0, vec3(1.4)), roughness);
211+
return getF82Specular(NdotV, albedoF0, reflectance.coloredF90, roughness);
216212
#else
217213
return getReflectanceFromBRDFLookup(reflectance.coloredF0, reflectance.coloredF90, environmentBrdf);
218214
#endif

packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.fx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
// This uses the geometric series for infinite reflections:
127127
// T = (1-R) / (1 + R + R² + R³ + ...) = (1-R) / (1/(1-R)) = (1-R)²
128128
let effectiveReflectance = averageReflectance * coat_weight;
129-
let transmission = (1.0f - effectiveReflectance) / (1.0f + effectiveReflectance);
129+
let transmission = (1.0f - effectiveReflectance) * (1.0f - effectiveReflectance);
130130
coatAbsorption = coat_color * mix(1.0f, transmission, coat_darkening);
131131
}
132132

packages/dev/core/src/ShadersWGSL/ShadersInclude/openpbrIblFunctions.fx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,10 @@
196196
fn conductorIblFresnel(reflectance: ReflectanceParams, NdotV: f32, roughness: f32, environmentBrdf: vec3f) -> vec3f
197197
{
198198
#if (CONDUCTOR_SPECULAR_MODEL == CONDUCTOR_SPECULAR_MODEL_OPENPBR)
199-
// For OpenPBR, we use a different specular lobe for metallic materials and then blend based on metalness. However,
200-
// to do this correctly, we really need reflectanceOut to contain separate F0 and F90 values for purely dielectric
201-
// and purely metal. Instead, the values are already a mix of dielectric and metallic values.
202-
// So, for intermediate metallic values, the result isn't 100% correct but it seems to work well enough in practice.
203-
// Because specular weight in OpenPBR removes the specular lobe entirely for metals, we do need the actual dielectric
204-
// F0 value to pickup the weight from the dielectric lobe.
205-
return getF82Specular(NdotV, reflectance.coloredF0, reflectance.coloredF90, roughness);
199+
// This is an empirical hack to modify the F0 albedo based on roughness. It's not based on any paper
200+
// or anything. Just trying to match results of rough metals in a pathtracer.
201+
let albedoF0: vec3f = mix(reflectance.coloredF0, pow(reflectance.coloredF0, vec3f(1.4f)), roughness);
202+
return getF82Specular(NdotV, albedoF0, reflectance.coloredF90, roughness);
206203
#else
207204
return getReflectanceFromBRDFLookup(reflectance.coloredF0, reflectance.coloredF90, environmentBrdf);
208205
#endif

packages/dev/inspector/src/components/actionTabs/tabs/propertyGrids/materials/openpbrMaterialPropertyGridComponent.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,14 @@ export class OpenPBRMaterialPropertyGridComponent extends React.Component<IOpenP
450450
step={0.01}
451451
onPropertyChangedObservable={this.props.onPropertyChangedObservable}
452452
/>
453+
<TextureLinkLineComponent
454+
label="Darkening Texture"
455+
texture={material.coatDarkeningTexture}
456+
propertyName="coatDarkeningTexture"
457+
material={material}
458+
onSelectionChangedObservable={this.props.onSelectionChangedObservable}
459+
onDebugSelectionChangeObservable={this._onDebugSelectionChangeObservable}
460+
/>
453461
</LineContainerComponent>
454462
<LineContainerComponent title="EMISSION" selection={this.props.globalState}>
455463
<Color3LineComponent
37.5 KB
Loading
113 KB
Loading

packages/tools/tests/test/visualization/config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2812,10 +2812,20 @@
28122812
"playgroundId": "#GRQHVV#46",
28132813
"excludedEngines": ["webgl1"]
28142814
},
2815+
{
2816+
"title": "OpenPBR IBL Coat Darkening vs Coat IOR",
2817+
"playgroundId": "#GRQHVV#48",
2818+
"excludedEngines": ["webgl1"]
2819+
},
28152820
{
28162821
"title": "OpenPBR Analytic Lights Coat Darkening",
28172822
"playgroundId": "#GRQHVV#47",
28182823
"excludedEngines": ["webgl1"]
2824+
},
2825+
{
2826+
"title": "OpenPBR Analytic Lights Coat Darkening vs Coat IOR",
2827+
"playgroundId": "#GRQHVV#49",
2828+
"excludedEngines": ["webgl1"]
28192829
}
28202830
]
28212831
}

0 commit comments

Comments
 (0)