Scene and glTF Loader
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scene3d-view / 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 mediump vec2 aTexCoord0;\n"
88   "in mediump vec2 aTexCoord1;\n"
89   "in lowp vec3 aNormal;\n"
90   "in lowp vec4 aTangent;\n"
91   "in lowp 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 lowp int uLightType;\n"
98   "uniform mediump vec3 uLightVector;\n"
99   "uniform lowp int uIsColor;\n"
100
101   "out lowp vec2 vUV[2];\n"
102   "out lowp mat3 vTBN;\n"
103   "out lowp vec4 vColor;\n"
104   "flat out int visLight;\n"
105   "out highp vec3 vLightDirection;\n"
106   "out highp vec3 vPositionToCamera;\n"
107
108   "void main()\n"
109   "{\n"
110   "  highp vec4 invY = vec4(1.0, -1.0, 1.0, 1.0);\n"
111   "  highp vec4 positionW = uModelMatrix * vec4( aPosition * uSize, 1.0 );\n"
112   "  highp vec4 positionV = uViewMatrix * ( invY * positionW );\n"
113
114   "  vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) );\n"
115   "  vPositionToCamera *= invY.xyz;\n"
116
117   "  lowp vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w;\n"
118   "  vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal);\n"
119
120   "  vUV[0] = aTexCoord0;\n"
121   "  vUV[1] = aTexCoord1;\n"
122
123   "  visLight = 1;\n"
124   "  if( uLightType == 1 )\n"
125   "  {\n"
126   "    vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w );\n"
127   "  }\n"
128   "  else if( uLightType == 2 )\n"
129   "  {\n"
130   "    vLightDirection = -( invY.xyz * uLightVector );\n"
131   "  }\n"
132   "  else\n"
133   "  {\n"
134   "    visLight = 0;\n"
135   "  }\n"
136
137   "  vColor = vec4( 1.0 );\n"
138   "  if( uIsColor == 1 )\n"
139   "  {\n"
140   "    vColor = aVertexColor;\n"
141   "  }\n"
142
143   "  gl_Position = uProjection * positionV;\n" // needs w for proper perspective correction
144   "  gl_Position = gl_Position/gl_Position.w;\n"
145   "}\n"
146 };
147
148 const char* PHYSICALLY_BASED_FRAGMENT_SHADER = {
149   "uniform lowp vec3 uLightColor;\n"
150   "uniform lowp vec4 uBaseColorFactor;\n"
151   "uniform lowp vec2 uMetallicRoughnessFactors;\n"
152   "uniform lowp int alphaMode;\n"
153   "uniform lowp float alphaCutoff;\n"
154
155   "in lowp vec2 vUV[2];\n"
156   "in lowp mat3 vTBN;\n"
157   "in lowp vec4 vColor;\n"
158   "flat in int visLight;\n"
159   "in highp vec3 vLightDirection;\n"
160   "in highp vec3 vPositionToCamera;\n"
161
162   "out vec4 FragColor;"
163
164   "struct PBRInfo\n"
165   "{\n"
166   "  mediump float NdotL;\n"                  // cos angle between normal and light direction
167   "  mediump float NdotV;\n"                  // cos angle between normal and view direction
168   "  mediump float NdotH;\n"                  // cos angle between normal and half vector
169   "  mediump float VdotH;\n"                  // cos angle between view direction and half vector
170   "  mediump vec3 reflectance0;\n"            // full reflectance color (normal incidence angle)
171   "  mediump vec3 reflectance90;\n"           // reflectance color at grazing angle
172   "  lowp float alphaRoughness;\n"         // roughness mapped to a more linear change in the roughness (proposed by [2])
173   "};\n"
174
175   "const float M_PI = 3.141592653589793;\n"
176   "const float c_MinRoughness = 0.04;\n"
177
178   "vec3 getNormal()\n"
179   "{\n"
180   "#ifdef TEXTURE_NORMAL\n"
181   "  lowp vec3 n = texture( uNormalSampler, vUV[uNormalTexCoordIndex] ).rgb;\n"
182   "  n = normalize( vTBN * ( ( 2.0 * n - 1.0 ) * vec3( uNormalScale, uNormalScale, 1.0 ) ) );\n"
183   "#else\n"
184   "  lowp vec3 n = normalize( vTBN[2].xyz );\n"
185   "#endif\n"
186   "  return n;\n"
187   "}\n"
188
189   "vec3 specularReflection( PBRInfo pbrInputs )\n"
190   "{\n"
191   "  return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 );\n"
192   "}\n"
193
194   "float geometricOcclusion( PBRInfo pbrInputs )\n"
195   "{\n"
196   "  mediump float NdotL = pbrInputs.NdotL;\n"
197   "  mediump float NdotV = pbrInputs.NdotV;\n"
198   "  lowp float r = pbrInputs.alphaRoughness;\n"
199
200   "  lowp float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n"
201   "  lowp float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n"
202   "  return attenuationL * attenuationV;\n"
203   "}\n"
204
205   "float microfacetDistribution(PBRInfo pbrInputs)\n"
206   "{\n"
207   "  mediump float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;\n"
208   "  lowp float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;\n"
209   "  return roughnessSq / (M_PI * f * f);\n"
210   "}\n"
211
212   "vec3 linear( vec3 color )\n"
213   "{\n"
214   "  return pow(color,vec3(2.2));\n"
215   "}\n"
216
217   "void main()\n"
218   "{\n"
219   // Metallic and Roughness material properties are packed together
220   // In glTF, these factors can be specified by fixed scalar values
221   // or from a metallic-roughness map
222   "  lowp float metallic = uMetallicRoughnessFactors.x;\n"
223   "  lowp float perceptualRoughness = uMetallicRoughnessFactors.y;\n"
224
225   // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
226   // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
227   "#ifdef TEXTURE_METALLICROUGHNESS\n"
228   "  lowp vec4 metrou = texture(uMetallicRoughnessSampler, vUV[uMetallicRoughnessTexCoordIndex]);\n"
229   "  metallic = metrou.b * metallic;\n"
230   "  perceptualRoughness = metrou.g * perceptualRoughness;\n"
231   "#endif\n"
232
233   "  metallic = clamp(metallic, 0.0, 1.0);\n"
234   "  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n"
235   // Roughness is authored as perceptual roughness; as is convention,
236   // convert to material roughness by squaring the perceptual roughness [2].
237   "  lowp float alphaRoughness = perceptualRoughness * perceptualRoughness;\n"
238
239   "#ifdef TEXTURE_BASECOLOR\n"
240   // The albedo may be defined from a base texture or a flat color
241   "  lowp vec4 baseColor = texture(uBaseColorSampler, vUV[uBaseColorTexCoordIndex]) * uBaseColorFactor;\n"
242   "  baseColor = vec4(linear(baseColor.rgb), baseColor.w);\n"
243   "#else\n"
244   "  lowp vec4 baseColor = vColor * uBaseColorFactor;\n"
245   "#endif\n"
246
247   "  if( alphaMode == 0 )\n"
248   "  {\n"
249   "    baseColor.w = 1.0;\n"
250   "  }\n"
251   "  else if( alphaMode == 1 )\n"
252   "  {\n"
253   "    if( baseColor.w >= alphaCutoff )"
254   "    {\n"
255   "      baseColor.w = 1.0;\n"
256   "    }\n"
257   "    else\n"
258   "    {\n"
259   "      baseColor.w = 0.0;\n"
260   "    }\n"
261   "  }\n"
262
263   "  lowp vec3 f0 = vec3(0.04);\n"
264   "  lowp vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);\n"
265   "  diffuseColor *= ( 1.0 - metallic );\n"
266   "  lowp vec3 specularColor = mix(f0, baseColor.rgb, metallic);\n"
267
268   // Compute reflectance.
269   "  lowp float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n"
270
271   // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
272   // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
273   "  lowp float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n"
274   "  lowp vec3 specularEnvironmentR0 = specularColor.rgb;\n"
275   "  lowp vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;\n"
276
277   "  mediump vec3 n = getNormal();\n"                            // normal at surface point
278   "  mediump vec3 v = normalize(vPositionToCamera);\n"           // Vector from surface point to camera
279   "  mediump vec3 l = normalize(vLightDirection);\n"             // Vector from light to surface point
280   "  mediump vec3 h = normalize(l+v);\n"                         // Half vector between both l and v
281   "  mediump vec3 reflection = -normalize(reflect(v, n));\n"
282
283   "  mediump float NdotL = clamp(dot(n, l), 0.001, 1.0);\n"
284   "  mediump float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n"
285   "  mediump float NdotH = dot(n, h);\n"
286   "  mediump float LdotH = dot(l, h);\n"
287   "  mediump float VdotH = dot(v, h);\n"
288
289   "  PBRInfo pbrInputs = PBRInfo(\n"
290   "    NdotL,\n"
291   "    NdotV,\n"
292   "    NdotH,\n"
293   "    VdotH,\n"
294   "    specularEnvironmentR0,\n"
295   "    specularEnvironmentR90,\n"
296   "    alphaRoughness\n"
297   "  );\n"
298
299   // Calculate the shading terms for the microfacet specular shading model
300   "  lowp vec3 color = vec3(0.0);\n"
301   "  if( visLight == 1 )\n"
302   "  {\n"
303   "    lowp vec3 F = specularReflection( pbrInputs );\n"
304   "    lowp float G = geometricOcclusion( pbrInputs );\n"
305   "    lowp float D = microfacetDistribution( pbrInputs );\n"
306
307   // Calculation of analytical lighting contribution
308   "    lowp vec3 diffuseContrib = ( 1.0 - F ) * ( diffuseColor / M_PI );\n"
309   "    lowp vec3 specContrib = F * G * D / ( 4.0 * NdotL * NdotV );\n"
310   // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
311   "    color = NdotL * uLightColor * (diffuseContrib + specContrib);\n"
312   "  }\n"
313
314   "#ifdef TEXTURE_IBL\n"
315   "  lowp float lod = ( perceptualRoughness * uMipmapLevel );\n"
316   // retrieve a scale and bias to F0. See [1], Figure 3
317   "  lowp vec3 brdf = linear( texture( ubrdfLUT, vec2( NdotV, 1.0 - perceptualRoughness ) ).rgb );\n"
318   "  lowp vec3 diffuseLight = linear( texture( uDiffuseEnvSampler, n ).rgb );\n"
319   "  lowp vec3 specularLight = linear( textureLod( uSpecularEnvSampler, reflection, lod ).rgb );\n"
320
321   "  lowp vec3 diffuse = diffuseLight * diffuseColor * uScaleIBLAmbient.x;\n"
322   "  lowp vec3 specular = specularLight * ( specularColor * brdf.x + brdf.y ) * uScaleIBLAmbient.y;\n"
323   "  color += ( diffuse + specular );\n"
324   "#endif\n"
325
326   "#ifdef TEXTURE_OCCLUSION\n"
327   "  lowp float ao = texture( uOcclusionSampler, vUV[uOcclusionTexCoordIndex] ).r;\n"
328   "  color = mix( color, color * ao, uOcclusionStrength );\n"
329   "#endif\n"
330
331   "#ifdef TEXTURE_EMIT\n"
332   "  lowp vec3 emissive = linear( texture( uEmissiveSampler, vUV[uEmissiveTexCoordIndex] ).rgb ) * uEmissiveFactor;\n"
333   "  color += emissive;\n"
334   "#endif\n"
335
336   "  FragColor = vec4( pow( color,vec3( 1.0 / 2.2 ) ), baseColor.a );\n"
337   "}\n"
338 };
339
340 } // namespace internal
341
342 } // namespace Toolkit
343
344 } // namespace Dali
345
346 #endif // DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H