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