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 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"
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"
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"
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"
114 " vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) );\n"
115 " vPositionToCamera *= invY.xyz;\n"
117 " lowp vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w;\n"
118 " vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal);\n"
120 " vUV[0] = aTexCoord0;\n"
121 " vUV[1] = aTexCoord1;\n"
124 " if( uLightType == 1 )\n"
126 " vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w );\n"
128 " else if( uLightType == 2 )\n"
130 " vLightDirection = -( invY.xyz * uLightVector );\n"
137 " vColor = vec4( 1.0 );\n"
138 " if( uIsColor == 1 )\n"
140 " vColor = aVertexColor;\n"
143 " gl_Position = uProjection * positionV;\n" // needs w for proper perspective correction
144 " gl_Position = gl_Position/gl_Position.w;\n"
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"
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"
162 "out vec4 FragColor;"
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])
175 "const float M_PI = 3.141592653589793;\n"
176 "const float c_MinRoughness = 0.04;\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"
184 " lowp vec3 n = normalize( vTBN[2].xyz );\n"
189 "vec3 specularReflection( PBRInfo pbrInputs )\n"
191 " return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 );\n"
194 "float geometricOcclusion( PBRInfo pbrInputs )\n"
196 " mediump float NdotL = pbrInputs.NdotL;\n"
197 " mediump float NdotV = pbrInputs.NdotV;\n"
198 " lowp float r = pbrInputs.alphaRoughness;\n"
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"
205 "float microfacetDistribution(PBRInfo pbrInputs)\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"
212 "vec3 linear( vec3 color )\n"
214 " return pow(color,vec3(2.2));\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"
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"
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"
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"
244 " lowp vec4 baseColor = vColor * uBaseColorFactor;\n"
247 " if( alphaMode == 0 )\n"
249 " baseColor.w = 1.0;\n"
251 " else if( alphaMode == 1 )\n"
253 " if( baseColor.w >= alphaCutoff )"
255 " baseColor.w = 1.0;\n"
259 " baseColor.w = 0.0;\n"
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"
268 // Compute reflectance.
269 " lowp float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n"
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"
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"
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"
289 " PBRInfo pbrInputs = PBRInfo(\n"
294 " specularEnvironmentR0,\n"
295 " specularEnvironmentR90,\n"
299 // Calculate the shading terms for the microfacet specular shading model
300 " lowp vec3 color = vec3(0.0);\n"
301 " if( visLight == 1 )\n"
303 " lowp vec3 F = specularReflection( pbrInputs );\n"
304 " lowp float G = geometricOcclusion( pbrInputs );\n"
305 " lowp float D = microfacetDistribution( pbrInputs );\n"
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"
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"
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"
326 "#ifdef TEXTURE_OCCLUSION\n"
327 " lowp float ao = texture( uOcclusionSampler, vUV[uOcclusionTexCoordIndex] ).r;\n"
328 " color = mix( color, color * ao, uOcclusionStrength );\n"
331 "#ifdef TEXTURE_EMIT\n"
332 " lowp vec3 emissive = linear( texture( uEmissiveSampler, vUV[uEmissiveTexCoordIndex] ).rgb ) * uEmissiveFactor;\n"
333 " color += emissive;\n"
336 " FragColor = vec4( pow( color,vec3( 1.0 / 2.2 ) ), baseColor.a );\n"
340 } // namespace internal
342 } // namespace Toolkit
346 #endif // DALI_TOOLKIT_INTERNAL_GLTF_SHADER_H