[Tizen] Scene, Scene Loader, and glTF Loader
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scene / gltf-shader.h
1 #ifndef DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H
2 #define DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H
3
4 /*
5  * Belows Vertex Shader and Fragment Shader code are based off glTF WebGL PBR.
6  * https://github.com/KhronosGroup/glTF-WebGL-PBR/
7  *
8  * Copyright (c) 2016-2017 Mohamad Moneimne and Contributors
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  */
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 const char* GLES_VERSION_300 = {
39   "#version 300 es\n\n"
40   "precision highp float;\n\n"
41 };
42
43 const char* DEFINE_BASECOLOR_TEXTURE = {
44   "#define TEXTURE_BASECOLOR\n\n"
45   "uniform sampler2D uBaseColorSampler;\n"
46   "uniform int uBaseColorTexCoordIndex;\n\n"
47 };
48
49 const char* DEFINE_METALLICROUGHNESS_TEXTURE = {
50   "#define TEXTURE_METALLICROUGHNESS\n\n"
51   "uniform sampler2D uMetallicRoughnessSampler;\n"
52   "uniform int uMetallicRoughnessTexCoordIndex;\n\n"
53 };
54
55 const char* DEFINE_NORMAL_TEXTURE = {
56   "#define TEXTURE_NORMAL\n\n"
57   "uniform sampler2D uNormalSampler;\n"
58   "uniform float uNormalScale;\n"
59   "uniform int uNormalTexCoordIndex;\n\n"
60 };
61
62 const char* DEFINE_OCCLUSION_TEXTURE = {
63   "#define TEXTURE_OCCLUSION\n\n"
64   "uniform sampler2D uOcclusionSampler;\n"
65   "uniform int uOcclusionTexCoordIndex;\n"
66   "uniform float uOcclusionStrength;\n\n"
67 };
68
69 const char* DEFINE_EMIT_TEXTURE = {
70   "#define TEXTURE_EMIT\n\n"
71   "uniform sampler2D uEmissiveSampler;\n"
72   "uniform int uEmissiveTexCoordIndex;\n"
73   "uniform vec3 uEmissiveFactor;\n\n"
74 };
75
76 const char* DEFINE_IBL_TEXTURE = {
77   "#define TEXTURE_IBL\n\n"
78   "uniform sampler2D ubrdfLUT;\n"
79   "uniform samplerCube uDiffuseEnvSampler;\n"
80   "uniform samplerCube uSpecularEnvSampler;\n"
81   "uniform vec4 uScaleIBLAmbient;\n"
82   "uniform highp float uMipmapLevel;\n"
83 };
84
85 const char* PHYSICALLY_BASED_VERTEX_SHADER = {
86   "in highp vec3 aPosition;\n"
87   "in highp vec2 aTexCoord0;\n"
88   "in highp vec2 aTexCoord1;\n"
89   "in highp vec3 aNormal;\n"
90   "in highp vec4 aTangent;\n"
91   "in highp vec4 aVertexColor;\n"
92
93   "uniform mediump vec3 uSize;\n"
94   "uniform mediump mat4 uModelMatrix;\n"
95   "uniform mediump mat4 uViewMatrix;\n"
96   "uniform mediump mat4 uProjection;\n"
97   "uniform mediump mat4 uMvpMatrix;\n"
98   "uniform mediump mat3 uNormalMatrix;\n"
99   "uniform mediump int uLightType;\n"
100   "uniform mediump vec3 uLightVector;\n"
101   "uniform mediump int uIsColor;\n"
102
103   "out vec2 vUV[2];\n"
104   "out mat3 vTBN;\n"
105   "out vec4 vColor;\n"
106   "flat out int visLight;\n"
107   "out vec3 vLightDirection;\n"
108   "out vec3 vPositionToCamera;\n"
109
110   "void main()\n"
111   "{\n"
112   "  vec4 invY = vec4(1.0, -1.0, 1.0, 1.0);\n"
113   "  vec4 positionW = uModelMatrix * vec4( aPosition * uSize, 1.0 );\n"
114   "  vec4 positionV = uViewMatrix * ( invY * positionW );\n"
115
116   "  vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) );\n"
117   "  vPositionToCamera *= vec3( invY );\n"
118
119   "  vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w;\n"
120   "  vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal);\n"
121
122   "  vUV[0] = aTexCoord0;\n"
123   "  vUV[1] = aTexCoord1;\n"
124
125   "  visLight = 0;\n"
126   "  if( uLightType == 1 )\n"
127   "  {\n"
128   "    vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w );\n"
129   "  }\n"
130   "  else if( uLightType == 2 )\n"
131   "  {\n"
132   "    vLightDirection = -( invY.xyz * uLightVector );\n"
133   "  }\n"
134   "  else\n"
135   "  {\n"
136   "    visLight = 0;\n"
137   "  }\n"
138
139   "  vColor = vec4( 1.0 );\n"
140   "  if( uIsColor == 1 )\n"
141   "  {\n"
142   "    vColor = aVertexColor;\n"
143   "  }\n"
144
145   "  gl_Position = uProjection * positionV;\n" // needs w for proper perspective correction
146   "  gl_Position = gl_Position/gl_Position.w;\n"
147   "}\n"
148 };
149
150 const char* PHYSICALLY_BASED_FRAGMENT_SHADER = {
151   "uniform vec3 uLightColor;\n"
152   "uniform vec4 uBaseColorFactor;\n"
153   "uniform vec2 uMetallicRoughnessFactors;\n"
154   "uniform int alphaMode;\n"
155   "uniform float alphaCutoff;\n"
156
157   "in vec2 vUV[2];\n"
158   "in mat3 vTBN;\n"
159   "in vec4 vColor;\n"
160   "flat in int visLight;\n"
161   "in vec3 vLightDirection;\n"
162   "in vec3 vPositionToCamera;\n"
163
164   "out vec4 FragColor;"
165
166   "struct PBRInfo\n"
167   "{\n"
168   "  float NdotL;\n"                  // cos angle between normal and light direction
169   "  float NdotV;\n"                  // cos angle between normal and view direction
170   "  float NdotH;\n"                  // cos angle between normal and half vector
171   "  float LdotH;\n"                  // cos angle between light direction and half vector
172   "  float VdotH;\n"                  // cos angle between view direction and half vector
173   "  float perceptualRoughness;\n"    // roughness value, as authored by the model creator (input to shader)
174   "  float metalness;\n"              // metallic value at the surface
175   "  vec3 reflectance0;\n"            // full reflectance color (normal incidence angle)
176   "  vec3 reflectance90;\n"           // reflectance color at grazing angle
177   "  float alphaRoughness;\n"         // roughness mapped to a more linear change in the roughness (proposed by [2])
178   "  vec3 diffuseColor;\n"            // color contribution from diffuse lighting
179   "  vec3 specularColor;\n"           // color contribution from specular lighting
180   "};\n"
181
182   "const float M_PI = 3.141592653589793;\n"
183   "const float c_MinRoughness = 0.04;\n"
184
185   "vec3 getNormal()\n"
186   "{\n"
187   "#ifdef TEXTURE_NORMAL\n"
188   "  vec3 n = texture( uNormalSampler, vUV[uNormalTexCoordIndex] ).rgb;\n"
189   "  n = normalize( vTBN * ( ( 2.0 * n - 1.0 ) * vec3( uNormalScale, uNormalScale, 1.0 ) ) );\n"
190   "#else\n"
191   "  vec3 n = normalize( vTBN[2].xyz );\n"
192   "#endif\n"
193   "  return n;\n"
194   "}\n"
195
196   "vec3 specularReflection( PBRInfo pbrInputs )\n"
197   "{\n"
198   "  return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 );\n"
199   "}\n"
200
201   "float geometricOcclusion( PBRInfo pbrInputs )\n"
202   "{\n"
203   "  float NdotL = pbrInputs.NdotL;\n"
204   "  float NdotV = pbrInputs.NdotV;\n"
205   "  float r = pbrInputs.alphaRoughness;\n"
206
207   "  float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n"
208   "  float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n"
209   "  return attenuationL * attenuationV;\n"
210   "}\n"
211
212   "float microfacetDistribution(PBRInfo pbrInputs)\n"
213   "{\n"
214   "  float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;\n"
215   "  float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;\n"
216   "  return roughnessSq / (M_PI * f * f);\n"
217   "}\n"
218
219   "vec3 linear( vec3 color )\n"
220   "{\n"
221   "  return pow(color,vec3(2.2));\n"
222   "}\n"
223
224   "void main()\n"
225   "{\n"
226   // Metallic and Roughness material properties are packed together
227   // In glTF, these factors can be specified by fixed scalar values
228   // or from a metallic-roughness map
229   "  float metallic = uMetallicRoughnessFactors.x;\n"
230   "  float perceptualRoughness = uMetallicRoughnessFactors.y;\n"
231
232   // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
233   // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
234   "#ifdef TEXTURE_METALLICROUGHNESS\n"
235   "  vec4 metrou = texture(uMetallicRoughnessSampler, vUV[uMetallicRoughnessTexCoordIndex]);\n"
236   "  metallic = metrou.b * metallic;\n"
237   "  perceptualRoughness = metrou.g * perceptualRoughness;\n"
238   "#endif\n"
239
240   "  metallic = clamp(metallic, 0.0, 1.0);\n"
241   "  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n"
242   // Roughness is authored as perceptual roughness; as is convention,
243   // convert to material roughness by squaring the perceptual roughness [2].
244   "  float alphaRoughness = perceptualRoughness * perceptualRoughness;\n"
245
246   "#ifdef TEXTURE_BASECOLOR\n"
247   // The albedo may be defined from a base texture or a flat color
248   "  vec4 baseColor = texture(uBaseColorSampler, vUV[uBaseColorTexCoordIndex]) * uBaseColorFactor;\n"
249   "  baseColor = vec4(linear(baseColor.rgb), baseColor.w);\n"
250   "#else\n"
251   "  vec4 baseColor = vColor * uBaseColorFactor;\n"
252   "#endif\n"
253
254   "  if( alphaMode == 0 )\n"
255   "  {\n"
256   "    baseColor.w = 1.0;\n"
257   "  }\n"
258   "  else if( alphaMode == 1 )\n"
259   "  {\n"
260   "    if( baseColor.w >= alphaCutoff )"
261   "    {\n"
262   "      baseColor.w = 1.0;\n"
263   "    }\n"
264   "    else\n"
265   "    {\n"
266   "      baseColor.w = 0.0;\n"
267   "    }\n"
268   "  }\n"
269
270   "  vec3 f0 = vec3(0.04);\n"
271   "  vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);\n"
272   "  diffuseColor *= ( 1.0 - metallic );\n"
273   "  vec3 specularColor = mix(f0, baseColor.rgb, metallic);\n"
274
275   // Compute reflectance.
276   "  float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n"
277
278   // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
279   // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
280   "  float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n"
281   "  vec3 specularEnvironmentR0 = specularColor.rgb;\n"
282   "  vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;\n"
283
284   "  vec3 n = getNormal();\n"                            // normal at surface point
285   "  vec3 v = normalize(vPositionToCamera);\n"           // Vector from surface point to camera
286   "  vec3 l = normalize(vLightDirection);\n"             // Vector from light to surface point
287   "  vec3 h = normalize(l+v);\n"                         // Half vector between both l and v
288   "  vec3 reflection = -normalize(reflect(v, n));\n"
289
290   "  float NdotL = clamp(dot(n, l), 0.001, 1.0);\n"
291   "  float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n"
292   "  float NdotH = clamp(dot(n, h), 0.0, 1.0);\n"
293   "  float LdotH = clamp(dot(l, h), 0.0, 1.0);\n"
294   "  float VdotH = clamp(dot(v, h), 0.0, 1.0);\n"
295
296   "  PBRInfo pbrInputs = PBRInfo(\n"
297   "    NdotL,\n"
298   "    NdotV,\n"
299   "    NdotH,\n"
300   "    LdotH,\n"
301   "    VdotH,\n"
302   "    perceptualRoughness,\n"
303   "    metallic,\n"
304   "    specularEnvironmentR0,\n"
305   "    specularEnvironmentR90,\n"
306   "    alphaRoughness,\n"
307   "    diffuseColor,\n"
308   "    specularColor\n"
309   "  );\n"
310
311   // Calculate the shading terms for the microfacet specular shading model
312   "  vec3 color = vec3(0.0);\n"
313   "  if( visLight == 1 )\n"
314   "  {\n"
315   "    vec3 F = specularReflection(pbrInputs);\n"
316   "    float G = geometricOcclusion(pbrInputs);\n"
317   "    float D = microfacetDistribution(pbrInputs);\n"
318
319   // Calculation of analytical lighting contribution
320   "    vec3 diffuseContrib = (1.0 - F) * ( pbrInputs.diffuseColor / M_PI );\n"
321   "    vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);\n"
322   // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
323   "    color = NdotL * uLightColor * (diffuseContrib + specContrib);\n"
324   "  }\n"
325
326   "#ifdef TEXTURE_IBL\n"
327   "  float lod = (pbrInputs.perceptualRoughness * uMipmapLevel);\n"
328   // retrieve a scale and bias to F0. See [1], Figure 3
329   "  vec3 brdf = linear(texture(ubrdfLUT, vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness)).rgb);\n"
330   "  vec3 diffuseLight = linear(texture(uDiffuseEnvSampler, n).rgb);\n"
331   "  vec3 specularLight = linear(textureLod(uSpecularEnvSampler, reflection, lod).rgb);\n"
332
333   "  vec3 diffuse = diffuseLight * pbrInputs.diffuseColor;\n"
334   "  vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y);\n"
335   "  diffuse *= uScaleIBLAmbient.x;\n"
336   "  specular *= uScaleIBLAmbient.y;\n"
337   "  color += (diffuse+specular);\n"
338   "#endif\n"
339
340   "#ifdef TEXTURE_OCCLUSION\n"
341   "  float ao = texture(uOcclusionSampler, vUV[uOcclusionTexCoordIndex]).r;\n"
342   "  color = mix(color, color * ao, uOcclusionStrength);\n"
343   "#endif\n"
344
345   "#ifdef TEXTURE_EMIT\n"
346   "  vec3 emissive = linear(texture(uEmissiveSampler, vUV[uEmissiveTexCoordIndex]).rgb) * uEmissiveFactor;\n"
347   "  color += emissive;\n"
348   "#endif\n"
349
350   "  FragColor = vec4(pow(color,vec3(1.0/2.2)), baseColor.a);\n"
351   "}\n"
352 };
353
354 } // namespace internal
355
356 } // namespace Toolkit
357
358 } // namespace Dali
359
360 #endif // DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H