Ver código fonte

Adding support for Specular-AA (#2141)

* Fixes Issue #2132

* jme3-core:Adding support for Specular-AA

* jme3-core:del Specular_Anti_Aliasing2

* jme3-core:update Specular_Anti_Aliasing

* jme3-core:update Specular_Anti_Aliasing

* jme3-core:add MatParam:Sigma,Kappa

* jme3-terrain:Adding support for Specular-AA

* jme3-core:update PBRLighting.j3md(with SpecularAA)

* jme3-terrain:update PBRTerrain.j3md(with SpecularAA)

* jmee-core:remove the "f" suffix

* jmee-terrain:remove the "f" suffix

* jme3-core:Updated parameter names in PBRLighting.j3md

* jme3-terrain:Updated parameter names in PBRTerrain.j3md/AdvacedPBRTerrain.j3md

* jme3-core:Updated macro definitions in PBRLighting.j3md

* jme3-terrain:Updated macro definitions in PBRTerrain.j3md/AdvancedPBRTerrain.j3md

---------

Co-authored-by: chenliming <[email protected]>
John_R_Kkk 1 ano atrás
pai
commit
3ec59c87c8

+ 30 - 4
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag

@@ -98,6 +98,14 @@ varying vec3 wPosition;
 #endif
 varying vec3 wNormal;
 
+// Specular-AA
+#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+  uniform float m_SpecularAASigma;
+#endif
+#ifdef SPECULAR_AA_THRESHOLD
+  uniform float m_SpecularAAKappa;
+#endif
+
 #ifdef DISCARD_ALPHA
   uniform float m_AlphaDiscardThreshold;
 #endif
@@ -247,6 +255,16 @@ void main(){
        ao = clamp(ao, 0.0, 1.0);
     #endif
 
+    #ifdef SPECULAR_AA
+        float sigma = 1.0;
+        float kappa = 0.18;
+        #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+            sigma = m_SpecularAASigma;
+        #endif
+        #ifdef SPECULAR_AA_THRESHOLD
+            kappa = m_SpecularAAKappa;
+        #endif
+    #endif
     float ndotv = max( dot( normal, viewDir ),0.0);
     for( int i = 0;i < NB_LIGHTS; i+=3){
         vec4 lightColor = g_LightData[i];
@@ -270,10 +288,18 @@ void main(){
         lightDir.xyz = normalize(lightDir.xyz);            
         vec3 directDiffuse;
         vec3 directSpecular;
-        
-        float hdotv = PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
-                            lightColor.rgb, fZero, Roughness, ndotv,
-                            directDiffuse,  directSpecular);
+
+        #ifdef SPECULAR_AA
+            float hdotv = PBR_ComputeDirectLightWithSpecularAA(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv,
+                                directDiffuse,  directSpecular);
+        #else
+            float hdotv = PBR_ComputeDirectLight(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, ndotv,
+                                directDiffuse,  directSpecular);
+        #endif
 
         vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;
         

+ 10 - 0
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md

@@ -56,6 +56,13 @@ MaterialDef PBR Lighting {
         // Parallax/height map
         Texture2D ParallaxMap -LINEAR
 
+        // Specular-AA
+        Boolean UseSpecularAA : true
+        // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing.
+        Float SpecularAASigma
+        // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts.
+        Float SpecularAAKappa
+
         //Set to true if parallax map is stored in the alpha channel of the normal map
         Boolean PackedNormalParallax   
 
@@ -163,6 +170,9 @@ MaterialDef PBR Lighting {
             USE_PACKED_MR: MetallicRoughnessMap
             USE_PACKED_SG: SpecularGlossinessMap
             SPECULARMAP : SpecularMap
+            SPECULAR_AA : UseSpecularAA
+            SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma
+            SPECULAR_AA_THRESHOLD : SpecularAAKappa
             GLOSSINESSMAP : GlossinessMap
             NORMAL_TYPE: NormalType
             VERTEX_COLOR : UseVertexColor

+ 45 - 7
jme3-core/src/main/resources/Common/ShaderLib/PBR.glsllib

@@ -6,6 +6,22 @@
     #define NB_PROBES 0
 #endif
 
+// BEGIN-@jhonkkk,Specular AA --------------------------------------------------------------
+// see:http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA(slides).pdf
+// https://docs.unity3d.com/Packages/[email protected]/manual/Geometric-Specular-Anti-Aliasing.html
+float Specular_Anti_Aliasing(in vec3 normal, in vec3 half_vector,
+                           	float alpha, in float sigma, in float kappa)
+{
+
+    vec3 dndu = dFdx(normal);
+    vec3 dndv = dFdy(normal);
+    float  variance = sigma*sigma*(dot(dndu, dndu) + dot(dndv, dndv));
+    float  kernel_roughness = min(kappa, variance);
+    return sqrt(alpha*alpha + kernel_roughness);
+}
+// END-@jhonkkk
+
+
 //Specular fresnel computation
 vec3 F_Shlick(float vh,	vec3 F0){
 	float fresnelFact = pow(2.0, (-5.55473*vh - 6.98316) * vh);
@@ -34,12 +50,11 @@ vec3 sphericalHarmonics( const in vec3 normal, const vec3 sph[9] ){
     return max(result, vec3(0.0));
 }
 
-
-float PBR_ComputeDirectLight(vec3 normal, vec3 lightDir, vec3 viewDir,
-                            vec3 lightColor, vec3 fZero, float roughness, float ndotv,
+// BEGIN-@jhonkkk,todo:Keeping the original PBR_ComputeDirectLight function signature is for backwards compatibility, but this adds an extra internal function call, theoretically here we should use a macro to define Inner_PBR_ComputeDirectLight, or best to calculate alpha externally and directly call the Inner_PBR_ComputeDirectLight function.
+float Inner_PBR_ComputeDirectLight(
+                            vec3 normal, vec3 halfVec, vec3 lightDir, vec3 viewDir,
+                            vec3 lightColor, vec3 fZero, float alpha, float ndotv,
                             out vec3 outDiffuse, out vec3 outSpecular){
-    // Compute halfway vector.
-    vec3 halfVec = normalize(lightDir + viewDir);
 
     // Compute ndotl, ndoth,  vdoth terms which are needed later.
     float ndotl = max( dot(normal,   lightDir), 0.0);
@@ -53,8 +68,6 @@ float PBR_ComputeDirectLight(vec3 normal, vec3 lightDir, vec3 viewDir,
 
     //cook-torrence, microfacet BRDF : http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
    
-    float alpha = roughness * roughness;
-
     //D, GGX normal Distribution function
     float alpha2 = alpha * alpha;
     float sum  = ((ndoth * ndoth) * (alpha2 - 1.0) + 1.0);
@@ -89,6 +102,31 @@ float PBR_ComputeDirectLight(vec3 normal, vec3 lightDir, vec3 viewDir,
     return hdotv;
 }
 
+float PBR_ComputeDirectLight(
+                            vec3 normal, vec3 lightDir, vec3 viewDir,
+                            vec3 lightColor, vec3 fZero, float roughness, float ndotv,
+                            out vec3 outDiffuse, out vec3 outSpecular){
+    // Compute halfway vector.
+    vec3 halfVec = normalize(lightDir + viewDir);
+    return Inner_PBR_ComputeDirectLight(normal, halfVec, lightDir, viewDir,
+                                        lightColor, fZero, roughness * roughness, ndotv,
+                                        outDiffuse, outSpecular);
+}
+
+float PBR_ComputeDirectLightWithSpecularAA(
+                            vec3 normal, vec3 lightDir, vec3 viewDir,
+                            vec3 lightColor, vec3 fZero, float roughness, float sigma, float kappa, float ndotv,
+                            out vec3 outDiffuse, out vec3 outSpecular){
+    // Compute halfway vector.
+    vec3 halfVec = normalize(lightDir + viewDir);
+    // Specular-AA
+    float alpha = Specular_Anti_Aliasing(normal, halfVec, roughness * roughness, sigma, kappa);
+    return Inner_PBR_ComputeDirectLight(normal, halfVec, lightDir, viewDir,
+                                        lightColor, fZero, alpha, ndotv,
+                                        outDiffuse, outSpecular);
+}
+// END-@jhonkkk
+
 vec3 integrateBRDFApprox( const in vec3 specular, float roughness, float NoV ){
     const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 );
     const vec4 c1 = vec4( 1, 0.0425, 1.04, -0.04 );

+ 29 - 3
jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.frag

@@ -17,6 +17,14 @@ varying vec3 lightVec;
 varying vec3 inNormal;
 varying vec3 wNormal;
 
+// Specular-AA
+#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+  uniform float m_SpecularAASigma;
+#endif
+#ifdef SPECULAR_AA_THRESHOLD
+  uniform float m_SpecularAAKappa;
+#endif
+
 #ifdef DEBUG_VALUES_MODE
     uniform int m_DebugValuesMode;
 #endif
@@ -485,6 +493,16 @@ void main(){
     
      
     float ndotv = max( dot( normal, viewDir ),0.0);
+    #ifdef SPECULAR_AA
+        float sigma = 1.0;
+        float kappa = 0.18;
+        #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+            sigma = m_SpecularAASigma;
+        #endif
+        #ifdef SPECULAR_AA_THRESHOLD
+            kappa = m_SpecularAAKappa;
+        #endif
+    #endif
     for( int i = 0;i < NB_LIGHTS; i+=3){
         vec4 lightColor = g_LightData[i];
         vec4 lightData1 = g_LightData[i+1];                
@@ -508,9 +526,17 @@ void main(){
         vec3 directDiffuse;
         vec3 directSpecular;
         
-        float hdotv = PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
-                            lightColor.rgb, fZero, Roughness, ndotv,
-                            directDiffuse,  directSpecular);
+        #ifdef SPECULAR_AA
+            float hdotv = PBR_ComputeDirectLightWithSpecularAA(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv,
+                                directDiffuse,  directSpecular);
+        #else
+            float hdotv = PBR_ComputeDirectLight(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, ndotv,
+                                directDiffuse,  directSpecular);
+        #endif
 
         vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;
             

+ 11 - 0
jme3-terrain/src/main/resources/Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md

@@ -27,6 +27,13 @@ MaterialDef Advanced PBR Terrain {
      // affliction texture splatting & desaturation functionality
         Boolean UseTriplanarAfflictionMapping
 
+        // Specular-AA
+        Boolean UseSpecularAA : true
+        // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing.
+        Float SpecularAASigma
+        // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts.
+        Float SpecularAAKappa
+
         Texture2D AfflictionAlphaMap
 
         Texture2D SplatAlbedoMap  -LINEAR
@@ -280,6 +287,10 @@ MaterialDef Advanced PBR Terrain {
             AFFLICTIONEMISSIVEMAP : SplatEmissiveMap
             USE_SPLAT_NOISE : SplatNoiseVar
 
+            SPECULAR_AA : UseSpecularAA
+            SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma
+            SPECULAR_AA_THRESHOLD : SpecularAAKappa
+
             TRI_PLANAR_MAPPING : useTriPlanarMapping
 
             DISCARD_ALPHA : AlphaDiscardThreshold

+ 29 - 3
jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.frag

@@ -17,6 +17,14 @@ varying vec3 lightVec;
 varying vec3 inNormal;
 varying vec3 wNormal;
 
+// Specular-AA
+#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+  uniform float m_SpecularAASigma;
+#endif
+#ifdef SPECULAR_AA_THRESHOLD
+  uniform float m_SpecularAAKappa;
+#endif
+
 #ifdef DEBUG_VALUES_MODE
     uniform int m_DebugValuesMode;
 #endif
@@ -417,6 +425,16 @@ gl_FragColor.rgb = vec3(0.0);
     
      
     float ndotv = max( dot( normal, viewDir ),0.0);
+    #ifdef SPECULAR_AA
+        float sigma = 1.0;
+        float kappa = 0.18;
+        #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
+            sigma = m_SpecularAASigma;
+        #endif
+        #ifdef SPECULAR_AA_THRESHOLD
+            kappa = m_SpecularAAKappa;
+        #endif
+    #endif
     for( int i = 0;i < NB_LIGHTS; i+=3){
         vec4 lightColor = g_LightData[i];
         vec4 lightData1 = g_LightData[i+1];                
@@ -440,9 +458,17 @@ gl_FragColor.rgb = vec3(0.0);
         vec3 directDiffuse;
         vec3 directSpecular;
         
-        float hdotv = PBR_ComputeDirectLight(normal, lightDir.xyz, viewDir,
-                            lightColor.rgb, fZero, Roughness, ndotv,
-                            directDiffuse,  directSpecular);
+        #ifdef SPECULAR_AA
+            float hdotv = PBR_ComputeDirectLightWithSpecularAA(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv,
+                                directDiffuse,  directSpecular);
+        #else
+            float hdotv = PBR_ComputeDirectLight(
+                                normal, lightDir.xyz, viewDir,
+                                lightColor.rgb, fZero, Roughness, ndotv,
+                                directDiffuse,  directSpecular);
+        #endif
 
         vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;
             

+ 11 - 0
jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.j3md

@@ -24,6 +24,13 @@ MaterialDef PBR Terrain {
         Texture2D SplatRoughnessMetallicMap -LINEAR
         Texture2D SplatEmissiveMap -LINEAR
 
+        // Specular-AA
+        Boolean UseSpecularAA : true
+        // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing.
+        Float SpecularAASigma
+        // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts.
+        Float SpecularAAKappa
+
         Color AfflictionEmissiveColor : 0.0 0.0 0.0 0.0
 
         Float SplatNoiseVar
@@ -256,6 +263,10 @@ MaterialDef PBR Terrain {
 
             USE_SPLAT_NOISE : SplatNoiseVar
 
+            SPECULAR_AA : UseSpecularAA
+            SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma
+            SPECULAR_AA_THRESHOLD : SpecularAAKappa
+
 
             USE_VERTEX_COLORS_AS_SUN_INTENSITY : UseVertexColorsAsSunIntensity
             STATIC_SUN_INTENSITY : StaticSunIntensity