|
@@ -177,38 +177,18 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
|
|
|
}
|
|
|
|
|
|
- init( { reflectedLight } ) {
|
|
|
+ start( /*context*/ ) {
|
|
|
|
|
|
if ( this.clearcoat === true ) {
|
|
|
|
|
|
- this.clearcoatRadiance = vec3().temp();
|
|
|
- this.clearcoatSpecular = vec3().temp();
|
|
|
-
|
|
|
- const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
|
-
|
|
|
- const Fcc = F_Schlick( {
|
|
|
- dotVH: dotNVcc,
|
|
|
- f0: clearcoatF0,
|
|
|
- f90: clearcoatF90
|
|
|
- } );
|
|
|
-
|
|
|
- const outgoingLight = reflectedLight.total;
|
|
|
- const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( this.clearcoatSpecular.mul( clearcoat ) );
|
|
|
-
|
|
|
- outgoingLight.assign( clearcoatLight );
|
|
|
+ this.clearcoatRadiance = vec3().temp( 'clearcoatRadiance' );
|
|
|
+ this.clearcoatSpecular = vec3().temp( 'clearcoatSpecular' );
|
|
|
|
|
|
}
|
|
|
|
|
|
if ( this.sheen === true ) {
|
|
|
|
|
|
- this.sheenSpecular = vec3().temp();
|
|
|
-
|
|
|
- const outgoingLight = reflectedLight.total;
|
|
|
-
|
|
|
- const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
|
|
|
- const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( this.sheenSpecular );
|
|
|
-
|
|
|
- outgoingLight.assign( sheenLight );
|
|
|
+ this.sheenSpecular = vec3().temp( 'sheenSpecular' );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -227,7 +207,7 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
// Approximates multiscattering in order to preserve energy.
|
|
|
// http://www.jcgt.org/published/0008/01/03/
|
|
|
|
|
|
- computeMultiscattering( singleScatter, multiScatter, specularF90 = float( 1 ) ) {
|
|
|
+ computeMultiscattering( stack, singleScatter, multiScatter, specularF90 = float( 1 ) ) {
|
|
|
|
|
|
const fab = DFGApprox( { roughness } );
|
|
|
|
|
@@ -241,19 +221,19 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
const Favg = specularColor.add( specularColor.oneMinus().mul( 0.047619 ) ); // 1/21
|
|
|
const Fms = FssEss.mul( Favg ).div( Ems.mul( Favg ).oneMinus() );
|
|
|
|
|
|
- singleScatter.addAssign( FssEss );
|
|
|
- multiScatter.addAssign( Fms.mul( Ems ) );
|
|
|
+ stack.addAssign( singleScatter, FssEss );
|
|
|
+ stack.addAssign( multiScatter, Fms.mul( Ems ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- direct( { lightDirection, lightColor, reflectedLight } ) {
|
|
|
+ direct( { lightDirection, lightColor, reflectedLight }, stack ) {
|
|
|
|
|
|
const dotNL = transformedNormalView.dot( lightDirection ).clamp();
|
|
|
const irradiance = dotNL.mul( lightColor );
|
|
|
|
|
|
if ( this.sheen === true ) {
|
|
|
|
|
|
- this.sheenSpecular.addAssign( irradiance.mul( BRDF_Sheen( { lightDirection } ) ) );
|
|
|
+ stack.addAssign( this.sheenSpecular, irradiance.mul( BRDF_Sheen( { lightDirection } ) ) );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -262,27 +242,27 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
const dotNLcc = transformedClearcoatNormalView.dot( lightDirection ).clamp();
|
|
|
const ccIrradiance = dotNLcc.mul( lightColor );
|
|
|
|
|
|
- this.clearcoatSpecular.addAssign( ccIrradiance.mul( BRDF_GGX( { lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView } ) ) );
|
|
|
+ stack.addAssign( this.clearcoatSpecular, ccIrradiance.mul( BRDF_GGX( { lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView } ) ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- reflectedLight.directDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
|
|
|
+ stack.addAssign( reflectedLight.directDiffuse, irradiance.mul( BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
|
|
|
|
|
|
- reflectedLight.directSpecular.addAssign( irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, iridescenceFresnel: this.iridescenceFresnel } ) ) );
|
|
|
+ stack.addAssign( reflectedLight.directSpecular, irradiance.mul( BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, iridescenceFresnel: this.iridescenceFresnel } ) ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- indirectDiffuse( { irradiance, reflectedLight } ) {
|
|
|
+ indirectDiffuse( { irradiance, reflectedLight }, stack ) {
|
|
|
|
|
|
- reflectedLight.indirectDiffuse.addAssign( irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
|
|
|
+ stack.addAssign( reflectedLight.indirectDiffuse, irradiance.mul( BRDF_Lambert( { diffuseColor } ) ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- indirectSpecular( { radiance, iblIrradiance, reflectedLight, } ) {
|
|
|
+ indirectSpecular( { radiance, iblIrradiance, reflectedLight }, stack ) {
|
|
|
|
|
|
if ( this.sheen === true ) {
|
|
|
|
|
|
- this.sheenSpecular.addAssign( iblIrradiance.mul(
|
|
|
+ stack.addAssign( this.sheenSpecular, iblIrradiance.mul(
|
|
|
sheen,
|
|
|
IBLSheenBRDF( transformedNormalView, positionViewDirection, sheenRoughness )
|
|
|
) );
|
|
@@ -300,30 +280,30 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
roughness: clearcoatRoughness
|
|
|
} );
|
|
|
|
|
|
- this.clearcoatSpecular.addAssign( this.clearcoatRadiance.mul( clearcoatEnv ) );
|
|
|
+ stack.addAssign( this.clearcoatSpecular, this.clearcoatRadiance.mul( clearcoatEnv ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
// Both indirect specular and indirect diffuse light accumulate here
|
|
|
|
|
|
- const singleScattering = vec3().temp();
|
|
|
- const multiScattering = vec3().temp();
|
|
|
+ const singleScattering = vec3().temp( 'singleScattering' );
|
|
|
+ const multiScattering = vec3().temp( 'multiScattering' );
|
|
|
const cosineWeightedIrradiance = iblIrradiance.mul( 1 / Math.PI );
|
|
|
|
|
|
- this.computeMultiscattering( singleScattering, multiScattering );
|
|
|
+ this.computeMultiscattering( stack, singleScattering, multiScattering );
|
|
|
|
|
|
const totalScattering = singleScattering.add( multiScattering );
|
|
|
|
|
|
const diffuse = diffuseColor.mul( totalScattering.r.max( totalScattering.g ).max( totalScattering.b ).oneMinus() );
|
|
|
|
|
|
- reflectedLight.indirectSpecular.addAssign( radiance.mul( singleScattering ) );
|
|
|
- reflectedLight.indirectSpecular.addAssign( multiScattering.mul( cosineWeightedIrradiance ) );
|
|
|
+ stack.addAssign( reflectedLight.indirectSpecular, radiance.mul( singleScattering ) );
|
|
|
+ stack.addAssign( reflectedLight.indirectSpecular, multiScattering.mul( cosineWeightedIrradiance ) );
|
|
|
|
|
|
- reflectedLight.indirectDiffuse.addAssign( diffuse.mul( cosineWeightedIrradiance ) );
|
|
|
+ stack.addAssign( reflectedLight.indirectDiffuse, diffuse.mul( cosineWeightedIrradiance ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- ambientOcclusion( { ambientOcclusion, reflectedLight } ) {
|
|
|
+ ambientOcclusion( { ambientOcclusion, reflectedLight }, stack ) {
|
|
|
|
|
|
const dotNV = transformedNormalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
|
|
|
|
|
@@ -332,9 +312,39 @@ class PhysicalLightingModel extends LightingModel {
|
|
|
|
|
|
const aoNode = ambientOcclusion.sub( aoNV.pow( aoExp ).oneMinus() ).clamp();
|
|
|
|
|
|
- reflectedLight.indirectDiffuse.mulAssign( ambientOcclusion );
|
|
|
+ stack.mulAssign( reflectedLight.indirectDiffuse, ambientOcclusion );
|
|
|
+ stack.mulAssign( reflectedLight.indirectSpecular, aoNode );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ finish( context, stack ) {
|
|
|
+
|
|
|
+ const { outgoingLight } = context;
|
|
|
+
|
|
|
+ if ( this.clearcoat === true ) {
|
|
|
+
|
|
|
+ const dotNVcc = transformedClearcoatNormalView.dot( positionViewDirection ).clamp();
|
|
|
+
|
|
|
+ const Fcc = F_Schlick( {
|
|
|
+ dotVH: dotNVcc,
|
|
|
+ f0: clearcoatF0,
|
|
|
+ f90: clearcoatF90
|
|
|
+ } );
|
|
|
+
|
|
|
+ const clearcoatLight = outgoingLight.mul( clearcoat.mul( Fcc ).oneMinus() ).add( this.clearcoatSpecular.mul( clearcoat ) );
|
|
|
|
|
|
- reflectedLight.indirectSpecular.mulAssign( aoNode );
|
|
|
+ stack.assign( outgoingLight, clearcoatLight );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( this.sheen === true ) {
|
|
|
+
|
|
|
+ const sheenEnergyComp = sheen.r.max( sheen.g ).max( sheen.b ).mul( 0.157 ).oneMinus();
|
|
|
+ const sheenLight = outgoingLight.mul( sheenEnergyComp ).add( this.sheenSpecular );
|
|
|
+
|
|
|
+ stack.assign( outgoingLight, sheenLight );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|