Skip to content

Commit 6342bfc

Browse files
authored
Improve IBLSheenBRDF approximation accuracy (#32397)
1 parent 3a84165 commit 6342bfc

File tree

4 files changed

+7
-14
lines changed

4 files changed

+7
-14
lines changed
298 Bytes
Loading
124 Bytes
Loading

src/nodes/functions/PhysicalLightingModel.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { diffuseColor, diffuseContribution, specularColor, specularColorBlended,
1212
import { normalView, clearcoatNormalView, normalWorld } from '../accessors/Normal.js';
1313
import { positionViewDirection, positionView, positionWorld } from '../accessors/Position.js';
1414
import { Fn, float, vec2, vec3, vec4, mat3, If } from '../tsl/TSLBase.js';
15-
import { mix, normalize, refract, length, clamp, log2, log, exp, smoothstep, inverseSqrt } from '../math/MathNode.js';
15+
import { mix, normalize, refract, length, clamp, log2, log, exp, smoothstep } from '../math/MathNode.js';
1616
import { div } from '../math/OperatorNode.js';
1717
import { cameraPosition, cameraProjectionMatrix, cameraViewMatrix } from '../accessors/Camera.js';
1818
import { modelWorldMatrix } from '../accessors/ModelNode.js';
@@ -313,21 +313,14 @@ const evalIridescence = /*@__PURE__*/ Fn( ( { outsideIOR, eta2, cosTheta1, thinF
313313

314314
// This is a curve-fit approximation to the "Charlie sheen" BRDF integrated over the hemisphere from
315315
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF".
316-
// The low roughness fit (< 0.25) uses an inversesqrt/log model to accurately capture the sharp peak.
317316
const IBLSheenBRDF = /*@__PURE__*/ Fn( ( { normal, viewDir, roughness } ) => {
318317

319318
const dotNV = normal.dot( viewDir ).saturate();
320319
const r2 = roughness.mul( roughness );
320+
const rInv = roughness.add( 0.1 ).reciprocal();
321321

322-
const a = roughness.lessThan( 0.25 ).select(
323-
inverseSqrt( roughness ).mul( - 1.57 ),
324-
r2.mul( - 3.33 ).add( roughness.mul( 6.27 ) ).sub( 4.40 )
325-
);
326-
327-
const b = roughness.lessThan( 0.25 ).select(
328-
log( roughness ).mul( - 0.46 ).sub( 0.64 ),
329-
r2.mul( 0.92 ).sub( roughness.mul( 1.79 ) ).add( 0.35 )
330-
);
322+
const a = float( - 1.9362 ).add( roughness.mul( 1.0678 ) ).add( r2.mul( 0.4573 ) ).sub( rInv.mul( 0.8469 ) );
323+
const b = float( - 0.6014 ).add( roughness.mul( 0.5538 ) ).sub( r2.mul( 0.4670 ) ).sub( rInv.mul( 0.1255 ) );
331324

332325
const DG = a.mul( dotNV ).add( b ).exp();
333326

src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,15 +360,15 @@ vec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 no
360360
361361
// This is a curve-fit approximation to the "Charlie sheen" BRDF integrated over the hemisphere from
362362
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF".
363-
// The low roughness fit (< 0.25) uses an inversesqrt/log model to accurately capture the sharp peak.
364363
float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {
365364
366365
float dotNV = saturate( dot( normal, viewDir ) );
367366
368367
float r2 = roughness * roughness;
368+
float rInv = 1.0 / ( roughness + 0.1 );
369369
370-
float a = roughness < 0.25 ? - 1.57 * inversesqrt( roughness ) : - 3.33 * r2 + 6.27 * roughness - 4.40;
371-
float b = roughness < 0.25 ? - 0.46 * log( roughness ) - 0.64 : 0.92 * r2 - 1.79 * roughness + 0.35;
370+
float a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;
371+
float b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;
372372
373373
float DG = exp( a * dotNV + b );
374374

0 commit comments

Comments
 (0)