Skip to content

Commit

Permalink
fix: sheen layer
Browse files Browse the repository at this point in the history
  • Loading branch information
hhhhkrx committed Dec 10, 2024
1 parent 99a6d8e commit f550f37
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 48 deletions.
4 changes: 2 additions & 2 deletions packages/shaderlab/src/shaders/PBR.gs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Shader "PBR.gs" {
}

Header("Sheen"){
material_Sheen("Sheen", Range(0, 1, 0.01)) = 0;
material_SheenColor("SheenColor", Color ) = (0, 0, 0, 1);
material_Sheen("SheenIntensity", Range(0, 1, 0.01)) = 0;
material_SheenColor("SheenColor", Color ) = (0, 0, 0, 0);
material_SheenRoughness("SheenRoughness", Range(0, 1, 0.01)) = 0;
material_SheenTexture("SheenTexture", Texture2D);
material_SheenRoughnessTexture("SheenRoughnessTexture", Texture2D);
Expand Down
22 changes: 4 additions & 18 deletions packages/shaderlab/src/shaders/shadingPBR/BRDF.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ struct BRDFData{

#ifdef MATERIAL_ENABLE_SHEEN
float sheenRoughness;
float sheenScaling;
float sheenDFG;
float sheenEnergy;
#endif

};
Expand Down Expand Up @@ -331,27 +330,15 @@ vec3 BRDF_Diffuse_Lambert(vec3 diffuseColor) {
return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));
}

vec3 BRDF_Sheen(vec3 incidentDirection, SurfaceData surfaceData, vec3 sheenColor, float sheenRoughness) {
vec3 sheenBRDF(vec3 incidentDirection, SurfaceData surfaceData, vec3 sheenColor, float sheenRoughness) {
vec3 halfDir = normalize(incidentDirection + surfaceData.viewDir);
float dotNL = saturate(dot(surfaceData.normal, incidentDirection));
float dotNH = saturate(dot(surfaceData.normal, halfDir));
float D = D_Charlie(sheenRoughness, dotNH);
float V = V_Neubelt(surfaceData.dotNV, dotNL);
vec3 F = sheenColor;
vec3 F = sheenColor.rgb;
return D * V * F;
}

// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
float IBLSheenBRDF(SurfaceData surfaceData, float roughness) {
float dotNV = surfaceData.dotNV;
float r2 = roughness * roughness;
float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;
float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;
float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );
return saturate( DG * RECIPROCAL_PI );
}
#endif

void initBRDFData(SurfaceData surfaceData, out BRDFData brdfData){
Expand Down Expand Up @@ -384,10 +371,9 @@ void initBRDFData(SurfaceData surfaceData, out BRDFData brdfData){

#ifdef MATERIAL_ENABLE_SHEEN
brdfData.sheenRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.sheenRoughness + getAARoughnessFactor(surfaceData.normal), 1.0));
brdfData.sheenDFG = IBLSheenBRDF(surfaceData, brdfData.sheenRoughness);
// sheen energy compensation approximation calculation in ‘Sheen DFG LUT integrated over diffuse IBL’
// https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
brdfData.sheenScaling = 1.0 - 0.157 * max(max(surfaceData.sheenColor.r, surfaceData.sheenColor.g), surfaceData.sheenColor.b);
brdfData.sheenEnergy = 1.0 - 0.157 * max(max(surfaceData.sheenColor.r, surfaceData.sheenColor.g), surfaceData.sheenColor.b);
#endif
}

Expand Down
13 changes: 6 additions & 7 deletions packages/shaderlab/src/shaders/shadingPBR/FragmentPBR.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ float material_OcclusionTextureCoord;
#endif

#ifdef MATERIAL_ENABLE_SHEEN
float material_Sheen;
float material_SheenRoughness;
vec3 material_SheenColor;
vec4 material_SheenColor;
#ifdef MATERIAL_HAS_SHEEN_TEXTURE
sampler2D material_SheenTexture;
#endif
Expand Down Expand Up @@ -277,7 +276,8 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
#endif

#ifdef MATERIAL_ENABLE_SHEEN
vec3 sheencolor = material_SheenColor * material_Sheen;
float sheen = material_SheenColor.a;
vec3 sheencolor = material_SheenColor.rgb * sheen;
#ifdef MATERIAL_HAS_SHEEN_TEXTURE
vec4 sheenTexturecolor = texture2D(material_SheenTexture, uv);
#ifndef ENGINE_IS_COLORSPACE_GAMMA
Expand All @@ -287,12 +287,11 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
#endif
surfaceData.sheenColor = sheencolor;

float sheenRoughness = clamp(material_SheenRoughness, 0.01, 1.0);
surfaceData.sheenRoughness = material_SheenRoughness;
#ifdef MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE
vec4 sheenRoughnessTexture = (texture2D(material_SheenRoughnessTexture, uv));
sheenRoughness *= sheenRoughnessTexture.a;
vec4 sheenRoughnessTexture = texture2D(material_SheenRoughnessTexture, uv);
surfaceData.sheenRoughness *= sheenRoughnessTexture.a;
#endif
surfaceData.sheenRoughness = sheenRoughness;
#endif

// AO
Expand Down
5 changes: 5 additions & 0 deletions packages/shaderlab/src/shaders/shadingPBR/LightDirectPBR.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#ifndef FUNCTION_CLEAR_COAT_LOBE
#define FUNCTION_CLEAR_COAT_LOBE clearCoatLobe
#endif
#ifndef FUNCTION_SHEEN_LOBE
#define FUNCTION_SHEEN_LOBE SheenLobe
#endif

