Merge changes I776588c1,I7292a2fb into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / graphics / shaders / default-physically-based-shader.frag
index 9a436f5..db3c146 100644 (file)
@@ -78,6 +78,11 @@ uniform mediump int uLightCount;
 uniform mediump vec3 uLightDirection[MAX_LIGHTS];
 uniform mediump vec3 uLightColor[MAX_LIGHTS];
 
+// For Shadow Map
+uniform lowp int uIsShadowEnabled;
+uniform sampler2D sShadowMap;
+in highp vec3 positionFromLightView;
+
 //// For IBL
 uniform sampler2D sbrdfLUT;
 uniform samplerCube sDiffuseEnvSampler;
@@ -102,6 +107,21 @@ out vec4 FragColor;
 const float c_MinRoughness = 0.04;
 const float M_PI = 3.141592653589793;
 
+// These properties can be used for circular sampling for PCF
+
+// Percentage Closer Filtering to mitigate the banding artifacts.
+const int kPcfSampleCount = 9;
+
+const float kPi = 3.141592653589f;
+const float kInvSampleCount = 1.0 / float(kPcfSampleCount);
+const float kPcfTheta = 2.f * kPi * kInvSampleCount;
+const float kSinPcfTheta = sin(kPcfTheta);
+const float kCosPcfTheta = cos(kPcfTheta);
+
+uniform lowp int uEnableShadowSoftFiltering;
+uniform mediump float uShadowIntensity;
+uniform mediump float uShadowBias;
+
 vec3 linear(vec3 color)
 {
   return pow(color, vec3(2.2));
@@ -117,7 +137,7 @@ void main()
   lowp float metallic = uMetallicFactor;
   lowp float perceptualRoughness = uRoughnessFactor;
   // If there isn't normal texture, use surface normal
-  mediump vec3 n = normalize(vTBN[2].xyz);
+  highp vec3 n = normalize(vTBN[2].xyz);
 
 #ifdef THREE_TEX
   // The albedo may be defined from a base texture or a flat color
@@ -222,8 +242,8 @@ void main()
 
     for(int i = 0; i < uLightCount; ++i)
     {
-      mediump vec3 l = normalize(-uLightDirection[i]);               // Vector from surface point to light
-      mediump vec3 h = normalize(l+v);                              // Half vector between both l and v
+      highp vec3 l = normalize(-uLightDirection[i]); // Vector from surface point to light
+      mediump vec3 h = normalize(l+v);               // Half vector between both l and v
       mediump float VdotH = dot(v, h);
       lowp vec3 specularReflection = f0 + (reflectance90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);
 
@@ -231,8 +251,8 @@ void main()
       lowp float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
       lowp float geometricOcclusion = attenuationL * attenuationV;
 
-      mediump float NdotH = dot(n, h);
-      lowp float f = (NdotH * roughnessSq - NdotH) * NdotH + 1.0;
+      highp float NdotH = dot(n, h);
+      highp float f = (NdotH * roughnessSq - NdotH) * NdotH + 1.0;
       lowp float microfacetDistribution = roughnessSq / (M_PI * f * f);;
 
       // Calculation of analytical lighting contribution
@@ -244,6 +264,31 @@ void main()
     }
   }
 
+  if(float(uIsShadowEnabled) * uShadowIntensity > 0.0)
+  {
+    mediump float exposureFactor = 0.0;
+    if(uEnableShadowSoftFiltering > 0)
+    {
+      ivec2 texSize = textureSize(sShadowMap, 0);
+      mediump vec2 texelSize = vec2(1.0) / vec2(texSize.x, texSize.y);
+      mediump vec2 pcfSample = vec2(1.f, 0.f);
+      for (int i = 0; i < kPcfSampleCount; ++i)
+      {
+        pcfSample = vec2(kCosPcfTheta * pcfSample.x - kSinPcfTheta * pcfSample.y,
+                         kSinPcfTheta * pcfSample.x + kCosPcfTheta * pcfSample.y);
+        lowp float depthValue = texture(sShadowMap, positionFromLightView.xy + pcfSample * texelSize).r;
+        exposureFactor += (depthValue < positionFromLightView.z - uShadowBias) ? 0.0 : 1.0;
+      }
+      exposureFactor *= kInvSampleCount;
+    }
+    else
+    {
+      mediump float depthValue = texture(sShadowMap, positionFromLightView.xy).r;
+      exposureFactor           = (depthValue < positionFromLightView.z - uShadowBias) ? 0.0 : 1.0;
+    }
+    color *= (1.0 - (1.0 - exposureFactor) * uShadowIntensity);
+  }
+
 #ifdef OCCLUSION
   lowp float ao = texture(sOcclusion, vUV).r;
   color = mix(color, color * ao, uOcclusionStrength);