1 #ifndef DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H
2 #define DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H
5 * Belows Vertex Shader and Fragment Shader code are based off glTF WebGL PBR.
6 * https://github.com/KhronosGroup/glTF-WebGL-PBR/
8 * Copyright (c) 2016-2017 Mohamad Moneimne and Contributors
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:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
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
38 const char* GLES_VERSION_300 = {
40 "precision highp float;\n\n"
43 const char* DEFINE_BASECOLOR_TEXTURE = {
44 "#define TEXTURE_BASECOLOR\n\n"
45 "uniform sampler2D uBaseColorSampler;\n"
46 "uniform int uBaseColorTexCoordIndex;\n\n"
49 const char* DEFINE_METALLICROUGHNESS_TEXTURE = {
50 "#define TEXTURE_METALLICROUGHNESS\n\n"
51 "uniform sampler2D uMetallicRoughnessSampler;\n"
52 "uniform int uMetallicRoughnessTexCoordIndex;\n\n"
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"
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"
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"
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"
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"
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"
106 "flat out int visLight;\n"
107 "out vec3 vLightDirection;\n"
108 "out vec3 vPositionToCamera;\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"
116 " vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) );\n"
117 " vPositionToCamera *= vec3( invY );\n"
119 " vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w;\n"
120 " vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal);\n"
122 " vUV[0] = aTexCoord0;\n"
123 " vUV[1] = aTexCoord1;\n"
126 " if( uLightType == 1 )\n"
128 " vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w );\n"
130 " else if( uLightType == 2 )\n"
132 " vLightDirection = -( invY.xyz * uLightVector );\n"
139 " vColor = vec4( 1.0 );\n"
140 " if( uIsColor == 1 )\n"
142 " vColor = aVertexColor;\n"
145 " gl_Position = uProjection * positionV;\n" // needs w for proper perspective correction
146 " gl_Position = gl_Position/gl_Position.w;\n"
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"
160 "flat in int visLight;\n"
161 "in vec3 vLightDirection;\n"
162 "in vec3 vPositionToCamera;\n"
164 "out vec4 FragColor;"
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
182 "const float M_PI = 3.141592653589793;\n"
183 "const float c_MinRoughness = 0.04;\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"
191 " vec3 n = normalize( vTBN[2].xyz );\n"
196 "vec3 specularReflection( PBRInfo pbrInputs )\n"
198 " return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 );\n"
201 "float geometricOcclusion( PBRInfo pbrInputs )\n"
203 " float NdotL = pbrInputs.NdotL;\n"
204 " float NdotV = pbrInputs.NdotV;\n"
205 " float r = pbrInputs.alphaRoughness;\n"
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"
212 "float microfacetDistribution(PBRInfo pbrInputs)\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"
219 "vec3 linear( vec3 color )\n"
221 " return pow(color,vec3(2.2));\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"
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"
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"
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"
251 " vec4 baseColor = vColor * uBaseColorFactor;\n"
254 " if( alphaMode == 0 )\n"
256 " baseColor.w = 1.0;\n"
258 " else if( alphaMode == 1 )\n"
260 " if( baseColor.w >= alphaCutoff )"
262 " baseColor.w = 1.0;\n"
266 " baseColor.w = 0.0;\n"
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"
275 // Compute reflectance.
276 " float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n"
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"
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"
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"
296 " PBRInfo pbrInputs = PBRInfo(\n"
302 " perceptualRoughness,\n"
304 " specularEnvironmentR0,\n"
305 " specularEnvironmentR90,\n"
311 // Calculate the shading terms for the microfacet specular shading model
312 " vec3 color = vec3(0.0);\n"
313 " if( visLight == 1 )\n"
315 " vec3 F = specularReflection(pbrInputs);\n"
316 " float G = geometricOcclusion(pbrInputs);\n"
317 " float D = microfacetDistribution(pbrInputs);\n"
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"
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"
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"
340 "#ifdef TEXTURE_OCCLUSION\n"
341 " float ao = texture(uOcclusionSampler, vUV[uOcclusionTexCoordIndex]).r;\n"
342 " color = mix(color, color * ao, uOcclusionStrength);\n"
345 "#ifdef TEXTURE_EMIT\n"
346 " vec3 emissive = linear(texture(uEmissiveSampler, vUV[uEmissiveTexCoordIndex]).rgb) * uEmissiveFactor;\n"
347 " color += emissive;\n"
350 " FragColor = vec4(pow(color,vec3(1.0/2.2)), baseColor.a);\n"
354 } // namespace internal
356 } // namespace Toolkit
360 #endif // DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H