[dali_2.0.7] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / resources / dli_pbr.fsh
1 #version 300 es\r
2 \r
3 #ifdef HIGHP\r
4   precision highp float;\r
5 #else\r
6   precision mediump float;\r
7 #endif\r
8 \r
9 #ifdef THREE_TEX\r
10 #ifdef GLTF_CHANNELS\r
11 // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture\r
12 #define METALLIC b\r
13 #define ROUGHNESS g\r
14 #else //GLTF_CHANNELS\r
15 #define METALLIC r\r
16 #define ROUGHNESS a\r
17 #endif //GLTF_CHANNELS\r
18 #endif //THREE_TEX\r
19 \r
20 #ifdef THREE_TEX\r
21   uniform sampler2D sAlbedoAlpha;\r
22   uniform sampler2D sMetalRoughness;\r
23   uniform sampler2D sNormal;\r
24 \r
25 #ifdef ALPHA_TEST\r
26   uniform float uAlphaThreshold;\r
27 #endif  //ALPHA_TEST\r
28 \r
29 #else\r
30   uniform sampler2D sAlbedoMetal;\r
31   uniform sampler2D sNormalRoughness;\r
32 #endif\r
33 \r
34 uniform samplerCube sDiffuse;\r
35 uniform samplerCube sSpecular;\r
36 \r
37 // Number of mip map levels in the texture\r
38 uniform float uMaxLOD;\r
39 \r
40 // Transformation matrix of the cubemap texture\r
41 uniform mat4 uCubeMatrix;\r
42 \r
43 uniform vec4 uColor;\r
44 uniform float uMetallicFactor;\r
45 uniform float uRoughnessFactor;\r
46 \r
47 //IBL Light intensity\r
48 uniform float uIblIntensity;\r
49 \r
50 in vec2 vUV;\r
51 in vec3 vNormal;\r
52 in vec3 vTangent;\r
53 in vec3 vViewVec;\r
54 \r
55 out vec4 FragColor;\r
56 \r
57 // Functions for BRDF calculation come from\r
58 // https://www.unrealengine.com/blog/physically-based-shading-on-mobile\r
59 // Based on the paper by Dimitar Lazarov\r
60 // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf\r
61 vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )\r
62 {\r
63   const vec4 c0 = vec4( -1.0, -0.0275, -0.572, 0.022 );\r
64   const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04 );\r
65   vec4 r = Roughness * c0 + c1;\r
66   float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;\r
67   vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\r
68 \r
69   return SpecularColor * AB.x + AB.y;\r
70 }\r
71 \r
72 void main()\r
73 {\r
74   // We get information from the maps (albedo, normal map, roughness, metalness\r
75   // I access the maps in the order they will be used\r
76 #ifdef THREE_TEX\r
77   vec4 albedoAlpha = texture(sAlbedoAlpha, vUV.st);\r
78   float alpha = albedoAlpha.a;\r
79 #ifdef ALPHA_TEST\r
80   if (alpha <= uAlphaThreshold)\r
81   {\r
82     discard;\r
83   }\r
84 #endif  //ALPHA_TEST\r
85   vec3 albedoColor = albedoAlpha.rgb * uColor.rgb;\r
86 \r
87   vec4 metalRoughness = texture(sMetalRoughness, vUV.st);\r
88   float metallic = metalRoughness.METALLIC * uMetallicFactor;\r
89   float roughness = metalRoughness.ROUGHNESS * uRoughnessFactor;\r
90 \r
91   vec3 normalMap = texture(sNormal, vUV.st).rgb;\r
92 #else  //THREE_TEX\r
93   vec4 albedoMetal = texture(sAlbedoMetal, vUV.st);\r
94   vec3 albedoColor = albedoMetal.rgb * uColor.rgb;\r
95   float metallic = albedoMetal.a * uMetallicFactor;\r
96 \r
97   vec4 normalRoughness = texture(sNormalRoughness, vUV.st);\r
98   vec3 normalMap = normalRoughness.rgb;\r
99   float roughness = normalRoughness.a * uRoughnessFactor;\r
100 #endif\r
101   //Normalize vectors\r
102   vec3 normal = normalize(vNormal);\r
103   vec3 tangent = normalize(vTangent);\r
104 \r
105   // NOTE: normal and tangent have to be orthogonal for the result of the cross()\r
106   // product to be a unit vector. We might find that we need to normalize().\r
107   vec3 bitangent = cross(normal, tangent);\r
108 \r
109   vec3 viewVec = normalize(vViewVec);\r
110 \r
111   // Create Inverse Local to world matrix\r
112   mat3 vInvTBN = mat3(tangent, bitangent, normal);\r
113 \r
114   // Get normal map info in world space\r
115   normalMap = normalize(normalMap - 0.5);\r
116   vec3 newNormal = vInvTBN * normalMap.rgb;\r
117 \r
118   // Calculate normal dot view vector\r
119   float NoV = max(dot(newNormal, -viewVec), 0.0);\r
120 \r
121   // Reflect vector\r
122   vec3 reflectionVec = reflect(viewVec, newNormal);\r
123 \r
124   //transform it now to environment coordinates (used when the environment rotates)\r
125   vec3 reflecCube = (uCubeMatrix * vec4( reflectionVec, 0.0 ) ).xyz;\r
126   reflecCube = normalize( reflecCube );\r
127 \r
128   //transform it now to environment coordinates\r
129   vec3 normalCube = ( uCubeMatrix * vec4( newNormal, 0.0 ) ).xyz;\r
130   normalCube = normalize( normalCube );\r
131 \r
132   // Get irradiance from diffuse cubemap\r
133   vec3 irradiance = texture( sDiffuse, normalCube ).rgb;\r
134 \r
135   // Access reflection color using roughness value\r
136   float finalLod = mix( 0.0, uMaxLOD - 2.0, roughness);\r
137   vec3 reflectionColor = textureLod(sSpecular, reflecCube, finalLod).rgb;\r
138 \r
139   // We are supposed to be using DielectricColor (0.04) of a plastic (almost everything)\r
140   // http://blog.selfshadow.com/publications/s2014-shading-course/hoffman/s2014_pbs_physics_math_slides.pdf\r
141   // however that seems to prevent achieving very dark tones (i.e. get dark gray blacks).\r
142   vec3 DiffuseColor = albedoColor - albedoColor * metallic;  // 1 mad\r
143   vec3 SpecularColor = mix( vec3(0.04), albedoColor, metallic); // 2 mad\r
144 \r
145   // Calculate specular color using Magic Function (takes original roughness and normal dot view).\r
146   vec3 specColor =  reflectionColor.rgb * EnvBRDFApprox(SpecularColor, roughness, NoV );\r
147 \r
148   // Multiply the result by albedo texture and do energy conservation\r
149   vec3 diffuseColor = irradiance * DiffuseColor;\r
150 \r
151   // Final color is the sum of the diffuse and specular term\r
152   vec3 finalColor = diffuseColor + specColor;\r
153 \r
154   finalColor = sqrt( finalColor ) * uIblIntensity;\r
155 #ifdef THREE_TEX\r
156   FragColor = vec4( finalColor, alpha );\r
157 #else //THREE_TEX\r
158   FragColor = vec4( finalColor, 1.0 );\r
159 #endif //THREE_TEX\r
160 }\r