Let we can use emissiveFactor without Texture
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / graphics / shaders / default-physically-based-shader.frag
index ee7eeff..fcbcd0b 100644 (file)
@@ -23,7 +23,6 @@ precision highp float;
 precision mediump float;
 #endif
 
-#ifdef THREE_TEX
 #ifdef GLTF_CHANNELS
 #define METALLIC b
 #define ROUGHNESS g
@@ -31,12 +30,12 @@ precision mediump float;
 #define METALLIC r
 #define ROUGHNESS a
 #endif //GLTF_CHANNELS
-#endif //THREE_TEX
 
 uniform lowp vec4 uColor; // Color from SceneGraph
 uniform lowp vec4 uColorFactor; // Color from material
 uniform lowp float uMetallicFactor;
 uniform lowp float uRoughnessFactor;
+uniform lowp float uDielectricSpecular;
 
 #ifdef THREE_TEX
 #ifdef BASECOLOR_TEX
@@ -59,9 +58,18 @@ uniform sampler2D sOcclusion;
 uniform float uOcclusionStrength;
 #endif
 
-#ifdef EMISSIVE
+#ifdef EMISSIVE_TEXTURE
 uniform sampler2D sEmissive;
+#endif
 uniform vec3 uEmissiveFactor;
+
+uniform float uSpecularFactor;
+uniform vec3  uSpecularColorFactor;
+#ifdef MATERIAL_SPECULAR_TEXTURE
+uniform sampler2D sSpecular;
+#endif
+#ifdef MATERIAL_SPECULAR_COLOR_TEXTURE
+uniform sampler2D sSpecularColor;
 #endif
 
 //// For IBL
@@ -77,50 +85,17 @@ uniform lowp float uMask;
 uniform lowp float uAlphaThreshold;
 
 // TODO: Multiple texture coordinate will be supported.
-in lowp vec2 vUV;
+in mediump vec2 vUV;
 in lowp mat3 vTBN;
+#ifdef COLOR_ATTRIBUTE
 in lowp vec4 vColor;
+#endif
 in highp vec3 vPositionToCamera;
 
 out vec4 FragColor;
 
-struct PBRInfo
-{
-  mediump float NdotL;        // cos angle between normal and light direction
-  mediump float NdotV;        // cos angle between normal and view direction
-  mediump float NdotH;        // cos angle between normal and half vector
-  mediump float VdotH;        // cos angle between view direction and half vector
-  mediump vec3 reflectance0;  // full reflectance color (normal incidence angle)
-  mediump vec3 reflectance90; // reflectance color at grazing angle
-  lowp float alphaRoughness;  // roughness mapped to a more linear change in the roughness (proposed by [2])
-};
-
-const float M_PI = 3.141592653589793;
 const float c_MinRoughness = 0.04;
 
