[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / graphics / shaders / default-physically-based-shader.vert
1
2 // Original Code
3 // https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-vert.glsl
4 // Commit dc84b5e374fb3d23153d2248a338ef88173f9eb6
5
6 #define MORPH defined(MORPH_POSITION) || defined(MORPH_NORMAL) || defined(MORPH_TANGENT)
7
8 // These lines in the shader may be replaced with actual definitions by the model loader,
9 // if they are needed. Note, some shader compilers have problems with spurious ";", so
10 // the macro invocations don't have a trailing ";". The replacement strings in the model
11 // loader will provide it instead.
12 #define ADD_EXTRA_SKINNING_ATTRIBUTES
13 #define ADD_EXTRA_WEIGHTS
14
15 #ifdef HIGHP
16   precision highp float;
17 #else
18   precision mediump float;
19 #endif
20
21 INPUT vec3 aPosition;
22 INPUT vec2 aTexCoord;
23 INPUT vec3 aNormal;
24
25 #ifdef VEC4_TANGENT
26 INPUT vec4 aTangent;
27 #else
28 INPUT vec3 aTangent;
29 #endif
30
31 INPUT vec4 aVertexColor;
32
33 #ifdef SL_VERSION_LOW
34 INPUT float aVertexID;
35 #endif
36
37 #ifdef SKINNING
38 INPUT vec4 aJoints0;
39 INPUT vec4 aWeights0;
40 ADD_EXTRA_SKINNING_ATTRIBUTES
41 #endif
42
43 #ifdef MORPH
44 uniform highp sampler2D sBlendShapeGeometry;
45 #ifdef SL_VERSION_LOW
46 uniform int uBlendShapeGeometryWidth;
47 uniform int uBlendShapeGeometryHeight;
48 #endif
49 #endif
50
51 OUTPUT mediump vec2 vUV;
52 OUTPUT lowp mat3 vTBN;
53 OUTPUT lowp vec4 vColor;
54 OUTPUT highp vec3 vPositionToCamera;
55
56 uniform highp mat4 uViewMatrix;
57 uniform mat3 uNormalMatrix;
58 uniform mat4 uModelMatrix;
59 uniform mat4 uProjection;
60
61 #ifdef SKINNING
62
63 #ifdef SL_VERSION_LOW
64 #define MAX_BONES 80
65 uniform mat4 uBone[MAX_BONES];
66 #else
67 #define MAX_BONES 256
68 layout(std140) uniform Bones
69 {
70   mat4 uBone[MAX_BONES];
71 };
72 #endif
73
74 uniform mediump vec3 uYDirection;
75 #endif
76
77 #ifdef MORPH
78 #define MAX_BLEND_SHAPE_NUMBER 256
79 uniform int uNumberOfBlendShapes;                                         ///< Total number of blend shapes loaded.
80 uniform highp float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER];            ///< The weight of each blend shape.
81 #ifdef MORPH_VERSION_2_0
82 uniform highp float uBlendShapeUnnormalizeFactor;                         ///< Factor used to unnormalize the geometry of the blend shape.
83 #else
84 uniform highp float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
85 #endif
86 uniform highp int uBlendShapeComponentSize;                               ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
87 #endif
88
89 // Shadow
90 uniform lowp int uIsShadowEnabled;
91 uniform highp mat4 uShadowLightViewProjectionMatrix;
92 OUTPUT highp vec3 positionFromLightView;
93
94 void main()
95 {
96   highp vec4 position = vec4(aPosition, 1.0);
97   highp vec3 normal = aNormal;
98   highp vec3 tangent = aTangent.xyz;
99
100 #ifdef MORPH
101 #ifdef SL_VERSION_LOW
102   int width = uBlendShapeGeometryWidth;
103 #else
104   int width = textureSize( sBlendShapeGeometry, 0 ).x;
105 #endif
106
107   highp int blendShapeBufferOffset = 0;
108
109 #ifdef SL_VERSION_LOW
110   highp float blendShapeWidth = float(uBlendShapeGeometryWidth);
111   highp float blendShapeHeight = float(uBlendShapeGeometryHeight);
112   highp float invertBlendShapeWidth = 1.0 / blendShapeWidth;
113   highp float invertBlendShapeHeight = 1.0 / blendShapeHeight;
114 #endif
115
116   for( int index = 0; index < uNumberOfBlendShapes; ++index )
117   {
118     highp vec3 diff = vec3(0.0);
119     highp int vertexId = 0;
120     highp int x = 0;
121     highp int y = 0;
122     highp float weight = clamp(uBlendShapeWeight[index], 0.0, 1.0);
123
124 #ifdef MORPH_POSITION
125     // Calculate the index to retrieve the geometry from the texture.
126 #ifdef SL_VERSION_LOW
127     vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
128     y = vertexId / width;
129     x = vertexId - y * width;
130 #else
131     vertexId = gl_VertexID + blendShapeBufferOffset;
132     x = vertexId % width;
133     y = vertexId / width;
134 #endif
135
136     // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
137     if(0.0 != weight)
138     {
139 #ifdef MORPH_VERSION_2_0
140        highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
141 #else
142        highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
143 #endif
144
145 #ifdef SL_VERSION_LOW
146       highp float floatX = float(x) + 0.5;
147       highp float floatY = float(y) + 0.5;
148       diff = weight * unnormalizeFactor * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
149 #else
150       diff = weight * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
151 #endif
152     }
153
154     position.xyz += diff;
155
156     blendShapeBufferOffset += uBlendShapeComponentSize;
157 #endif
158
159 #ifdef MORPH_NORMAL
160     // Calculate the index to retrieve the normal from the texture.
161 #ifdef SL_VERSION_LOW
162     vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
163     y = vertexId / width;
164     x = vertexId - y * width;
165 #else
166     vertexId = gl_VertexID + blendShapeBufferOffset;
167     x = vertexId % width;
168     y = vertexId / width;
169 #endif
170
171     // Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight.
172     if(0.0 != weight)
173     {
174 #ifdef SL_VERSION_LOW
175       highp float floatX = float(x) + 0.5;
176       highp float floatY = float(y) + 0.5;
177       diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
178 #else
179       diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
180 #endif
181     }
182
183     normal += diff.xyz;
184
185     blendShapeBufferOffset += uBlendShapeComponentSize;
186 #endif
187
188 #ifdef MORPH_TANGENT
189     // Calculate the index to retrieve the tangent from the texture.
190 #ifdef SL_VERSION_LOW
191     vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
192     y = vertexId / width;
193     x = vertexId - y * width;
194 #else
195     vertexId = gl_VertexID + blendShapeBufferOffset;
196     x = vertexId % width;
197     y = vertexId / width;
198 #endif
199
200     // Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight.
201     if(0.0 != weight)
202     {
203 #ifdef SL_VERSION_LOW
204       highp float floatX = float(x) + 0.5;
205       highp float floatY = float(y) + 0.5;
206       diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
207 #else
208       diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
209 #endif
210     }
211
212     tangent += diff.xyz;
213
214     blendShapeBufferOffset += uBlendShapeComponentSize;
215 #endif
216   }
217
218 #endif
219
220
221
222
223 #ifdef SKINNING
224   highp mat4 bone =
225     uBone[int(aJoints0.x)] * aWeights0.x +
226     uBone[int(aJoints0.y)] * aWeights0.y +
227     uBone[int(aJoints0.z)] * aWeights0.z +
228     uBone[int(aJoints0.w)] * aWeights0.w;
229
230   ADD_EXTRA_WEIGHTS
231
232   position = bone * position;
233   normal = uYDirection * (bone * vec4(normal, 0.0)).xyz;
234   tangent = uYDirection * (bone * vec4(tangent, 0.0)).xyz;
235
236   highp vec4 positionW = position;
237 #else
238   highp vec4 positionW = uModelMatrix * position;
239 #endif
240
241   highp vec4 positionV = uViewMatrix * positionW;
242
243 #ifdef SL_VERSION_LOW
244   highp vec3 i0 = uViewMatrix[0].xyz;
245   highp vec3 i1 = uViewMatrix[1].xyz;
246   highp vec3 i2 = uViewMatrix[2].xyz;
247
248   vPositionToCamera = mat3(vec3(i0.x, i1.x, i2.x), vec3(i0.y, i1.y, i2.y), vec3(i0.z, i1.z, i2.z)) * -vec3(positionV.xyz / positionV.w);
249 #else
250   vPositionToCamera = transpose(mat3(uViewMatrix)) * -vec3(positionV.xyz / positionV.w);
251 #endif
252
253   normal = normalize(normal);
254   tangent = normalize(tangent);
255   vec3 bitangent = cross(normal, tangent);
256 #ifdef VEC4_TANGENT
257   bitangent *= aTangent.w;
258 #endif
259   vTBN = mat3(uModelMatrix) * mat3(tangent, bitangent, normal);
260
261 #ifdef FLIP_V
262   vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
263 #else
264   vUV = aTexCoord;
265 #endif
266
267   vColor = aVertexColor;
268
269   positionFromLightView = vec3(1.0);
270   if(uIsShadowEnabled > 0)
271   {
272     highp vec4 positionInLightView = uShadowLightViewProjectionMatrix * positionW;
273     positionFromLightView = ((positionInLightView.xyz / positionInLightView.w) * 0.5) + vec3(0.5);
274   }
275
276   gl_Position = uProjection * positionV;
277 }