|
@@ -1,23 +1,5 @@
|
|
|
export default /* glsl */`
|
|
|
|
|
|
-// Analytical approximation of the DFG LUT, one half of the
|
|
|
-// split-sum approximation used in indirect specular lighting.
|
|
|
-// via 'environmentBRDF' from "Physically Based Shading on Mobile"
|
|
|
-// https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
|
|
|
-vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {
|
|
|
-
|
|
|
- const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
|
|
|
-
|
|
|
- const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
|
|
|
-
|
|
|
- vec4 r = roughness * c0 + c1;
|
|
|
-
|
|
|
- float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
|
|
|
-
|
|
|
- return vec2( - 1.04, 1.04 ) * a004 + r.zw;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
|
|
|
|
|
|
#if defined ( PHYSICALLY_CORRECT_LIGHTS )
|
|
@@ -118,6 +100,56 @@ vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 view
|
|
|
|
|
|
} // validated
|
|
|
|
|
|
+// Analytical approximation of the DFG LUT, one half of the
|
|
|
+// split-sum approximation used in indirect specular lighting.
|
|
|
+// via 'environmentBRDF' from "Physically Based Shading on Mobile"
|
|
|
+// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
|
|
|
+vec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {
|
|
|
+
|
|
|
+ float dotNV = saturate( dot( normal, viewDir ) );
|
|
|
+
|
|
|
+ const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
|
|
|
+
|
|
|
+ const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
|
|
|
+
|
|
|
+ vec4 r = roughness * c0 + c1;
|
|
|
+
|
|
|
+ float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
|
|
|
+
|
|
|
+ vec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;
|
|
|
+
|
|
|
+ return fab;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+vec3 BRDF_Specular_GGX_Environment( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {
|
|
|
+
|
|
|
+ vec2 fab = DFGApprox( normal, viewDir, roughness );
|
|
|
+
|
|
|
+ return specularColor * fab.x + specularF90 * fab.y;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
|
|
|
+// Approximates multiscattering in order to preserve energy.
|
|
|
+// http://www.jcgt.org/published/0008/01/03/
|
|
|
+void BRDF_Specular_Multiscattering_Environment( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
|
|
|
+
|
|
|
+ vec2 fab = DFGApprox( normal, viewDir, roughness );
|
|
|
+
|
|
|
+ vec3 FssEss = specularColor * fab.x + specularF90 * fab.y;
|
|
|
+
|
|
|
+ float Ess = fab.x + fab.y;
|
|
|
+ float Ems = 1.0 - Ess;
|
|
|
+
|
|
|
+ vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; // 1/21
|
|
|
+ vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );
|
|
|
+
|
|
|
+ singleScatter += FssEss;
|
|
|
+ multiScatter += Fms * Ems;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
// Rect Area Light
|
|
|
|
|
|
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
|
|
@@ -235,38 +267,6 @@ vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in m
|
|
|
|
|
|
// End Rect Area Light
|
|
|
|
|
|
-// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
|
|
|
-vec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float specularF90, const in float roughness ) {
|
|
|
-
|
|
|
- float dotNV = saturate( dot( normal, viewDir ) );
|
|
|
-
|
|
|
- vec2 brdf = integrateSpecularBRDF( dotNV, roughness );
|
|
|
-
|
|
|
- return specularColor * brdf.x + specularF90 * brdf.y;
|
|
|
-
|
|
|
-} // validated
|
|
|
-
|
|
|
-// Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting"
|
|
|
-// Approximates multiscattering in order to preserve energy.
|
|
|
-// http://www.jcgt.org/published/0008/01/03/
|
|
|
-void BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
|
|
|
-
|
|
|
- float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
|
|
|
-
|
|
|
- vec2 brdf = integrateSpecularBRDF( dotNV, roughness );
|
|
|
-
|
|
|
- vec3 FssEss = specularColor * brdf.x + specularF90 * brdf.y;
|
|
|
-
|
|
|
- float Ess = brdf.x + brdf.y;
|
|
|
- float Ems = 1.0 - Ess;
|
|
|
-
|
|
|
- vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; // 1/21
|
|
|
- vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );
|
|
|
-
|
|
|
- singleScatter += FssEss;
|
|
|
- multiScatter += Fms * Ems;
|
|
|
-
|
|
|
-}
|
|
|
|
|
|
float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) {
|
|
|
|