Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified examples/screenshots/webgl_loader_gltf_sheen.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { WebGLUniformsGroups } from './webgl/WebGLUniformsGroups.js';
import { createCanvasElement, probeAsync, warnOnce, error, warn, log } from '../utils.js';
import { ColorManagement } from '../math/ColorManagement.js';
import { getDFGLUT } from './shaders/DFGLUTData.js';
import { getSheenLUT } from './shaders/SheenLUTData.js';

/**
* This renderer uses WebGL 2 to display scenes.
Expand Down Expand Up @@ -2520,6 +2521,13 @@ class WebGLRenderer {

}

// Set Sheen LUT for sheen materials
if ( material.sheen > 0 ) {

m_uniforms.sheenLUT.value = getSheenLUT();

}

if ( refreshMaterial ) {

p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default /* glsl */`

uniform sampler2D dfgLUT;
uniform sampler2D sheenLUT;

struct PhysicalMaterial {

Expand Down Expand Up @@ -530,6 +531,21 @@ void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geome

sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );

float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );
float maxSheenColor = max( max( material.sheenColor.r, material.sheenColor.g ), material.sheenColor.b );

// Lookup directional albedo for both view and light angles
float E_sheen_V = texture2D( sheenLUT, vec2( dotNV, material.sheenRoughness ) ).r;
float E_sheen_L = texture2D( sheenLUT, vec2( dotNL, material.sheenRoughness ) ).r;

// Take minimum for proper energy conservation
float sheenScaling = min(
1.0 - maxSheenColor * E_sheen_V,
1.0 - maxSheenColor * E_sheen_L
);

irradiance *= sheenScaling;

#endif

reflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );
Expand All @@ -555,6 +571,15 @@ void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradia

sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );

// Energy conservation for indirect lighting
float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );
float maxSheenColor = max( max( material.sheenColor.r, material.sheenColor.g ), material.sheenColor.b );

// Lookup directional albedo from LUT
float E_sheen = texture2D( sheenLUT, vec2( dotNV, material.sheenRoughness ) ).r;

float sheenScaling = 1.0 - maxSheenColor * E_sheen;

#endif

// Both indirect specular and indirect diffuse light accumulate here
Expand All @@ -576,10 +601,16 @@ void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradia
vec3 totalScattering = singleScattering + multiScattering;
vec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );

reflectedLight.indirectSpecular += radiance * singleScattering;
reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;

reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;
#ifdef USE_SHEEN
// Apply energy conservation scaling to base layers
reflectedLight.indirectSpecular += radiance * singleScattering * sheenScaling;
reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance * sheenScaling;
reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance * sheenScaling;
#else
reflectedLight.indirectSpecular += radiance * singleScattering;
reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;
reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;
#endif

}

Expand Down
65 changes: 65 additions & 0 deletions src/renderers/shaders/SheenLUTData.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/renderers/shaders/UniformsLib.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ const UniformsLib = {
alphaMap: { value: null },
alphaMapTransform: { value: /*@__PURE__*/ new Matrix3() },

alphaTest: { value: 0 }
alphaTest: { value: 0 },

sheenLUT: { value: null }

},

Expand Down
Loading