Просмотр исходного кода

Merge pull request #5849 from sebavan/master

Aniso Base Layer Remapping
David Catuhe 6 лет назад
Родитель
Сommit
9ae6bde3d4

+ 4 - 6
src/Materials/PBR/pbrAnisotropicConfiguration.ts

@@ -63,12 +63,10 @@ export class PBRAnisotropicConfiguration {
      * @param mesh the mesh we are preparing the defines for.
      */
     public prepareDefines(defines: IMaterialAnisotropicDefines, mesh: AbstractMesh): void {
-        if (defines._areMiscDirty) {
-            defines.ANISOTROPIC = this._isEnabled;
-            if (this._isEnabled && !mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
-                defines._needUVs = true;
-                defines.MAINUV1 = true;
-            }
+        defines.ANISOTROPIC = this._isEnabled;
+        if (this._isEnabled && !mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
+            defines._needUVs = true;
+            defines.MAINUV1 = true;
         }
     }
 

+ 40 - 11
src/Shaders/ShadersInclude/pbrFunctions.fx

@@ -4,6 +4,10 @@
 // AlphaG epsilon to avoid numerical issues
 #define MINIMUMVARIANCE 0.0005
 
+// f0 = 4% based on the IOR of a air-polyurethane interface.
+#define CLEARCOATREFLECTANCE0 0.04
+#define CLEARCOATREFLECTANCE90 1.0
+
 float convertRoughnessToAverageSlope(float roughness)
 {
     // Calculate AlphaG as square of roughness; add epsilon to avoid numerical issues
@@ -30,6 +34,34 @@ vec2 getAARoughnessFactors(vec3 normalVector) {
     #endif
 }
 
+// Schlick's approximation for R0 (Fresnel Reflectance Values)
+// Keep for references
+// vec3 getR0fromAirToSurfaceIOR(vec3 ior1) {
+//     return getR0fromIOR(ior1, vec3(1.0));
+// }
+
+// vec3 getR0fromIOR(vec3 ior1, vec3 ior2) {
+//     vec3 t = (ior1 - ior2) / (ior1 + ior2);
+//     return t * t;
+// }
+
+// vec3 getIORfromAirToSurfaceR0(vec3 f0) {
+//     vec3 s = sqrt(f0);
+//     return (1.0 + s) / (1.0 - s);
+// }
+
+// // Clear coat Remapping
+// vec3 getR0RemappedForClearCoat(vec3 f0, vec3 clearCoatF0) {
+//     vec3 iorBase = getIORfromAirToSurfaceR0(f0);
+//     vec3 clearCoatIor = getIORfromAirToSurfaceR0(clearCoatF0);
+//     return getR0fromIOR(iorBase, clearCoatIor);
+// }
+
+vec3 getR0RemappedForPolyurethaneClearCoat(vec3 f0) {
+    vec3 s = sqrt(f0);
+    return (-1.0 + 5.0 * s) / (5.0 + s);
+}
+
 // From Microfacet Models for Refraction through Rough Surfaces, Walter et al. 2007
 // Keep for references
 // float smithVisibilityG1_TrowbridgeReitzGGX(float dot, float alphaG)
@@ -114,12 +146,12 @@ float smithVisibility_GGXCorrelated_Anisotropic(float NdotV, float NdotL, float
     return v;
 }
 
-vec3 fresnelSchlickGGXVec3(float VdotH, vec3 reflectance0, vec3 reflectance90)
+vec3 fresnelSchlickGGX(float VdotH, vec3 reflectance0, vec3 reflectance90)
 {
     return reflectance0 + (reflectance90 - reflectance0) * pow(1.0 - VdotH, 5.0);
 }
 
-float fresnelSchlickGGXFloat(float VdotH, float reflectance0, float reflectance90)
+float fresnelSchlickGGX(float VdotH, float reflectance0, float reflectance90)
 {
     return reflectance0 + (reflectance90 - reflectance0) * pow(1.0 - VdotH, 5.0);
 }
@@ -131,6 +163,9 @@ vec3 fresnelSchlickEnvironmentGGX(float VdotN, vec3 reflectance0, vec3 reflectan
     return reflectance0 + weight * (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotN, 0., 1.), 5.0);
 }
 
+// Disney diffuse term
+// https://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf
+// Page 14
 float computeDiffuseTerm(float NdotL, float NdotV, float VdotH, float roughness)
 {
     // Diffuse fresnel falloff as per Disney principled BRDF, and in the spirit of
@@ -154,7 +189,7 @@ vec3 computeSpecularTerm(float NdotH, float NdotL, float NdotV, float VdotH, flo
     float visibility = smithVisibility_TrowbridgeReitzGGXFast(NdotL, NdotV, alphaG);
     float specTerm = max(0., visibility * distribution);
 
-    vec3 fresnel = fresnelSchlickGGXVec3(VdotH, reflectance0, reflectance90);
+    vec3 fresnel = fresnelSchlickGGX(VdotH, reflectance0, reflectance90);
     return fresnel * specTerm;
 }
 
@@ -167,7 +202,7 @@ vec3 computeAnisotropicSpecularTerm(float NdotH, float NdotL, float NdotV, float
     float visibility = smithVisibility_GGXCorrelated_Anisotropic(NdotV, NdotL, TdotV, BdotV, TdotL, BdotL, alphaTB);
     float specTerm = max(0., visibility * distribution);
 
-    vec3 fresnel = fresnelSchlickGGXVec3(VdotH, reflectance0, reflectance90);
+    vec3 fresnel = fresnelSchlickGGX(VdotH, reflectance0, reflectance90);
     return fresnel * specTerm;
 }
 
@@ -179,13 +214,7 @@ vec2 computeClearCoatTerm(float NdotH, float VdotH, float clearCoatRoughness, fl
     float visibility = kelemenVisibility(VdotH);
     float clearCoatTerm = max(0., visibility * distribution);
 
-    // fo = 4% based on the IOR of a air-polyurethane interface.
-    // the max reflectance is relying on our special trick to prevent weird values on highly diffuse materials.
-    // To let as a configuration if required
-    const float reflectance0 = 0.04;
-    const float reflectance90 = 1.;
-
-    float fresnel = fresnelSchlickGGXFloat(VdotH, reflectance0, reflectance90);
+    float fresnel = fresnelSchlickGGX(VdotH, CLEARCOATREFLECTANCE0, CLEARCOATREFLECTANCE90);
     fresnel *= clearCoatIntensity;
     
     return vec2(fresnel * clearCoatTerm, 1.0 - fresnel);

+ 47 - 34
src/Shaders/pbr.fragment.fx

@@ -379,15 +379,30 @@ void main(void) {
         // Diffuse is used as the base of the reflectivity.
         vec3 baseColor = surfaceAlbedo;
 
-        // Default specular reflectance at normal incidence.
-        // 4% corresponds to index of refraction (IOR) of 1.50, approximately equal to glass.
-        const vec3 DefaultSpecularReflectanceDielectric = vec3(0.04, 0.04, 0.04);
+        #ifdef REFLECTANCE
+            // Following Frostbite Remapping,
+            // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf page 115
+            // vec3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + baseColor * metallic;
+            // where 0.16 * reflectance * reflectance remaps the reflectance to allow storage in 8 bit texture
 
-        // Compute the converted diffuse.
-        surfaceAlbedo = mix(baseColor.rgb * (1.0 - DefaultSpecularReflectanceDielectric.r), vec3(0., 0., 0.), metallicRoughness.r);
+            // Compute the converted diffuse.
+            surfaceAlbedo = baseColor.rgb * (1.0 - metallicRoughness.r);
 
-        // Compute the converted reflectivity.
-        surfaceReflectivityColor = mix(DefaultSpecularReflectanceDielectric, baseColor, metallicRoughness.r);
+            // Compute the converted reflectivity.
+            surfaceReflectivityColor = mix(0.16 * reflectance * reflectance, baseColor, metallicRoughness.r);
+        #else
+            // we are here fixing our default reflectance to a common value for none metallic surface.
+
+            // Default specular reflectance at normal incidence.
+            // 4% corresponds to index of refraction (IOR) of 1.50, approximately equal to glass.
+            const vec3 DefaultSpecularReflectanceDielectric = vec3(0.04, 0.04, 0.04);
+
+            // Compute the converted diffuse.
+            surfaceAlbedo = mix(baseColor.rgb * (1.0 - DefaultSpecularReflectanceDielectric.r), vec3(0., 0., 0.), metallicRoughness.r);
+
+            // Compute the converted reflectivity.
+            surfaceReflectivityColor = mix(DefaultSpecularReflectanceDielectric, baseColor, metallicRoughness.r);
+        #endif
     #else
         #ifdef REFLECTIVITY
             vec4 surfaceReflectivityColorMap = texture2D(reflectivitySampler, vReflectivityUV + uvOffset);
@@ -657,6 +672,12 @@ void main(void) {
         environmentIrradiance *= vReflectionColor.rgb;
     #endif
 
+    // ___________________ Compute Reflectance aka R0 F0 info _________________________
+    float reflectance = max(max(surfaceReflectivityColor.r, surfaceReflectivityColor.g), surfaceReflectivityColor.b);
+    float reflectance90 = fresnelGrazingReflectance(reflectance);
+    vec3 specularEnvironmentR0 = surfaceReflectivityColor.rgb;
+    vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
     // _____________________________ Clear Coat Information ____________________________
     #ifdef CLEARCOAT
         // Clear COAT parameters.
@@ -667,12 +688,16 @@ void main(void) {
             vec2 clearCoatMapData = texture2D(clearCoatSampler, vClearCoatUV + uvOffset).rg * vClearCoatInfos.y;
             clearCoatIntensity *= clearCoatMapData.x;
             clearCoatRoughness *= clearCoatMapData.y;
-
-            // remapping and linearization of clear coat roughness
-            // Let s see how it ends up in gltf
-            // clearCoatRoughness = mix(0.089, 0.6, clearCoatRoughness);
         #endif
 
+        // remapping and linearization of clear coat roughness
+        // Let s see how it ends up in gltf
+        // clearCoatRoughness = mix(0.089, 0.6, clearCoatRoughness);
+
+        // Remap F0 to account for the change of interface within the material.
+        vec3 specularEnvironmentR0Updated = getR0RemappedForPolyurethaneClearCoat(specularEnvironmentR0);
+        specularEnvironmentR0 = mix(specularEnvironmentR0, specularEnvironmentR0Updated, clearCoatIntensity);
+
         #ifdef CLEARCOAT_BUMP
             #ifdef NORMALXYSCALE
                 float clearCoatNormalScale = 1.0;
@@ -783,15 +808,8 @@ void main(void) {
     #endif
 
     // ____________________________________________________________________________________
-    // _____________________________ Direct Lighting Param ________________________________
-        // Compute reflectance.
-        float reflectance = max(max(surfaceReflectivityColor.r, surfaceReflectivityColor.g), surfaceReflectivityColor.b);
-        float reflectance90 = fresnelGrazingReflectance(reflectance);
-        vec3 specularEnvironmentR0 = surfaceReflectivityColor.rgb;
-        vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
-
     // _____________________________ Direct Lighting Info __________________________________
-        vec3 diffuseBase = vec3(0., 0., 0.);
+    vec3 diffuseBase = vec3(0., 0., 0.);
     #ifdef SPECULARTERM
         vec3 specularBase = vec3(0., 0., 0.);
     #endif
@@ -807,11 +825,10 @@ void main(void) {
         lightmapColor *= vLightmapInfos.y;
     #endif
 
+    // Direct Lighting Variables
     preLightingInfo preInfo;
     lightingInfo info;
-
-    // 1 - shadowLevel
-    float shadow = 1.;
+    float shadow = 1.; // 1 - shadowLevel
 
     #include<lightFragment>[0..maxSimultaneousLights]
 
@@ -858,7 +875,7 @@ void main(void) {
             // We can find the scale and offset to apply to the specular value.
             vec4 environmentClearCoatBrdf = texture2D(environmentBrdfSampler, brdfClearCoatSamplerUV);
 
-            vec3 clearCoatEnvironmentReflectance = vec3(0.04) * environmentClearCoatBrdf.x + environmentClearCoatBrdf.y;
+            vec3 clearCoatEnvironmentReflectance = vec3(CLEARCOATREFLECTANCE0 * environmentClearCoatBrdf.x + environmentClearCoatBrdf.y);
 
             #ifdef RADIANCEOCCLUSION
                 float clearCoatSeo = environmentRadianceOcclusion(ambientMonochrome, clearCoatNdotVUnclamped);
@@ -878,19 +895,13 @@ void main(void) {
             vec3 clearCoatEnvironmentReflectance = fresnelSchlickEnvironmentGGX(clearCoatNdotV, vec3(1.), vec3(1.), sqrt(1. - clearCoatRoughness));
         #endif
 
-        // clear coar energy conservation
-        // fo = 4% based on the IOR of a air-polyurethane interface.
-        // the max reflectance is relying on our special trick to prevent weird values on highly diffuse materials.
-        // To let as a configuration if required
-        const float IBLClearCoatReflectance0 = 0.04;
-        const float IBLClearCoatReflectance90 = 1.;
+        clearCoatEnvironmentReflectance *= clearCoatIntensity;
 
-        float fresnelIBLClearCoat = fresnelSchlickGGXFloat(clearCoatNdotV, IBLClearCoatReflectance0, IBLClearCoatReflectance90);
+        // clear coat energy conservation
+        float fresnelIBLClearCoat = fresnelSchlickGGX(clearCoatNdotV, CLEARCOATREFLECTANCE0, CLEARCOATREFLECTANCE90);
         fresnelIBLClearCoat *= clearCoatIntensity;
-        
-        float conservationFactor = (1. - fresnelIBLClearCoat);
 
-        clearCoatEnvironmentReflectance *= clearCoatIntensity;
+        float conservationFactor = (1. - fresnelIBLClearCoat);
         #ifdef REFLECTION
             environmentIrradiance *= conservationFactor;
         #endif
@@ -1020,7 +1031,6 @@ void main(void) {
 // _______________ Not done before as it is unlit only __________________________
 // _____________________________ Diffuse ________________________________________
     vec3 finalDiffuse = diffuseBase;
-    finalDiffuse.rgb += vAmbientColor;
     finalDiffuse *= surfaceAlbedo.rgb;
     finalDiffuse = max(finalDiffuse, 0.0);
 
@@ -1043,6 +1053,7 @@ void main(void) {
 // _____________________________ Composition _____________________________________
     // Reflection already includes the environment intensity.
     vec4 finalColor = vec4(
+        vAmbientColor			* ambientOcclusionColor +
         finalDiffuse			* ambientOcclusionForDirectDiffuse * vLightingIntensity.x +
 #ifndef UNLIT
     #ifdef REFLECTION
@@ -1165,4 +1176,6 @@ void main(void) {
     //gl_FragColor = vec4(vPositionW * 0.5 + 0.5, 1.0);
 
     //gl_FragColor = vec4(vMainUV1, 0., 1.0);
+
+    //gl_FragColor = vec4(specularEnvironmentR0, 1.0);
 }