#include "BRDF.glsl"
#include "Light.glsl"
Expand All @@ -34,6 +37,8 @@ void surfaceShading(Varyings varyings, SurfaceData surfaceData, BRDFData brdfDat
FUNCTION_DIFFUSE_LOBE(varyings, surfaceData, brdfData, attenuationIrradiance, diffuseColor);
// Specular Lobe
FUNCTION_SPECULAR_LOBE(varyings, surfaceData, brdfData, incidentDirection, attenuationIrradiance, specularColor);
// Sheen Lobe
FUNCTION_SHEEN_LOBE(varyings, surfaceData, brdfData, incidentDirection, diffuseColor, specularColor);

color += diffuseColor + specularColor;

Expand Down
30 changes: 17 additions & 13 deletions packages/shaderlab/src/shaders/shadingPBR/LightIndirectPBR.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#ifndef FUNCTION_CLEAR_COAT_IBL
#define FUNCTION_CLEAR_COAT_IBL evaluateClearCoatIBL
#endif

#ifndef FUNCTION_SHEEN_IBL
#define FUNCTION_SHEEN_IBL evaluateSheenIBL
#endif
#include "BRDF.glsl"
#include "Light.glsl"
#include "LightProbe.glsl"
Expand Down Expand Up @@ -50,10 +52,6 @@ void evaluateDiffuseIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brd
irradiance *= PI;
#endif

#ifdef MATERIAL_ENABLE_SHEEN
diffuseColor *= brdfData.sheenScaling;
#endif

diffuseColor += surfaceData.diffuseAO * irradiance * BRDF_Diffuse_Lambert( brdfData.diffuseColor );
}

Expand All @@ -78,17 +76,19 @@ void evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BRDFData br
vec3 speculaColor = brdfData.specularColor;
#endif

outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * envBRDFApprox(speculaColor, brdfData.roughness, surfaceData.dotNV);
}

void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, inout vec3 diffuseColor, inout vec3 SpecularColor){
#ifdef MATERIAL_ENABLE_SHEEN
outSpecularColor *= brdfData.sheenScaling;
vec3 environmentBRDF = brdfData.sheenDFG * surfaceData.sheenColor;
#else
vec3 environmentBRDF = envBRDFApprox(speculaColor, brdfData.roughness, surfaceData.dotNV);
diffuseColor *= brdfData.sheenEnergy;
SpecularColor *= brdfData.sheenEnergy;

vec3 reflectance = IBLSheenDFG(surfaceData, brdfData.sheenRoughness) * surfaceData.sheenColor;
SpecularColor += reflectance;
#endif

outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * environmentBRDF;
}


void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, inout vec3 color){
vec3 diffuseColor = vec3(0);
vec3 specularColor = vec3(0);
Expand All @@ -101,8 +101,12 @@ void evaluateIBL(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData,

// IBL specular
FUNCTION_SPECULAR_IBL(varyings, surfaceData, brdfData, radianceAttenuation, specularColor);


// IBL sheen
FUNCTION_SHEEN_IBL(varyings, surfaceData, brdfData, diffuseColor, specularColor);

color += diffuseColor + specularColor;

}


Expand Down
12 changes: 12 additions & 0 deletions packages/shaderlab/src/shaders/shadingPBR/LightProbe.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,16 @@ vec3 getLightProbeRadiance(SurfaceData surfaceData, vec3 normal, float roughness
#endif
}

// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found
// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing
float IBLSheenDFG(SurfaceData surfaceData, float roughness) {
float dotNV = surfaceData.dotNV;
float r2 = roughness * roughness;
float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;
float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;
float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );
return saturate( DG * RECIPROCAL_PI );
}

#endif
16 changes: 8 additions & 8 deletions packages/shaderlab/src/shaders/shadingPBR/ReflectionLobe.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
#define REFLECTION_LOBE_INCLUDED

void diffuseLobe(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, vec3 attenuationIrradiance, inout vec3 diffuseColor){
#ifdef MATERIAL_ENABLE_SHEEN
diffuseColor *= brdfData.sheenScaling;
#endif
diffuseColor += attenuationIrradiance * BRDF_Diffuse_Lambert( brdfData.diffuseColor );
}

void specularLobe(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 specularColor){
#ifdef MATERIAL_ENABLE_SHEEN
specularColor *= brdfData.sheenScaling;
vec3 BRDF_sheen = BRDF_Sheen(incidentDirection, surfaceData, surfaceData.sheenColor, brdfData.sheenRoughness);
specularColor += attenuationIrradiance * BRDF_sheen;
#else
specularColor += attenuationIrradiance * BRDF_Specular_GGX( incidentDirection, surfaceData, brdfData, surfaceData.normal, brdfData.specularColor, brdfData.roughness);
}

void SheenLobe(Varyings varyings, SurfaceData surfaceData, BRDFData brdfData, vec3 incidentDirection, inout vec3 diffuseColor, inout vec3 specularColor){
#ifdef MATERIAL_ENABLE_SHEEN
diffuseColor *= brdfData.sheenEnergy;
diffuseColor += sheenBRDF(incidentDirection, surfaceData, surfaceData.sheenColor, brdfData.sheenRoughness);
specularColor *= brdfData.sheenEnergy;
specularColor += sheenBRDF(incidentDirection, surfaceData, surfaceData.sheenColor, brdfData.sheenRoughness);
#endif
}

Expand Down

0 comments on commit f550f37

Please sign in to comment.