mirror of
https://github.com/galacean/engine.git
synced 2026-05-17 08:57:23 +08:00
Fix Indirect Light Sheen/ClearCoat specularAO (#2744)
* fix: pbr specularAO
This commit is contained in:
@@ -21,8 +21,7 @@ struct SurfaceData{
|
||||
vec3 emissiveColor;
|
||||
float metallic;
|
||||
float roughness;
|
||||
float diffuseAO;
|
||||
float specularAO;
|
||||
float ambientOcclusion;
|
||||
float f0;
|
||||
float opacity;
|
||||
float IOR;
|
||||
@@ -79,6 +78,7 @@ struct BSDFData{
|
||||
vec3 specularColor;
|
||||
float roughness;
|
||||
vec3 envSpecularDFG;
|
||||
float diffuseAO;
|
||||
|
||||
#ifdef MATERIAL_ENABLE_CLEAR_COAT
|
||||
vec3 clearCoatSpecularColor;
|
||||
@@ -434,6 +434,8 @@ void initBSDFData(SurfaceData surfaceData, out BSDFData bsdfData){
|
||||
bsdfData.roughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(roughness + getAARoughnessFactor(surfaceData.normal), 1.0));
|
||||
bsdfData.envSpecularDFG = envBRDFApprox(bsdfData.specularColor, bsdfData.roughness, surfaceData.dotNV);
|
||||
|
||||
bsdfData.diffuseAO = surfaceData.ambientOcclusion;
|
||||
|
||||
#ifdef MATERIAL_ENABLE_CLEAR_COAT
|
||||
bsdfData.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.clearCoatRoughness + getAARoughnessFactor(surfaceData.clearCoatNormal), 1.0));
|
||||
bsdfData.clearCoatSpecularColor = vec3(0.04);
|
||||
|
||||
@@ -221,7 +221,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
|
||||
#ifdef MATERIAL_HAS_NORMALTEXTURE
|
||||
surfaceData.normal = getNormalByNormalTexture(tbn, material_NormalTexture, material_NormalIntensity, uv, isFrontFacing);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
surfaceData.dotNV = saturate( dot(surfaceData.normal, surfaceData.viewDir) );
|
||||
|
||||
@@ -265,7 +265,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
|
||||
surfaceData.anisotropicN = getAnisotropicBentNormal(surfaceData);
|
||||
#endif
|
||||
|
||||
//Iridescence
|
||||
// Iridescence
|
||||
#ifdef MATERIAL_ENABLE_IRIDESCENCE
|
||||
surfaceData.iridescenceFactor = material_IridescenceInfo.x;
|
||||
surfaceData.iridescenceIOR = material_IridescenceInfo.y;
|
||||
@@ -310,21 +310,13 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// AO
|
||||
float diffuseAO = 1.0;
|
||||
float specularAO = 1.0;
|
||||
|
||||
// Ambient Occlusion
|
||||
#ifdef MATERIAL_HAS_OCCLUSION_TEXTURE
|
||||
diffuseAO = ((texture2D(material_OcclusionTexture, aoUV)).r - 1.0) * material_OcclusionIntensity + 1.0;
|
||||
surfaceData.ambientOcclusion = ((texture2D(material_OcclusionTexture, aoUV)).r - 1.0) * material_OcclusionIntensity + 1.0;
|
||||
#else
|
||||
surfaceData.ambientOcclusion = 1.0;
|
||||
#endif
|
||||
|
||||
#if defined(MATERIAL_HAS_OCCLUSION_TEXTURE) && defined(SCENE_USE_SPECULAR_ENV)
|
||||
specularAO = saturate( pow( surfaceData.dotNV + diffuseAO, exp2( - 16.0 * surfaceData.roughness - 1.0 ) ) - 1.0 + diffuseAO );
|
||||
#endif
|
||||
|
||||
surfaceData.diffuseAO = diffuseAO;
|
||||
surfaceData.specularAO = specularAO;
|
||||
|
||||
return surfaceData;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,4 +43,13 @@ vec3 getLightProbeRadiance(SurfaceData surfaceData, vec3 normal, float roughness
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
float evaluateSpecularOcclusion(float dotNV, float diffuseAO, float roughness){
|
||||
float specularAOFactor = 1.0;
|
||||
#if defined(MATERIAL_HAS_OCCLUSION_TEXTURE) && defined(SCENE_USE_SPECULAR_ENV)
|
||||
specularAOFactor = saturate( pow(dotNV + diffuseAO, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + diffuseAO );
|
||||
#endif
|
||||
return specularAOFactor;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -48,8 +48,7 @@ void evaluateDiffuseIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsd
|
||||
vec3 irradiance = scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity;
|
||||
irradiance *= PI;
|
||||
#endif
|
||||
|
||||
diffuseColor += surfaceData.diffuseAO * irradiance * BRDF_Diffuse_Lambert( bsdfData.diffuseColor );
|
||||
diffuseColor += bsdfData.diffuseAO * irradiance * BRDF_Diffuse_Lambert( bsdfData.diffuseColor );
|
||||
}
|
||||
|
||||
float evaluateClearCoatIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, inout vec3 specularColor){
|
||||
@@ -57,7 +56,8 @@ float evaluateClearCoatIBL(Varyings varyings, SurfaceData surfaceData, BSDFData
|
||||
|
||||
#ifdef MATERIAL_ENABLE_CLEAR_COAT
|
||||
vec3 clearCoatRadiance = getLightProbeRadiance(surfaceData, surfaceData.clearCoatNormal, bsdfData.clearCoatRoughness);
|
||||
specularColor += surfaceData.specularAO * clearCoatRadiance * surfaceData.clearCoat * envBRDFApprox(bsdfData.clearCoatSpecularColor, bsdfData.clearCoatRoughness, surfaceData.clearCoatDotNV);
|
||||
float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.clearCoatRoughness);
|
||||
specularColor += specularAO * clearCoatRadiance * surfaceData.clearCoat * envBRDFApprox(bsdfData.clearCoatSpecularColor, bsdfData.clearCoatRoughness, surfaceData.clearCoatDotNV);
|
||||
radianceAttenuation -= surfaceData.clearCoat * F_Schlick(surfaceData.f0, surfaceData.clearCoatDotNV);
|
||||
#endif
|
||||
|
||||
@@ -72,16 +72,17 @@ void evaluateSpecularIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bs
|
||||
#else
|
||||
vec3 speculaColor = bsdfData.specularColor;
|
||||
#endif
|
||||
|
||||
outSpecularColor += surfaceData.specularAO * radianceAttenuation * radiance * envBRDFApprox(speculaColor, bsdfData.roughness, surfaceData.dotNV);
|
||||
|
||||
float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.roughness);
|
||||
outSpecularColor += specularAO * radianceAttenuation * radiance * envBRDFApprox(speculaColor, bsdfData.roughness, surfaceData.dotNV);
|
||||
}
|
||||
|
||||
void evaluateSheenIBL(Varyings varyings, SurfaceData surfaceData, BSDFData bsdfData, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){
|
||||
#ifdef MATERIAL_ENABLE_SHEEN
|
||||
diffuseColor *= bsdfData.sheenScaling;
|
||||
specularColor *= bsdfData.sheenScaling;
|
||||
|
||||
vec3 reflectance = surfaceData.specularAO * radianceAttenuation * bsdfData.approxIBLSheenDG * surfaceData.sheenColor;
|
||||
float specularAO = evaluateSpecularOcclusion(surfaceData.dotNV, bsdfData.diffuseAO, bsdfData.sheenRoughness) ;
|
||||
vec3 reflectance = specularAO * radianceAttenuation * bsdfData.approxIBLSheenDG * surfaceData.sheenColor;
|
||||
specularColor += reflectance;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user