-vec3 specularReflection(PBRInfo pbrInputs)
-{
-  return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
-}
-
-float geometricOcclusion(PBRInfo pbrInputs)
-{
-  mediump float NdotL = pbrInputs.NdotL;
-  mediump float NdotV = pbrInputs.NdotV;
-  lowp float r = pbrInputs.alphaRoughness;
-
-  lowp float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
-  lowp float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
-  return attenuationL * attenuationV;
-}
-
-float microfacetDistribution(PBRInfo pbrInputs)
-{
-  mediump float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
-  lowp float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
-  return roughnessSq / (M_PI * f * f);
-}
-
 vec3 linear(vec3 color)
 {
   return pow(color, vec3(2.2));
@@ -144,7 +119,11 @@ void main()
   lowp vec4 baseColor = texture(sAlbedoAlpha, vUV);
   baseColor = vec4(linear(baseColor.rgb), baseColor.w) * uColorFactor;
 #else // BASECOLOR_TEX
+#ifdef COLOR_ATTRIBUTE
   lowp vec4 baseColor = vColor * uColorFactor;
+#else // COLOR_ATTRIBUTE
+  lowp vec4 baseColor = uColorFactor;
+#endif // COLOR_ATTRIBUTE
 #endif // BASECOLOR_TEX
 
 #ifdef METALLIC_ROUGHNESS_TEX
@@ -159,7 +138,11 @@ void main()
 #endif // NORMAL_TEX
 #else // THREE_TEX
   vec4 albedoMetal = texture(sAlbedoMetal, vUV);
+#ifdef COLOR_ATTRIBUTE
   lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * vColor * uColorFactor;
+#else // COLOR_ATTRIBUTE
+  lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * uColorFactor;
+#endif // COLOR_ATTRIBUTE
 
   metallic = albedoMetal.METALLIC * metallic;
 
@@ -171,56 +154,71 @@ void main()
 #endif // THREE_TEX
 
   // The value of uOpaque and uMask can be 0.0 or 1.0.
+  // If uMask is 1.0, a Pixel that has bigger alpha than uAlphaThreashold becomes fully opaque,
+  // and, a pixel that has smaller alpha than uAlphaThreashold becomes fully transparent.
   // If uOpaque is 1.0, alpha value of final color is 1.0;
-  // If uOpaque is 0.0 and uMask is 1.0, alpha value of final color is 0.0 when input alpha is lower than uAlphaThreshold or
-  // 1.0 when input alpha is larger than uAlphaThreshold.
   // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_alphamode
+  if(uMask > 0.5 && baseColor.a < uAlphaThreshold)
+  {
+    discard;
+  }
   baseColor.a = mix(baseColor.a, 1.0, uOpaque);
-  baseColor.a = min(mix(baseColor.a, floor(baseColor.a - uAlphaThreshold + 1.0), uMask), 1.0);
 
   metallic = clamp(metallic, 0.0, 1.0);
   // Roughness is authored as perceptual roughness; as is convention,
   // convert to material roughness by squaring the perceptual roughness [2].
   perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
-  lowp float alphaRoughness = perceptualRoughness * perceptualRoughness;
-
-  lowp vec3 f0 = vec3(0.04);
-  lowp vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
-  diffuseColor *= (1.0 - metallic);
-  lowp vec3 specularColor = mix(f0, baseColor.rgb, metallic);
 
-  // Compute reflectance.
-  lowp float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+  // Material ior
+  lowp vec3 f0 = vec3(uDielectricSpecular);
 
-  // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
-  // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
-  lowp float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
-  lowp vec3 specularEnvironmentR0 = specularColor.rgb;
-  lowp vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+  // Material Specular
+  float specularWeight = 1.0;
+  vec4 materialSpecularTexture = vec4(1.0);
+#ifdef MATERIAL_SPECULAR_TEXTURE
+  materialSpecularTexture.a = texture(sSpecular, vUV).a;
+#endif
+#ifdef MATERIAL_SPECULAR_COLOR_TEXTURE
+  materialSpecularTexture.rgb = texture(sSpecularColor, vUV).rgb;
+#endif
+  specularWeight = uSpecularFactor * materialSpecularTexture.a;
+  f0 = min(f0 * uSpecularColorFactor * materialSpecularTexture.rgb, vec3(1.0));
+  f0 = mix(f0, baseColor.rgb, metallic);
 
   mediump vec3 v = normalize(vPositionToCamera); // Vector from surface point to camera
   mediump float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
   mediump vec3 reflection = -normalize(reflect(v, n));
+  lowp vec3 brdf = linear(texture(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb);
+  vec3 Fr = max(vec3(1.0 - perceptualRoughness), f0) - f0;
+  vec3 k_S = f0 + Fr * pow(1.0 - NdotV, 5.0);
+  vec3 FssEss = specularWeight * (k_S * brdf.x + brdf.y);
 
-  lowp vec3 color = vec3(0.0);
-  lowp vec3 diffuseLight = linear(texture(sDiffuseEnvSampler, n * uYDirection).rgb);
+  // Specular Light
   lowp vec3 specularLight = linear(texture(sSpecularEnvSampler, reflection * uYDirection).rgb);
-  // retrieve a scale and bias to F0. See [1], Figure 3
-  lowp vec3 brdf = linear(texture(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb);
+  lowp vec3 specular = specularLight * FssEss;
 
-  lowp vec3 diffuse = diffuseLight * diffuseColor;
-  lowp vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
-  color += (diffuse + specular) * uIblIntensity;
+  // Diffuse Light
+  lowp vec3 diffuseColor = mix(baseColor.rgb, vec3(0), metallic);
+  lowp vec3 irradiance = linear(texture(sDiffuseEnvSampler, n * uYDirection).rgb);
+  float Ems = (1.0 - (brdf.x + brdf.y));
+  vec3 F_avg = specularWeight * (f0 + (1.0 - f0) / 21.0);
+  vec3 FmsEms = Ems * FssEss * F_avg / (1.0 - F_avg * Ems);
+  vec3 k_D = diffuseColor * (1.0 - FssEss + FmsEms);
+  lowp vec3 diffuse = (FmsEms + k_D) * irradiance;
+
+  lowp vec3 color = (diffuse + specular) * uIblIntensity;
 
 #ifdef OCCLUSION
   lowp float ao = texture(sOcclusion, vUV).r;
   color = mix(color, color * ao, uOcclusionStrength);
 #endif // OCCLUSION
 
-#ifdef EMISSIVE
+#ifdef EMISSIVE_TEXTURE
   lowp vec3 emissive = linear(texture(sEmissive, vUV).rgb) * uEmissiveFactor;
+#else
+  lowp vec3 emissive = uEmissiveFactor;
+#endif // EMISSIVE_TEXTURE
   color += emissive;
-#endif // EMISSIVE
 
   FragColor = vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a) * uColor;
 }