From 3fe10739e6f97364211acc7bd480def432d5f2b8 Mon Sep 17 00:00:00 2001 From: Gustav Sterbrant <107400752+GSterbrant@users.noreply.github.com> Date: Thu, 6 Oct 2022 09:48:23 +0100 Subject: [PATCH] Fixes sheen intensity (#4697) * Fix double clearcoat spec multiplication. * Use CC fresnel for lights * Use CC fresnel for lights * Add reflection sample with base mip offset for materials * Defer multiplication of sheen specular color to combine step. * We don't use reciprocal PI for energy preservation, so doing it for sheen was a mistake. Also revert the mip offset reflection sampling. Also, sheen should not be a factor of the materials reflectivity. --- .../program-lib/chunks/lit/frag/clusteredLight.js | 6 +++--- src/graphics/program-lib/chunks/lit/frag/combine.js | 3 ++- .../program-lib/chunks/lit/frag/reflectionSheen.js | 2 +- src/graphics/program-lib/programs/lit-shader.js | 11 +++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/graphics/program-lib/chunks/lit/frag/clusteredLight.js b/src/graphics/program-lib/chunks/lit/frag/clusteredLight.js index 2949bfae04d..ed81495152a 100644 --- a/src/graphics/program-lib/chunks/lit/frag/clusteredLight.js +++ b/src/graphics/program-lib/chunks/lit/frag/clusteredLight.js @@ -523,14 +523,14 @@ void evaluateLight(ClusterLightData light) { #ifdef LIT_CLEARCOAT #ifdef LIT_SPECULAR_FRESNEL - ccSpecularLight += getLightSpecularCC(halfDir) * dAtten * light.color * dAtten3 * getFresnel(dot(dViewDirW, halfDir), vec3(ccSpecularity)); + ccSpecularLight += getLightSpecularCC(halfDir) * dAtten * light.color * dAtten3 * getFresnelCC(dot(dViewDirW, halfDir)); #else - ccSpecularLight += getLightSpecularCC(halfDir) * dAtten * light.color * dAtten3 * vec3(ccSpecularity); + ccSpecularLight += getLightSpecularCC(halfDir) * dAtten * light.color * dAtten3; #endif #endif #ifdef LIT_SHEEN - sSpecularLight += getLightSpecularSheen(halfDir) * dAtten * light.color * dAtten3 * sSpecularity; + sSpecularLight += getLightSpecularSheen(halfDir) * dAtten * light.color * dAtten3; #endif #endif diff --git a/src/graphics/program-lib/chunks/lit/frag/combine.js b/src/graphics/program-lib/chunks/lit/frag/combine.js index 6d57703e3c8..6abc6eda105 100644 --- a/src/graphics/program-lib/chunks/lit/frag/combine.js +++ b/src/graphics/program-lib/chunks/lit/frag/combine.js @@ -12,9 +12,10 @@ vec3 combineColor() { #ifdef LIT_REFLECTIONS ret += dReflection.rgb * dReflection.a; #endif + #ifdef LIT_SHEEN float sheenScaling = 1.0 - max(max(sSpecularity.r, sSpecularity.g), sSpecularity.b) * 0.157; - ret = ret * sheenScaling + sSpecularLight + sReflection.rgb * sReflection.a; + ret = ret * sheenScaling + (sSpecularLight + sReflection.rgb) * sSpecularity; #endif #ifdef LIT_CLEARCOAT float clearCoatScaling = 1.0 - ccFresnel * ccSpecularity; diff --git a/src/graphics/program-lib/chunks/lit/frag/reflectionSheen.js b/src/graphics/program-lib/chunks/lit/frag/reflectionSheen.js index eec0bd7da1c..99e8d29b206 100644 --- a/src/graphics/program-lib/chunks/lit/frag/reflectionSheen.js +++ b/src/graphics/program-lib/chunks/lit/frag/reflectionSheen.js @@ -8,6 +8,6 @@ void addReflectionSheen() { float a = sGlossiness < 0.25 ? -339.2 * alphaG + 161.4 * sGlossiness - 25.9 : -8.48 * alphaG + 14.3 * sGlossiness - 9.95; float b = sGlossiness < 0.25 ? 44.0 * alphaG - 23.7 * sGlossiness + 3.26 : 1.97 * alphaG - 3.27 * sGlossiness + 0.72; float DG = exp( a * NoV + b ) + ( sGlossiness < 0.25 ? 0.0 : 0.1 * ( sGlossiness - 0.25 ) ); - sReflection += vec4(calcReflection(dReflDirW, sGlossiness), saturate(DG * 1.0/PI)); + sReflection += calcReflection(dNormalW, 0.0) * saturate(DG); } `; diff --git a/src/graphics/program-lib/programs/lit-shader.js b/src/graphics/program-lib/programs/lit-shader.js index 8bcba07f4e0..561d8c422f9 100644 --- a/src/graphics/program-lib/programs/lit-shader.js +++ b/src/graphics/program-lib/programs/lit-shader.js @@ -1042,7 +1042,6 @@ class LitShader { code += " ccReflection.rgb *= ccFresnel;\n"; } else { code += " ccFresnel = 0.0;\n"; - code += " ccReflection.rgb *= ccSpecularity;\n"; } } if (options.useSpecularityFactor) { @@ -1051,11 +1050,11 @@ class LitShader { if (options.sheen) { code += " addReflectionSheen();\n"; - code += " sReflection.rgb *= sSpecularity;\n"; } // Fresnel has to be applied to reflections code += " addReflection();\n"; + if (options.fresnelModel > 0) { code += " dReflection.rgb *= getFresnel(dot(dViewDirW, dNormalW), dSpecularity);\n"; } else { @@ -1248,18 +1247,18 @@ class LitShader { if (options.clearCoat) { code += " ccSpecularLight += getLightSpecularCC(dHalfDirW) * dAtten * light" + i + "_color"; code += usesCookieNow ? " * dAtten3" : ""; - code += calcFresnel ? " * getFresnel(dot(dViewDirW, dHalfDirW), vec3(ccSpecularity))" : " * vec3(ccSpecularity)"; + code += calcFresnel ? " * getFresnelCC(dot(dViewDirW, dHalfDirW))" : ""; code += ";\n"; } if (options.sheen) { - code += " sSpecularLight += getLightSpecularSheen(dHalfDirW) * dAtten * light" + i + "_color * sSpecularity"; + code += " sSpecularLight += getLightSpecularSheen(dHalfDirW) * dAtten * light" + i + "_color"; code += usesCookieNow ? " * dAtten3" : ""; code += ";\n"; } if (options.useSpecular) { code += " dSpecularLight += getLightSpecular(dHalfDirW) * dAtten * light" + i + "_color"; code += usesCookieNow ? " * dAtten3" : ""; - code += calcFresnel ? " * getFresnel(dot(dViewDirW, dHalfDirW), dSpecularity)" : " * dSpecularity"; + code += calcFresnel ? " * getFresnel(dot(dViewDirW, dHalfDirW), dSpecularity)" : ""; code += ";\n"; } } @@ -1374,7 +1373,7 @@ class LitShader { if (code.includes("ccSpecularLight")) structCode += "vec3 ccSpecularLight;\n"; if (code.includes("ccSpecularityNoFres")) structCode += "float ccSpecularityNoFres;\n"; if (code.includes("sSpecularLight")) structCode += "vec3 sSpecularLight;\n"; - if (code.includes("sReflection")) structCode += "vec4 sReflection;\n"; + if (code.includes("sReflection")) structCode += "vec3 sReflection;\n"; const result = this._fsGetBeginCode() + this.varyings +