Skip to content

Commit 8409754

Browse files
authored
WebGPURenderer: Add multi-scattering energy compensation for direct lighting (#32089)
* WebGPURenderer: Add multi-scattering energy compensation for direct lighting. * Clean up. * Clean up. * Updated screenshot. * Updated screenshots.
1 parent 6da6c51 commit 8409754

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import BRDF_GGX from './BRDF_GGX.js';
2+
import DFGApprox from './DFGApprox.js';
3+
import { normalView } from '../../accessors/Normal.js';
4+
import { positionViewDirection } from '../../accessors/Position.js';
5+
import { EPSILON } from '../../math/MathNode.js';
6+
import { Fn, float } from '../../tsl/TSLBase.js';
7+
8+
// GGX BRDF with multi-scattering energy compensation for direct lighting
9+
// This provides more accurate energy conservation, especially for rough materials
10+
// Based on "Practical Multiple Scattering Compensation for Microfacet Models"
11+
// https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf
12+
const BRDF_GGX_Multiscatter = /*@__PURE__*/ Fn( ( { lightDirection, f0, f90, roughness: _roughness, f, USE_IRIDESCENCE, USE_ANISOTROPY } ) => {
13+
14+
// Single-scattering BRDF (standard GGX)
15+
const singleScatter = BRDF_GGX( { lightDirection, f0, f90, roughness: _roughness, f, USE_IRIDESCENCE, USE_ANISOTROPY } );
16+
17+
// Multi-scattering compensation
18+
const dotNL = normalView.dot( lightDirection ).clamp();
19+
const dotNV = normalView.dot( positionViewDirection ).clamp();
20+
21+
// Precomputed DFG values for view and light directions
22+
const dfgV = DFGApprox( { roughness: _roughness, dotNV } );
23+
const dfgL = DFGApprox( { roughness: _roughness, dotNV: dotNL } );
24+
25+
// Single-scattering energy for view and light
26+
const FssEss_V = f0.mul( dfgV.x ).add( f90.mul( dfgV.y ) );
27+
const FssEss_L = f0.mul( dfgL.x ).add( f90.mul( dfgL.y ) );
28+
29+
const Ess_V = dfgV.x.add( dfgV.y );
30+
const Ess_L = dfgL.x.add( dfgL.y );
31+
32+
// Energy lost to multiple scattering
33+
const Ems_V = float( 1.0 ).sub( Ess_V );
34+
const Ems_L = float( 1.0 ).sub( Ess_L );
35+
36+
// Average Fresnel reflectance
37+
const Favg = f0.add( f0.oneMinus().mul( 0.047619 ) ); // 1/21
38+
39+
// Multiple scattering contribution
40+
// Uses geometric mean of view and light contributions for better energy distribution
41+
const Fms = FssEss_V.mul( FssEss_L ).mul( Favg ).div( float( 1.0 ).sub( Ems_V.mul( Ems_L ).mul( Favg ).mul( Favg ) ).add( EPSILON ) );
42+
43+
// Energy compensation factor
44+
const compensationFactor = Ems_V.mul( Ems_L );
45+
46+
const multiScatter = Fms.mul( compensationFactor );
47+
48+
return singleScatter.add( multiScatter );
49+
50+
} );
51+
52+
export default BRDF_GGX_Multiscatter;

src/nodes/functions/PhysicalLightingModel.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import BRDF_Lambert from './BSDF/BRDF_Lambert.js';
22
import BRDF_GGX from './BSDF/BRDF_GGX.js';
3+
import BRDF_GGX_Multiscatter from './BSDF/BRDF_GGX_Multiscatter.js';
34
import DFGApprox from './BSDF/DFGApprox.js';
45
import EnvironmentBRDF from './BSDF/EnvironmentBRDF.js';
56
import F_Schlick from './BSDF/F_Schlick.js';
@@ -597,7 +598,7 @@ class PhysicalLightingModel extends LightingModel {
597598

598599
reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
599600

600-
reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy } ) ) );
601+
reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX_Multiscatter( { lightDirection, f0: specularColor, f90: 1, roughness, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy } ) ) );
601602

602603
}
603604

0 commit comments

Comments
 (0)