30 layout (location = 0) in vec4 a_position; // Vertex position attribute
31 layout (location = 1) in vec3 a_normal; // Vertex normal attribute)";
33 layout (location = 0) in vec3 a_position; // Particle position attribute)";
35 layout (location = 1) in vec3 a_velocity; // Particle velocity attribute)";
37 layout (location = 2) in float a_startTime; // Particle start time attribute)";
39 layout (location = 3) in vec3 a_initialVelocity;// Particle initial velocity attribute)";
41 layout (location = 4) in float a_rotation; // Particle rotation attribute)";
43 layout (location = 5) in float a_angularVelo; // Particle rotation rate attribute)";
45 layout (location = 6) in uint a_texNum; // Particle rotation attribute)";
47 layout (location = 7) in vec3 a_initialPosition;// Particle initial position attribute)";
49 layout (location = 8) in vec3 a_instancePos; // Particle instance triangle vertex position attribute)";
51 layout (location = 2) in vec2 a_uv0; // Vertex tex.coord. 1 for diffuse color)";
53 layout (location = 3) in vec2 a_uv1; // Vertex tex.coord. 2 for AO)";
55 layout (location = 5) in vec4 a_tangent; // Vertex tangent attribute)";
57 layout (location = 6) in ivec4 a_jointIds; // Vertex joint indices attributes
58 layout (location = 7) in vec4 a_jointWeights; // Vertex joint weights attributes)";
62 uniform mat4 u_mMatrix; // Model matrix (object to world transform)
63 uniform mat4 u_vMatrix; // View matrix (world to camera transform)
64 uniform mat4 u_pMatrix; // Projection matrix (camera to normalize device coords.))";
66 uniform mat4 u_vOmvMatrix; // view or modelview matrix)";
70 uniform mat4 u_jointMatrices[100]; // Joint matrices for skinning
71 uniform bool u_skinningEnabled; // Flag if the shader should perform skinning
76 uniform vec4 u_lightPosVS[NUM_LIGHTS]; // position of light in view space
77 uniform vec3 u_lightSpotDir[NUM_LIGHTS]; // spot direction in view space
78 uniform float u_lightSpotDeg[NUM_LIGHTS]; // spot cutoff angle 1-180 degrees)";
82 #define PI 3.1415926538
83 #define TWOPI 6.2831853076
87 uniform float u_time; // Simulation time
88 uniform float u_difTime; // Simulation delta time after frustum culling
89 uniform float u_tTL; // Time to live of a particle)";
91 uniform float u_tTL; // Time to live of a particle)";
93 uniform vec4 u_al_bernstein; // Bernstein polynomial for alpha over time)";
95 uniform vec4 u_si_bernstein; // Bernstein polynomial for size over time)";
97 uniform float u_colorArr[256 * 3]; // Array of color value (for color over life))";
99 uniform float u_colorArr[256 * 3]; // Array of color value (for color over life))";
101 uniform float u_deltaTime; // Elapsed time between frames)";
103 uniform vec3 u_pGPosition; // Particle Generator position)";
105 uniform float u_accConst; // Particle acceleration constant)";
107 uniform vec3 u_acceleration; // Particle acceleration)";
109 uniform vec3 u_gravity; // Particle gravity)";
111 uniform float u_angularVelo; // Particle angular velocity)";
113 uniform int u_col; // Number of column of flipbook texture)";
115 uniform int u_row; // Number of row of flipbook texture)";
117 uniform int u_condFB; // Condition to update texNum)";
121 out vec3 v_P_VS; // Point of illumination in view space (VS))";
123 out vec3 v_P_WS; // Point of illumination in world space (WS))";
125 out vec3 v_N_VS; // Normal at P_VS in view space (VS))";
127 out vec3 v_R_OS; // Reflection vector in object space (WS))";
129 out vec2 v_uv0; // Texture coordinate 0 output)";
131 out vec2 v_uv1; // Texture coordinate 1 output)";
133 out vec3 v_eyeDirTS; // Vector to the eye in tangent space
134 out vec3 v_lightDirTS[NUM_LIGHTS]; // Vector to the light 0 in tangent space
135 out vec3 v_spotDirTS[NUM_LIGHTS]; // Spot direction in tangent space)";
138 vec3 colorByAge(float age)
140 int cachePos = int(clamp(age, 0.0, 1.0) * 255.0) * 3;
141 vec3 color = vec3(u_colorArr[cachePos], u_colorArr[cachePos + 1], u_colorArr[cachePos + 2]);
146 vec3 colorByAge(float age)
148 int cachePos = int(clamp(age, 0.0, 1.0) * 255.0) * 3;
149 vec3 color = vec3(u_colorArr[cachePos], u_colorArr[cachePos + 1], u_colorArr[cachePos + 2]);
158 float transparency; // Transparency of a particle)";
160 float rotation; // Rotation of a particle)";
162 float size; // Size of a particle )";
164 vec3 color; // Color of a particle )";
166 uint texNum; // Num of texture in flipbook)";
171 out float transparency; // transparency of a particle )";
173 in float transparency; // transparency of a particle )";
176 vec4 color = vec4(colorByAge(v_age/u_tTL), 1.0); // Particle color)";
178 vec4 color = u_color; // Particle color)";
180 color.w *= transparency; // Apply transparency)";
182 uniform mat4 u_pMatrix; // Projection matrix)";
184 uniform mat4 u_vYawPMatrix; // Projection matrix)";
186 uniform vec4 u_color; // Particle color)";
188 uniform float u_scale; // Particle scale
189 uniform float u_radiusW; // Particle width radius)
190 uniform float u_radiusH; // Particle height radius)";
195 out vec3 tf_position; // To transform feedback)";
197 out vec3 tf_velocity; // To transform feedback)";
199 out float tf_startTime; // To transform feedback)";
201 out vec3 tf_initialVelocity; // To transform feedback)";
203 out float tf_rotation; // To transform feedback)";
205 out float tf_angularVelo; // To transform feedback)";
207 flat out uint tf_texNum; // To transform feedback)";
209 out vec3 tf_initialPosition; // To transform feedback)";
213 //-----------------------------------------------------------------------------
218 mat4 mvMatrix = u_vMatrix * u_mMatrix;
219 v_P_VS = vec3(mvMatrix * ${localPosition}); // vertex position in view space)";
221 v_P_WS = vec3(u_mMatrix * ${localPosition}); // vertex position in world space)";
223 mat3 invMvMatrix = mat3(inverse(mvMatrix));
224 mat3 nMatrix = transpose(invMvMatrix);
225 v_N_VS = vec3(nMatrix * ${localNormal}); // vertex normal in view space)";
227 vec3 I = normalize(v_P_VS);
228 vec3 N = normalize(v_N_VS);
229 v_R_OS = invMvMatrix * reflect(I, N); // R = I-2.0*dot(N,I)*N;)";
231 v_uv0 = a_uv0; // pass diffuse color tex.coord. 0 for interpolation)";
233 v_uv1 = a_uv1; // pass diffuse color tex.coord. 1 for interpolation)";
235 vec4 skinnedPosition;
238 if (u_skinningEnabled)
240 // In skinned skeleton animation, every vertex of a mesh is transformed by
241 // max. four joints (bones) of a skeleton identified by indices. The joint
242 // matrix is a weighted sum of four joint matrices and can change per frame
243 // to animate the mesh.
244 mat4 jm = u_jointMatrices[int(a_jointIds.x)] * a_jointWeights.x
245 + u_jointMatrices[int(a_jointIds.y)] * a_jointWeights.y
246 + u_jointMatrices[int(a_jointIds.z)] * a_jointWeights.z
247 + u_jointMatrices[int(a_jointIds.w)] * a_jointWeights.w;
249 skinnedPosition = jm * a_position;
250 skinnedNormal = mat3(jm) * a_normal;
254 skinnedPosition = a_position;
255 skinnedNormal = a_normal;
259 vec4 skinnedPosition;
263 if (u_skinningEnabled)
265 // In skinned skeleton animation, every vertex of a mesh is transformed by
266 // max. four joints (bones) of a skeleton identified by indices. The joint
267 // matrix is a weighted sum of four joint matrices and can change per frame
268 // to animate the mesh.
269 mat4 jm = u_jointMatrices[int(a_jointIds.x)] * a_jointWeights.x
270 + u_jointMatrices[int(a_jointIds.y)] * a_jointWeights.y
271 + u_jointMatrices[int(a_jointIds.z)] * a_jointWeights.z
272 + u_jointMatrices[int(a_jointIds.w)] * a_jointWeights.w;
274 skinnedPosition = jm * a_position;
275 skinnedNormal = mat3(jm) * a_normal;
276 skinnedTangent = vec4(mat3(jm) * a_tangent.xyz, a_tangent.w);
280 skinnedPosition = a_position;
281 skinnedNormal = a_normal;
282 skinnedTangent = a_tangent;
287 // Building the matrix Eye Space -> Tangent Space
288 // See the math behind at: http://www.terathon.com/code/tangent.html
289 vec3 n = normalize(nMatrix * ${localNormal});
290 vec3 t = normalize(nMatrix * ${localTangent}.xyz);
291 vec3 b = cross(n, t) * ${localTangent}.w; // bitangent w. corrected handedness
292 mat3 TBN = mat3(t,b,n);
294 // Transform vector to the eye into tangent space
295 v_eyeDirTS = -v_P_VS; // eye vector in view space
298 for (int i = 0; i < NUM_LIGHTS; ++i)
300 // Transform spot direction into tangent space
301 v_spotDirTS[i] = u_lightSpotDir[i];
302 v_spotDirTS[i] *= TBN;
304 // Transform vector to the light 0 into tangent space
305 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
307 v_lightDirTS[i] *= TBN;
315 vert.transparency = 0.0; // To be discard, because the particle is to be born
317 vert.transparency = 1.0;)";
320 vert.transparency = 0.0; // To be discard, because the particle is to be born
323 vert.transparency = age / u_tTL; // Get by the ratio age:lifetime)";
325 vert.transparency = 1.0 - vert.transparency; // Linear)";
327 vert.transparency = pow(vert.transparency,3.0) * u_al_bernstein.x +
328 pow(vert.transparency,2.0) * u_al_bernstein.y +
329 vert.transparency * u_al_bernstein.z +
330 u_al_bernstein.w; // Get transparency by bezier curve)";
334 vert.rotation = a_rotation;)";
336 vert.size = age / u_tTL;)";
338 vert.size = pow(vert.size,3.0) * u_si_bernstein.x +
339 pow(vert.size,2.0) * u_si_bernstein.y +
340 vert.size * u_si_bernstein.z +
341 u_si_bernstein.w; // Get transparency by bezier curve)";
344 vert.color = colorByAge(age/u_tTL);)";
346 out float v_age; // Age of a particle)";
348 in float v_age; // Age of a particle)";
350 vert.texNum = a_texNum;)";
352 float age = u_time - a_startTime; // Get the age of the particle)";
354 v_texCoord = 0.5 * (a_instancePos.xy + vec2(1.0));)";
358 int actCI = int(mod(float(a_texNum), float(u_col)));
359 float actC = float(actCI);
360 float actR = floor(float(int(a_texNum) - actCI) / float(u_col));
362 vec2 p = 0.5 * (a_instancePos.xy + vec2(1.0));
363 v_texCoord = vec2((actC + p.x)/float(u_col), 1.0 - (actR - p.y)/float(u_row));
367 vec3 position = a_instancePos;
370 float size = age / u_tTL;)";
372 size = pow(size,3.0) * u_si_bernstein.x +
373 pow(size,2.0) * u_si_bernstein.y +
374 size * u_si_bernstein.z +
375 u_si_bernstein.w; // Get transparency by bezier curve)";
377 position = size * position;
381 transparency = 0.0; // To be discard, because the particle is to be born
383 transparency = 1.0;)";
386 transparency = 0.0; // To be discard, because the particle is to be born
389 transparency = age / u_tTL; // Get by the ratio age:lifetime)";
391 transparency = 1.0 - transparency; // Linear)";
393 transparency = pow(transparency,3.0) * u_al_bernstein.x +
394 pow(transparency,2.0) * u_al_bernstein.y +
395 transparency * u_al_bernstein.z +
396 u_al_bernstein.w; // Get transparency by bezier curve)";
398 position = vec3(u_radiusW * position.x, u_radiusH * position.y, position.z);
399 position = u_scale * position;
402 mat2 rot = mat2(cos(a_rotation),-sin(a_rotation),
403 sin(a_rotation), cos(a_rotation)); // Matrix of rotation
404 position = vec3(rot * position.xy, position.z);
408 // Modelview matrix multiplication with (particle position + particle generator position)
409 // Calculate position in view space
410 gl_Position = u_pMatrix * (u_vOmvMatrix * vec4(a_position, 1) + vec4(position, 0.0));
414 //gl_Position = vec4(a_position + a_instancePos, 1);
415 gl_Position = u_pMatrix * u_vYawPMatrix * vec4(a_position + position, 1.0);
421 // Modelview matrix multiplication with (particle position + particle generator position)
422 // Calculate position in view space
423 gl_Position = u_vOmvMatrix * vec4(a_position, 1);
427 gl_Position = vec4(a_position, 1);
432 // pass the vertex w. the fix-function transform
433 gl_Position = u_pMatrix * mvMatrix * ${localPosition};
438 vec4 P = vec4(a_position.xyz, 1.0); // Need to be here for the compilation
439 gl_Position = P; // Need to be here for the compilation)";
441 tf_position = a_position; // Init the output variable)";
443 tf_velocity = a_velocity; // Init the output variable)";
445 tf_startTime = a_startTime; // Init the output variable)";
447 tf_initialVelocity = a_initialVelocity; // Init the output variable)";
449 tf_rotation = a_rotation; // Init the output variable)";
451 tf_angularVelo = a_angularVelo; // Init the output variable)";
453 tf_texNum = a_texNum; // Init the output variable)";
455 tf_initialPosition = a_initialPosition; // Init the output variable)";
457 tf_startTime += u_difTime; // Add time to resume after frustum culling
459 if( u_time >= tf_startTime )
460 { // Check if the particle is born
461 float age = u_time - tf_startTime; // Get the age of the particle
465 // The particle is past its lifetime, recycle.
466 tf_position = u_pGPosition; // Reset position)";
468 // The particle is past its lifetime, recycle.
469 tf_position = a_initialPosition + u_pGPosition; // Reset position)";
471 tf_velocity = a_initialVelocity; // Reset velocity)";
473 tf_startTime = u_time + (age - u_tTL); // Reset start time to actual time with counter gap)";
475 tf_startTime = u_time; // Reset start time to actual time)";
479 // The particle is alive, update.
480 tf_position += tf_velocity * u_deltaTime; // Scale the translation by the delta time)";
482 tf_rotation = mod(tf_rotation + (u_angularVelo*u_deltaTime), TWOPI);)";
484 tf_rotation = mod(tf_rotation + (tf_angularVelo*u_deltaTime), TWOPI);)";
486 tf_velocity += tf_initialVelocity * u_deltaTime * u_accConst; // Amplify the velocity)";
488 tf_velocity += u_deltaTime * u_acceleration; // Amplify the velocity)";
490 tf_velocity += u_deltaTime * u_gravity; // Apply gravity)";
494 tf_texNum++; // Increment to draw next texture (flipbook)
495 tf_texNum = uint(mod(float(tf_texNum), float(u_col * u_row))); // Modulo to not exceed the max and reset
504 layout (points) in; // Primitives that we received from vertex shader
505 layout (triangle_strip, max_vertices = 4) out; // Primitives that we will output and number of vertex that will be output)";
509 float transparency; // Transparency of a particle)";
511 float rotation; // Rotation of a particle)";
513 float size; // Size of a particle )";
515 vec3 color; // Color of a particle )";
517 uint texNum; // Num of texture in flipbook)";
522 uniform mat4 u_pMatrix; // Projection matrix)";
524 uniform mat4 u_vYawPMatrix; // Projection matrix)";
526 uniform float u_scale; // Particle scale
527 uniform float u_radiusW; // Particle width radius)
528 uniform float u_radiusH; // Particle height radius)";
530 uniform vec4 u_color; // Particle color)";
532 uniform int u_col; // Number of column of flipbook texture)";
534 uniform int u_row; // Number of row of flipbook texture)";
537 out vec4 v_particleColor; // The resulting color per vertex)";
539 out vec2 v_texCoord; // Texture coordinate at vertex)";
541 out vec2 v_texCoord; // Texture coordinate at vertex)";
544 float scale = u_scale;)";
546 scale *= vert[0].size;)";
548 float radiusW = u_radiusW * scale;
549 float radiusH = u_radiusH * scale;)";
551 vec4 P = gl_in[0].gl_Position; // Position of the point that we received)";
553 mat2 rot = mat2(cos(vert[0].rotation),-sin(vert[0].rotation),
554 sin(vert[0].rotation), cos(vert[0].rotation)); // Matrix of rotation)";
556 mat2 rot = mat2(1.0, 0.0, 0.0, 1.0); // Matrix of rotation)";
558 vec4 color = u_color; // Particle color)";
560 vec4 color = vec4(vert[0].color, 1.0); // Particle color)";
562 vec4 color = vec4( 0.0, 0.0, 0.0, 1.0); // Particle color)";
564 color.w *= vert[0].transparency; // Apply transparency)";
568 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
569 gl_Position = u_pMatrix * va; // Calculate position in clip space
570 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
571 v_particleColor = color;
575 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
576 gl_Position = u_pMatrix * vd;
577 v_texCoord = vec2(1.0, 0.0);
578 v_particleColor = color;
582 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
583 gl_Position = u_pMatrix * vb;
584 v_texCoord = vec2(0.0, 1.0);
585 v_particleColor = color;
589 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
590 gl_Position = u_pMatrix * vc;
591 v_texCoord = vec2(1.0, 1.0);
592 v_particleColor = color;
597 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
598 gl_Position = u_pMatrix * (u_vYawPMatrix * va); // Calculate position in clip space
599 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
600 v_particleColor = color;
604 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
605 gl_Position = u_pMatrix * (u_vYawPMatrix *vd);
606 v_texCoord = vec2(1.0, 0.0);
607 v_particleColor = color;
611 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
612 gl_Position = u_pMatrix * (u_vYawPMatrix * vb);
613 v_texCoord = vec2(0.0, 1.0);
614 v_particleColor = color;
618 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
619 gl_Position = u_pMatrix * (u_vYawPMatrix * vc);
620 v_texCoord = vec2(1.0, 1.0);
621 v_particleColor = color;
626 vec4 va = vec4(P.xyz, 1); //Position in view space
627 va.xz = va.xz + (rot * vec2(-radiusW, -radiusH));
628 gl_Position = u_pMatrix * u_vOmvMatrix * va; // Calculate position in clip space
629 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
630 v_particleColor = color;
634 vec4 vd = vec4(P.xyz,1);
635 vd.xz += (rot * vec2(radiusW, -radiusH));
636 gl_Position = u_pMatrix * u_vOmvMatrix * vd;
637 v_texCoord = vec2(1.0, 0.0);
638 v_particleColor = color;
642 vec4 vb = vec4(P.xyz,1);
643 vb.xz += (rot * vec2(-radiusW,radiusH));
644 gl_Position = u_pMatrix * u_vOmvMatrix * vb;
645 v_texCoord = vec2(0.0, 1.0);
646 v_particleColor = color;
650 vec4 vc = vec4(P.xyz,1);
651 vc.xz += (rot * vec2(radiusW, radiusH));
652 gl_Position = u_pMatrix * u_vOmvMatrix * vc;
653 v_texCoord = vec2(1.0, 1.0);
654 v_particleColor = color;
657 uint actCI = uint(mod(float(uint(vert[0].texNum), float(u_col)));
658 uint actRI = (vert[0].texNum - actCI) / u_col;
659 float actC = float(actCI);
660 float actR = float(actRI);
663 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
664 gl_Position = u_pMatrix * va; // Calculate position in clip space
665 v_texCoord = vec2(actC/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
666 v_particleColor = color;
670 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
671 gl_Position = u_pMatrix * vd;
672 v_texCoord = vec2((actC+1.0)/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
673 v_particleColor = color;
677 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
678 gl_Position = u_pMatrix * vb;
679 v_texCoord = vec2(actC/u_col, 1.0-(actR/u_row)); // Texture coordinate
680 v_particleColor = color;
684 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
685 gl_Position = u_pMatrix * vc;
686 v_texCoord = vec2((actC+1.0)/u_col, 1.0-(actR/u_row)); // Texture coordinate
687 v_particleColor = color;
690 uint actCI = uint(mod(float(vert[0].texNum), float(u_col)));
691 uint actRI = uint((float(vert[0].texNum) - float(actCI)) / float(u_col));
692 float actC = float(actCI);
693 float actR = float(actRI);
696 vec4 va = vec4(P.xyz, 1); //Position in view space
697 va.xz = va.xz + (rot * vec2(-radiusW, -radiusH));
698 gl_Position = u_pMatrix * u_vOmvMatrix * va; // Calculate position in clip space
699 v_texCoord = vec2(actC/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
700 v_particleColor = color;
704 vec4 vd = vec4(P.xyz,1);
705 vd.xz += (rot * vec2(radiusW, -radiusH));
706 gl_Position = u_pMatrix * u_vOmvMatrix * vd;
707 v_texCoord = vec2((actC+1.0)/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
708 v_particleColor = color;
712 vec4 vb = vec4(P.xyz,1);
713 vb.xz += (rot * vec2(-radiusW,radiusH));
714 gl_Position = u_pMatrix * u_vOmvMatrix * vb;
715 v_texCoord = vec2(actC/u_col, 1.0-(actR/u_row)); // Texture coordinate
716 v_particleColor = color;
720 vec4 vc = vec4(P.xyz,1);
721 vc.xz += (rot * vec2(radiusW, radiusH));
722 gl_Position = u_pMatrix * u_vOmvMatrix * vc;
723 v_texCoord = vec2((actC+1.0)/u_col, 1.0-(actR/u_row)); // Texture coordinate
724 v_particleColor = color;
727 uint actCI = uint(mod(float(vert[0].texNum), float(u_col)));
728 uint actRI = uint((float(vert[0].texNum) - float(actCI)) / float(u_col));
729 float actC = float(actCI);
730 float actR = float(actRI);
733 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
734 gl_Position = u_pMatrix * (u_vYawPMatrix * va); // Calculate position in clip space
735 v_texCoord = vec2(actC/float(u_col), 1.0-((actR+1.0)/float(u_row))); // Texture coordinate
736 v_particleColor = color;
740 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
741 gl_Position = u_pMatrix * (u_vYawPMatrix * vd);
742 v_texCoord = vec2((actC+1.0)/float(u_col), 1.0-((actR+1.0)/float(u_row))); // Texture coordinate
743 v_particleColor = color;
747 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
748 gl_Position = u_pMatrix * (u_vYawPMatrix * vb);
749 v_texCoord = vec2(actC/float(u_col), 1.0-(actR/float(u_row))); // Texture coordinate
750 v_particleColor = color;
754 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
755 gl_Position =u_pMatrix * (u_vYawPMatrix * vc);
756 v_texCoord = vec2((actC+1.0)/float(u_col), 1.0-(actR/float(u_row))); // Texture coordinate
757 v_particleColor = color;
762 EndPrimitive(); // Send primitives to fragment shader
766 in vec3 v_P_VS; // Interpol. point of illumination in view space (VS))";
768 in vec3 v_P_WS; // Interpol. point of illumination in world space (WS))";
770 in vec3 v_N_VS; // Interpol. normal at v_P_VS in view space)";
772 in vec3 v_R_OS; // Interpol. reflect in object space)";
774 in vec2 v_uv0; // Texture coordinate varying for uv 0)";
776 in vec2 v_uv1; // Texture coordinate varying for uv 1)";
778 in vec3 v_eyeDirTS; // Vector to the eye in tangent space
779 in vec3 v_lightDirTS[NUM_LIGHTS]; // Vector to light 0 in tangent space
780 in vec3 v_spotDirTS[NUM_LIGHTS]; // Spot direction in tangent space)";
783 in vec4 v_particleColor; // interpolated color from the geometry shader)";
785 in vec2 v_texCoord; // interpolated texture coordinate)";
788 uniform float u_oneOverGamma; // 1.0f / Gamma correction value)";
790 uniform bool u_doWireFrame; // Boolean for wireFrame)";
793 o_fragColor = vec4(0,0,0,0); // Need to be here for the compilation
798 // Just set the interpolated color from the vertex shader
799 o_fragColor = v_particleColor;
801 // componentwise multiply w. texture color
803 o_fragColor *= texture(u_matTextureDiffuse0, v_texCoord);
805 if(o_fragColor.a < 0.001)
809 // componentwise multiply w. texture color
811 o_fragColor = texture(u_matTextureDiffuse0, v_texCoord);
813 o_fragColor = vec4(0,0,0,1.0);
815 o_fragColor.a *= v_particleColor.a;
817 if(o_fragColor.a < 0.001)
821 // componentwise multiply w. texture color
823 o_fragColor = texture(u_matTextureDiffuse0, v_texCoord);
825 o_fragColor = vec4(0,0,0,1.0);
827 o_fragColor.a *= transparency;
829 if(o_fragColor.a < 0.001)
833 // Just set the interpolated color from the vertex shader
835 // componentwise multiply w. texture color
837 o_fragColor *= texture(u_matTextureDiffuse0, v_texCoord);
839 if(o_fragColor.a < 0.001)
843 //Same color for each wireframe
845 o_fragColor = vec4(0,0,0,1.0);
847 o_fragColor.rgb = pow(o_fragColor.rgb, vec3(u_oneOverGamma));
852 uniform bool u_lightIsOn[NUM_LIGHTS]; // flag if light is on
853 uniform vec4 u_lightPosVS[NUM_LIGHTS]; // position of light in view space
854 uniform vec4 u_lightAmbi[NUM_LIGHTS]; // ambient light intensity (Ia)
855 uniform vec4 u_lightDiff[NUM_LIGHTS]; // diffuse light intensity (Id)
856 uniform vec4 u_lightSpec[NUM_LIGHTS]; // specular light intensity (Is)
857 uniform vec3 u_lightSpotDir[NUM_LIGHTS]; // spot direction in view space
858 uniform float u_lightSpotDeg[NUM_LIGHTS]; // spot cutoff angle 1-180 degrees
859 uniform float u_lightSpotCos[NUM_LIGHTS]; // cosine of spot cutoff angle
860 uniform float u_lightSpotExp[NUM_LIGHTS]; // spot exponent
861 uniform vec3 u_lightAtt[NUM_LIGHTS]; // attenuation (const,linear,quadr.)
862 uniform bool u_lightDoAtt[NUM_LIGHTS]; // flag if att. must be calc.
863 uniform vec4 u_globalAmbi; // Global ambient scene color
864 uniform float u_oneOverGamma; // 1.0f / Gamma correction value
867 uniform vec4 u_matAmbi; // ambient color reflection coefficient (ka)
868 uniform vec4 u_matDiff; // diffuse color reflection coefficient (kd)
869 uniform vec4 u_matSpec; // specular color reflection coefficient (ks)
870 uniform vec4 u_matEmis; // emissive color for self-shining materials
871 uniform float u_matShin; // shininess exponent
874 uniform vec4 u_matAmbi; // ambient color reflection coefficient (ka))";
876 uniform vec4 u_matDiff; // diffuse color reflection coefficient (kd))";
878 uniform vec4 u_matEmis; // emissive color (ke))";
880 uniform float u_matRough; // roughness factor (0-1))";
882 uniform float u_matMetal; // metalness factor (0-1)";
885 uniform sampler2D u_matTextureDiffuse0; // Diffuse color map)";
887 uniform sampler2D u_matTextureNormal0; // Normal bump map)";
889 uniform sampler2D u_matTextureEmissive0; // PBR material emissive texture)";
891 uniform sampler2D u_matTextureOcclusion0; // Ambient occlusion map)";
893 uniform sampler2D u_matTextureRoughness0; // PBR material roughness texture)";
895 uniform sampler2D u_matTextureMetallic0; // PBR material metallic texture)";
897 uniform sampler2D u_matTextureRoughMetal0; // PBR material roughness-metallic texture)";
899 uniform sampler2D u_matTextureOccluRoughMetal0; // PBR material occlusion-roughness-metalic texture)";
902 uniform bool u_matGetsShadows; // flag if material receives shadows)";
904 uniform samplerCube u_skyIrradianceCubemap; // PBR skybox irradiance light
905 uniform samplerCube u_skyRoughnessCubemap; // PBR skybox cubemap for rough reflections
906 uniform sampler2D u_skyBrdfLutTexture; // PBR lighting lookup table for BRDF
907 uniform float u_skyExposure; // PBR skybox exposure)";
911 uniform int u_camProjType; // type of stereo
912 uniform int u_camStereoEye; // -1=left, 0=center, 1=right
913 uniform mat3 u_camStereoColors; // color filter matrix
914 uniform bool u_camFogIsOn; // flag if fog is on
915 uniform int u_camFogMode; // 0=LINEAR, 1=EXP, 2=EXP2
916 uniform float u_camFogDensity; // fog density value
917 uniform float u_camFogStart; // fog start distance
918 uniform float u_camFogEnd; // fog end distance
919 uniform vec4 u_camFogColor; // fog color (usually the background)
920 uniform float u_camClipNear; // camera near plane
921 uniform float u_camClipFar; // camera far plane
922 uniform float u_camBkgdWidth; // camera background width
923 uniform float u_camBkgdHeight; // camera background height
924 uniform float u_camBkgdLeft; // camera background left
925 uniform float u_camBkgdBottom; // camera background bottom)";
929 out vec4 o_fragColor; // output fragment color)";
932 //-----------------------------------------------------------------------------
933 void directLightBlinnPhong(in int i, // Light number between 0 and NUM_LIGHTS
934 in vec3 N, // Normalized normal at v_P
935 in vec3 E, // Normalized direction at v_P to the eye
936 in vec3 S, // Normalized light spot direction
937 in float shadow, // shadow factor
938 inout vec4 Ia, // Ambient light intensity
939 inout vec4 Id, // Diffuse light intensity
940 inout vec4 Is) // Specular light intensity
942 // Calculate diffuse & specular factors
943 float diffFactor = max(dot(N, S), 0.0);
944 float specFactor = 0.0;
948 vec3 H = normalize(S + E);// Half vector H between S and E
949 specFactor = pow(max(dot(N, H), 0.0), u_matShin);
952 // accumulate directional light intensities w/o attenuation
953 Ia += u_lightAmbi[i];
954 Id += u_lightDiff[i] * diffFactor * (1.0 - shadow);
955 Is += u_lightSpec[i] * specFactor * (1.0 - shadow);
957 //-----------------------------------------------------------------------------
958 void pointLightBlinnPhong( in int i,
968 // Calculate attenuation over distance & normalize L
974 att_dist.z = dot(L, L);// = distance * distance
975 att_dist.y = sqrt(att_dist.z);// = distance
976 att = min(1.0 / dot(att_dist, u_lightAtt[i]), 1.0);
977 L /= att_dist.y;// = normalize(L)
982 // Calculate diffuse & specular factors
983 vec3 H = normalize(E + L); // Blinn's half vector is faster than Phongs reflected vector
984 float diffFactor = max(dot(N, L), 0.0); // Lambertian downscale factor for diffuse reflection
985 float specFactor = 0.0;
986 if (diffFactor!=0.0) // specular reflection is only possible if surface is lit from front
987 specFactor = pow(max(dot(N, H), 0.0), u_matShin); // specular shininess
989 // Calculate spot attenuation
990 float spotAtt = 1.0;// Spot attenuation
991 if (u_lightSpotDeg[i] < 180.0)
993 float spotDot;// Cosine of angle between L and spotdir
994 spotDot = dot(-L, S);
995 if (spotDot < u_lightSpotCos[i]) // if outside spot cone
998 spotAtt = max(pow(spotDot, u_lightSpotExp[i]), 0.0);
1001 // Accumulate light intensities
1002 Ia += att * u_lightAmbi[i];
1003 Id += att * spotAtt * u_lightDiff[i] * diffFactor * (1.0 - shadow);
1004 Is += att * spotAtt * u_lightSpec[i] * specFactor * (1.0 - shadow);
1008 //-----------------------------------------------------------------------------
1009 vec3 fresnelSchlick(float cosTheta, vec3 F0)
1011 return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
1013 // ----------------------------------------------------------------------------
1014 vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
1016 return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
1018 //-----------------------------------------------------------------------------
1019 float distributionGGX(vec3 N, vec3 H, float roughness)
1021 float PI = 3.14159265;
1022 float a = roughness*roughness;
1024 float NdotH = max(dot(N, H), 0.0);
1025 float NdotH2 = NdotH*NdotH;
1028 float denom = (NdotH2 * (a2 - 1.0) + 1.0);
1029 denom = PI * denom * denom;
1033 //-----------------------------------------------------------------------------
1034 float geometrySchlickGGX(float NdotV, float roughness)
1036 float r = (roughness + 1.0);
1037 float k = (r*r) / 8.0;
1040 float denom = NdotV * (1.0 - k) + k;
1044 //-----------------------------------------------------------------------------
1045 float geometrySmith(vec3 N, vec3 E, vec3 L, float roughness)
1047 float NdotV = max(dot(N, E), 0.0);
1048 float NdotL = max(dot(N, L), 0.0);
1049 float ggx2 = geometrySchlickGGX(NdotV, roughness);
1050 float ggx1 = geometrySchlickGGX(NdotL, roughness);
1053 //-----------------------------------------------------------------------------
1054 void directLightCookTorrance(in int i, // Light index
1055 in vec3 N, // Normalized normal at v_P_VS
1056 in vec3 E, // Normalized vector from v_P to the eye
1057 in vec3 S, // Normalized light spot direction
1058 in vec3 F0, // Fresnel reflection at 90 deg. (0 to N)
1059 in vec3 matDiff, // diffuse material reflection
1060 in float matMetal, // diffuse material reflection
1061 in float matRough, // diffuse material reflection
1062 in float shadow, // shadow factor (0.0 - 1.0)
1063 inout vec3 Lo) // reflected intensity
1065 float PI = 3.14159265;
1066 vec3 H = normalize(E + S); // Normalized halfvector between eye and light vector
1068 vec3 radiance = u_lightDiff[i].rgb; // Per light radiance without attenuation
1070 // cook-torrance brdf
1071 float NDF = distributionGGX(N, H, matRough);
1072 float G = geometrySmith(N, E, S, matRough);
1073 vec3 F = fresnelSchlick(max(dot(H, E), 0.0), F0);
1076 vec3 kD = vec3(1.0) - kS;
1077 kD *= 1.0 - matMetal;
1079 vec3 nominator = NDF * G * F;
1080 float denominator = 4.0 * max(dot(N, E), 0.0) * max(dot(N, S), 0.0) + 0.001;
1081 vec3 specular = nominator / denominator;
1083 // add to outgoing radiance Lo
1084 float NdotL = max(dot(N, S), 0.0);
1086 Lo += (kD*matDiff.rgb/PI + specular) * radiance * NdotL * (1.0 - shadow);
1088 //-----------------------------------------------------------------------------
1089 void pointLightCookTorrance(in int i, // Light index
1090 in vec3 N, // Normalized normal at v_P_VS
1091 in vec3 E, // Normalized vector from v_P to the eye
1092 in vec3 L, // Vector from v_P to the light
1093 in vec3 S, // Normalized light spot direction
1094 in vec3 F0, // Fresnel reflection at 90 deg. (0 to N)
1095 in vec3 matDiff, // diffuse material reflection
1096 in float matMetal, // diffuse material reflection
1097 in float matRough, // diffuse material reflection
1098 in float shadow, // shadow factor (0.0 - 1.0)
1099 inout vec3 Lo) // reflected intensity
1101 float PI = 3.14159265;
1102 float distance = length(L); // distance to light
1103 L /= distance; // normalize light vector
1104 float att = 1.0 / (distance*distance); // quadratic light attenuation
1106 // Calculate spot attenuation
1107 if (u_lightSpotDeg[i] < 180.0)
1109 float spotAtt; // Spot attenuation
1110 float spotDot; // Cosine of angle between L and spotdir
1111 spotDot = dot(-L, S);
1112 if (spotDot < u_lightSpotCos[i]) spotAtt = 0.0;
1113 else spotAtt = max(pow(spotDot, u_lightSpotExp[i]), 0.0);
1117 vec3 radiance = u_lightDiff[i].rgb * att; // per light radiance
1119 // cook-torrance brdf
1120 vec3 H = normalize(E + L); // Normalized halfvector between eye and light vector
1121 float NDF = distributionGGX(N, H, matRough);
1122 float G = geometrySmith(N, E, L, matRough);
1123 vec3 F = fresnelSchlick(max(dot(H, E), 0.0), F0);
1126 vec3 kD = vec3(1.0) - kS;
1127 kD *= 1.0 - matMetal;
1129 vec3 nominator = NDF * G * F;
1130 float denominator = 4.0 * max(dot(N, E), 0.0) * max(dot(N, L), 0.0) + 0.001;
1131 vec3 specular = nominator / denominator;
1133 // add to outgoing radiance Lo
1134 float NdotL = max(dot(N, L), 0.0);
1136 Lo += (kD*matDiff.rgb/PI + specular) * radiance * NdotL * (1.0 - shadow);
1140 //-----------------------------------------------------------------------------
1141 void doStereoSeparation()
1143 // See SLProjType in SLEnum.h
1144 if (u_camProjType > 8) // stereoColors
1146 // Apply color filter but keep alpha
1147 o_fragColor.rgb = u_camStereoColors * o_fragColor.rgb;
1149 else if (u_camProjType == 6) // stereoLineByLine
1151 if (mod(floor(gl_FragCoord.y), 2.0) < 0.5)// even
1153 if (u_camStereoEye ==-1)
1157 if (u_camStereoEye == 1)
1161 else if (u_camProjType == 7) // stereoColByCol
1163 if (mod(floor(gl_FragCoord.x), 2.0) < 0.5)// even
1165 if (u_camStereoEye ==-1)
1169 if (u_camStereoEye == 1)
1173 else if (u_camProjType == 8) // stereoCheckerBoard
1175 bool h = (mod(floor(gl_FragCoord.x), 2.0) < 0.5);
1176 bool v = (mod(floor(gl_FragCoord.y), 2.0) < 0.5);
1177 if (h==v)// both even or odd
1179 if (u_camStereoEye ==-1)
1183 if (u_camStereoEye == 1)
1190 //-----------------------------------------------------------------------------
1191 vec4 fogBlend(vec3 P_VS, vec4 inColor)
1193 float factor = 0.0f;
1194 float distance = length(P_VS);
1196 switch (u_camFogMode)
1199 factor = (u_camFogEnd - distance) / (u_camFogEnd - u_camFogStart);
1202 factor = exp(-u_camFogDensity * distance);
1205 factor = exp(-u_camFogDensity * distance * u_camFogDensity * distance);
1209 vec4 outColor = factor * inColor + (1.0 - factor) * u_camFogColor;
1210 outColor = clamp(outColor, 0.0, 1.0);
1215 //-----------------------------------------------------------------------------
1216 void doColoredShadows(in vec3 N)
1218 const vec3 SHADOW_COLOR[6] = vec3[6](vec3(1.0, 0.0, 0.0),
1219 vec3(0.0, 1.0, 0.0),
1220 vec3(0.0, 0.0, 1.0),
1221 vec3(1.0, 1.0, 0.0),
1222 vec3(0.0, 1.0, 1.0),
1223 vec3(1.0, 0.0, 1.0));
1225 for (int i = 0; i < NUM_LIGHTS; ++i)
1229 if (u_lightPosVS[i].w == 0.0)
1231 // We use the spot light direction as the light direction vector
1232 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1234 // Test if the current fragment is in shadow
1235 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1236 if (u_lightNumCascades[i] > 0)
1238 int casIndex = getCascadesDepthIndex(i, u_lightNumCascades[i]);
1239 o_fragColor.rgb += shadow * SHADOW_COLOR[casIndex];
1241 o_fragColor.rgb += shadow * SHADOW_COLOR[0];
1245 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1247 // Test if the current fragment is in shadow
1248 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1249 o_fragColor.rgb += shadow * SHADOW_COLOR[0];
1256 vec4 Ia = vec4(0.0); // Accumulated ambient light intensity at v_P_VS
1257 vec4 Id = vec4(0.0); // Accumulated diffuse light intensity at v_P_VS
1258 vec4 Is = vec4(0.0); // Accumulated specular light intensity at v_P_VS
1262 vec3 E = normalize(-v_P_VS); // Interpolated vector from p to the eye
1263 vec3 N = normalize(v_N_VS); // A input normal has not anymore unit length
1266 vec3 E = normalize(v_eyeDirTS); // normalized interpolated eye direction
1268 // Get normal from normal map, move from [0,1] to [-1, 1] range & normalize
1269 vec3 N = normalize(texture(u_matTextureNormal0, v_uv0).rgb * 2.0 - 1.0);
1272 vec4 matEmis = u_matEmis;)";
1274 vec4 matEmis = texture(u_matTextureEmissive0, v_uv0);)";
1276 float matOccl = 1.0;)";
1278 float matOccl = texture(u_matTextureOcclusion0, v_uv0).r;)";
1280 float matOccl = texture(u_matTextureOcclusion0, v_uv1).r;)";
1284 // Get the reflection from all lights into Ia, Id & Is
1285 for (int i = 0; i < NUM_LIGHTS; ++i)
1289 if (u_lightPosVS[i].w == 0.0)
1291 // We use the spot light direction as the light direction vector
1292 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1293 directLightBlinnPhong(i, N, E, S, 0.0, Ia, Id, Is);
1297 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1298 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1299 pointLightBlinnPhong(i, N, E, S, L, 0.0, Ia, Id, Is);
1306 // Get the reflection from all lights into Ia, Id & Is
1307 for (int i = 0; i < NUM_LIGHTS; ++i)
1311 if (u_lightPosVS[i].w == 0.0)
1313 // We use the spot light direction as the light direction vector
1314 vec3 S = normalize(-v_spotDirTS[i]);
1315 directLightBlinnPhong(i, N, E, S, 0.0, Ia, Id, Is);
1319 vec3 S = normalize(v_spotDirTS[i]); // normalized spot direction in TS
1320 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1321 pointLightBlinnPhong(i, N, E, S, L, 0.0, Ia, Id, Is);
1328 // Get the reflection from all lights into Ia, Id & Is
1329 for (int i = 0; i < NUM_LIGHTS; ++i)
1333 if (u_lightPosVS[i].w == 0.0)
1335 // We use the spot light direction as the light direction vector
1336 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1338 // Test if the current fragment is in shadow
1339 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1340 directLightBlinnPhong(i, N, E, S, shadow, Ia, Id, Is);
1344 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1345 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1347 // Test if the current fragment is in shadow
1348 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1349 pointLightBlinnPhong(i, N, E, S, L, shadow, Ia, Id, Is);
1356 // Get the reflection from all lights into Ia, Id & Is
1357 for (int i = 0; i < NUM_LIGHTS; ++i)
1361 if (u_lightPosVS[i].w == 0.0)
1363 // We use the spot light direction as the light direction vector
1364 vec3 S = normalize(-v_spotDirTS[i]);
1366 // Test if the current fragment is in shadow
1367 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1368 directLightBlinnPhong(i, N, E, S, shadow, Ia, Id, Is);
1372 vec3 S = normalize(v_spotDirTS[i]); // normalized spot direction in TS
1373 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1375 // Test if the current fragment is in shadow
1376 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1377 pointLightBlinnPhong(i, N, E, S, L, shadow, Ia, Id, Is);
1383 // Sum up all the reflected color components
1384 o_fragColor = u_matEmis +
1386 Ia * u_matAmbi * matOccl +
1390 // For correct alpha blending overwrite alpha component
1391 o_fragColor.a = u_matDiff.a;
1394 // Sum up all the reflected color components
1395 o_fragColor = u_matEmis +
1397 Ia * u_matAmbi * matOccl +
1400 // Componentwise multiply w. texture color
1401 o_fragColor *= texture(u_matTextureDiffuse0, v_uv0);
1403 // add finally the specular RGB-part
1404 vec4 specColor = Is * u_matSpec;
1405 o_fragColor.rgb += specColor.rgb;
1409 // Colorize cascaded shadows for debugging purpose
1410 if (u_lightsDoColoredShadows)
1411 doColoredShadows(N);
1415 // Apply fog by blending over distance
1417 o_fragColor = fogBlend(v_P_VS, o_fragColor);
1419 // Apply gamma correction
1420 o_fragColor.rgb = pow(o_fragColor.rgb, vec3(u_oneOverGamma));
1422 // Apply stereo eye separation
1423 if (u_camProjType > 1)
1424 doStereoSeparation();
1429 vec4 matDiff = u_matDiff;)";
1431 vec4 matDiff = pow(texture(u_matTextureDiffuse0, v_uv0), vec4(2.2));)";
1433 vec4 matEmis = u_matEmis;)";
1435 vec4 matEmis = pow(texture(u_matTextureEmissive0, v_uv0), vec4(2.2));)";
1437 float matRough = u_matRough;)";
1439 float matRough = texture(u_matTextureRoughness0, v_uv0).r;)";
1441 float matRough = texture(u_matTextureRoughMetal0, v_uv0).g;)";
1443 float matRough = texture(u_matTextureOccluRoughMetal0, v_uv0).g;)";
1445 float matMetal = u_matMetal;)";
1447 float matMetal = texture(u_matTextureMetallic0, v_uv0).r;)";
1449 float matMetal = texture(u_matTextureRoughMetal0, v_uv0).b;)";
1451 float matMetal = texture(u_matTextureOccluRoughMetal0, v_uv0).b;)";
1453 float matOccl = 1.0;)";
1455 float matOccl = texture(u_matTextureOcclusion0, v_uv0).r;)";
1457 float matOccl = texture(u_matTextureOcclusion0, v_uv1).r;)";
1459 float matOccl = texture(u_matTextureOccluRoughMetal0, v_uv0).r;)";
1462 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1463 F0 = mix(F0, matDiff.rgb, matMetal);
1465 // Get the reflection from all lights into Lo
1466 vec3 Lo = vec3(0.0);
1467 for (int i = 0; i < NUM_LIGHTS; ++i)
1471 if (u_lightPosVS[i].w == 0.0)
1473 // We use the spot light direction as the light direction vector
1474 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1475 directLightCookTorrance(i, N, E, S, F0,
1484 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
1485 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1486 pointLightCookTorrance( i, N, E, L, S, F0,
1498 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1499 F0 = mix(F0, matDiff.rgb, matMetal);
1501 // Get the reflection from all lights into Lo
1502 vec3 Lo = vec3(0.0);
1503 for (int i = 0; i < NUM_LIGHTS; ++i)
1507 if (u_lightPosVS[i].w == 0.0)
1509 // We use the spot light direction as the light direction vector
1510 vec3 S = normalize(-v_spotDirTS[i]);
1511 directLightCookTorrance(i, N, E, S, F0,
1520 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1521 vec3 S = normalize(-v_spotDirTS[i]);
1522 pointLightCookTorrance( i, N, E, L, S, F0,
1534 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1535 F0 = mix(F0, matDiff.rgb, matMetal);
1537 // Get the reflection from all lights into Lo
1538 vec3 Lo = vec3(0.0);
1539 for (int i = 0; i < NUM_LIGHTS; ++i)
1543 if (u_lightPosVS[i].w == 0.0)
1545 // We use the spot light direction as the light direction vector
1546 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1548 // Test if the current fragment is in shadow
1549 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1550 directLightCookTorrance(i, N, E, S, F0,
1559 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
1560 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1562 // Test if the current fragment is in shadow
1563 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1564 pointLightCookTorrance( i, N, E, L, S, F0,
1576 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1577 F0 = mix(F0, matDiff.rgb, matMetal);
1579 // Get the reflection from all lights into Lo
1580 vec3 Lo = vec3(0.0);
1581 for (int i = 0; i < NUM_LIGHTS; ++i)
1585 if (u_lightPosVS[i].w == 0.0)
1587 // We use the spot light direction as the light direction vector
1588 vec3 S = normalize(-v_spotDirTS[i]);
1590 // Test if the current fragment is in shadow
1591 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1592 directLightCookTorrance(i, N, E, S, F0,
1601 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1602 vec3 S = normalize(-v_spotDirTS[i]);
1604 // Test if the current fragment is in shadow
1605 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1606 pointLightCookTorrance( i, N, E, L, S, F0,
1617 // ambient lighting (note that the next IBL tutorial will replace
1618 // this ambient lighting with environment lighting).
1619 vec3 ambient = vec3(0.03) * matDiff.rgb * matOccl;
1621 vec3 color = ambient + matEmis.rgb + Lo;
1624 color = color / (color + vec3(1.0));
1625 o_fragColor = vec4(color, 1.0);
1627 // For correct alpha blending overwrite alpha component
1628 o_fragColor.a = matDiff.a;
1631 // Build diffuse reflection from environment light map
1632 vec3 F = fresnelSchlickRoughness(max(dot(N, E), 0.0), F0, matRough);
1635 kD *= 1.0 - matMetal;
1636 vec3 irradiance = texture(u_skyIrradianceCubemap, N).rgb;
1637 vec3 diffuse = kD * irradiance * matDiff.rgb;
1639 // sample both the pre-filter map and the BRDF lut and combine them together as per the split-sum approximation to get the IBL specular part.
1640 const float MAX_REFLECTION_LOD = 4.0;
1641 vec3 prefilteredColor = textureLod(u_skyRoughnessCubemap, v_R_OS, matRough * MAX_REFLECTION_LOD).rgb;
1642 vec2 brdf = texture(u_skyBrdfLutTexture, vec2(max(dot(N, E), 0.0), matRough)).rg;
1643 vec3 specular = prefilteredColor * (F * brdf.x + brdf.y);
1644 vec3 ambient = (diffuse + specular) * matOccl;
1646 vec3 color = ambient + matEmis.rgb + Lo;
1648 // Exposure tone mapping
1649 vec3 mapped = vec3(1.0) - exp(-color * u_skyExposure);
1650 o_fragColor = vec4(mapped, 1.0);
1652 // For correct alpha blending overwrite alpha component
1653 o_fragColor.a = matDiff.a;
1657 float x = (gl_FragCoord.x - u_camBkgdLeft) / u_camBkgdWidth;
1658 float y = (gl_FragCoord.y - u_camBkgdBottom) / u_camBkgdHeight;
1660 if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f)
1661 o_fragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
1663 o_fragColor = texture(u_matTextureDiffuse0, vec2(x, y));
1665 vec3 N = normalize(v_N_VS); // A input normal has not anymore unit length
1668 // Colorize cascaded shadows for debugging purpose
1669 if (u_lightsDoColoredShadows)
1670 doColoredShadows(N);
1673 for (int i = 0; i < NUM_LIGHTS; ++i)
1677 if (u_lightPosVS[i].w == 0.0)
1679 // We use the spot light direction as the light direction vector
1680 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1682 // Test if the current fragment is in shadow
1683 shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1687 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1689 // Test if the current fragment is in shadow
1690 shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1692 o_fragColor = o_fragColor * min(1.0 - shadow + u_matAmbi.r, 1.0);
1726 SLbool supportGPUSkinning,
1727 string& programName)
1729 assert(mat &&
"No material pointer passed!");
1730 assert(lights && !lights->empty() &&
"No lights passed!");
1732 programName =
"gen";
1735 programName +=
"VideoBkgdDm";
1737 programName +=
"Blinn";
1739 programName +=
"Cook";
1741 programName +=
"Custom";
1747 for (
auto light : *lights)
1749 if (light->positionWS().w == 0.0f)
1751 if (light->doCascadedShadows())
1752 programName +=
"C" + std::to_string(light->shadowMap()->numCascades());
1756 else if (light->spotCutOffDEG() < 180.0f)
1760 if (light->createsShadows())
1764 if (supportGPUSkinning)
1765 programName +=
"-S";
1790 string& programName,
1794 assert(mat &&
"No material pointer passed!");
1795 programName =
"gen";
1798 programName +=
"Particle";
1800 programName +=
"Custom";
1805 programName +=
"-Draw";
1808 programName +=
"-Inst";
1811 GLint billboardType = mat->
ps()->billboardType();
1812 bool AlOvLi = mat->
ps()->doAlphaOverLT();
1813 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
1814 bool SiOvLi = mat->
ps()->doSizeOverLT();
1815 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
1816 bool Co = mat->
ps()->doColor();
1817 bool CoOvLi = mat->
ps()->doColorOverLT();
1818 bool FlBoTex = mat->
ps()->doFlipBookTexture();
1819 bool WS = mat->
ps()->doWorldSpace();
1820 bool rot = mat->
ps()->doRotation();
1821 programName +=
"-B" + std::to_string(billboardType);
1822 if (rot) programName +=
"-RT";
1823 if (AlOvLi) programName +=
"-AL";
1824 if (AlOvLi && AlOvLiCu) programName +=
"cu";
1825 if (SiOvLi) programName +=
"-SL";
1826 if (SiOvLi && SiOvLiCu) programName +=
"cu";
1827 if (Co) programName +=
"-CO";
1828 if (Co && CoOvLi) programName +=
"cl";
1829 if (FlBoTex) programName +=
"-FB";
1830 if (WS) programName +=
"-WS";
1834 bool counterGap = mat->
ps()->doCounterGap();
1835 bool acc = mat->
ps()->doAcc();
1836 bool accDiffDir = mat->
ps()->doAccDiffDir();
1837 bool gravity = mat->
ps()->doGravity();
1838 bool FlBoTex = mat->
ps()->doFlipBookTexture();
1839 bool rot = mat->
ps()->doRotation();
1840 bool rotRange = mat->
ps()->doRotRange();
1841 bool shape = mat->
ps()->doShape();
1842 programName +=
"-Update";
1843 if (counterGap) programName +=
"-CG";
1844 if (rot) programName +=
"-RT";
1845 if (rot) programName += rotRange ?
"ra" :
"co";
1848 programName +=
"-AC";
1849 programName += accDiffDir ?
"di" :
"co";
1851 if (gravity) programName +=
"-GR";
1852 if (FlBoTex) programName +=
"-FB";
1853 if (shape) programName +=
"-SH";
1865 SLbool supportGPUSkinning)
1867 assert(mat &&
"No material pointer passed!");
1868 assert(!lights->empty() &&
"No lights passed!");
1879 bool env = mat->
skybox() !=
nullptr;
1897 SL_EXIT_MSG(
"SLGLProgramGenerated::buildProgramCode: Unknown program for RM_Custom.");
1900 SL_EXIT_MSG(
"SLGLProgramGenerated::buildProgramCode: Unknown Lighting Model.");
1913 if (mat->
name() ==
"IBLMat")
1915 std::cout <<
"build program code for IBLMat" << std::endl;
1917 assert(mat &&
"No material pointer passed!");
1937 SLbool supportGPUSkinning)
1939 assert(mat && lights);
1959 bool sky = mat->
skybox() !=
nullptr;
1997 setVariable(vertCode,
"localPosition", supportGPUSkinning ?
"skinnedPosition" :
"a_position");
1998 setVariable(vertCode,
"localNormal", supportGPUSkinning ?
"skinnedNormal" :
"a_normal");
1999 if (Nm)
setVariable(vertCode,
"localTangent", supportGPUSkinning ?
"skinnedTangent" :
"a_tangent");
2071 SLbool supportGPUSkinning)
2073 assert(mat && lights);
2123 setVariable(vertCode,
"localPosition", supportGPUSkinning ?
"skinnedPosition" :
"a_position");
2124 setVariable(vertCode,
"localNormal", supportGPUSkinning ?
"skinnedNormal" :
"a_normal");
2125 if (Nm)
setVariable(vertCode,
"localTangent", supportGPUSkinning ?
"skinnedTangent" :
"a_tangent");
2190 GLint billboardType = mat->
ps()->billboardType();
2191 bool rot = mat->
ps()->doRotation();
2192 bool AlOvLi = mat->
ps()->doAlphaOverLT();
2193 bool Co = mat->
ps()->doColor();
2194 bool CoOvLi = mat->
ps()->doColorOverLT();
2195 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
2196 bool SiOvLi = mat->
ps()->doSizeOverLT();
2197 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
2198 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2325 GLint billboardType = mat->
ps()->billboardType();
2326 bool rot = mat->
ps()->doRotation();
2327 bool AlOvLi = mat->
ps()->doAlphaOverLT();
2328 bool Co = mat->
ps()->doColor();
2329 bool CoOvLi = mat->
ps()->doColorOverLT();
2330 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
2331 bool SiOvLi = mat->
ps()->doSizeOverLT();
2332 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
2333 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2476 bool counterGap = mat->
ps()->doCounterGap();
2477 bool acc = mat->
ps()->doAcc();
2478 bool accDiffDir = mat->
ps()->doAccDiffDir();
2479 bool gravity = mat->
ps()->doGravity();
2480 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2481 bool rot = mat->
ps()->doRotation();
2482 bool rotRange = mat->
ps()->doRotRange();
2483 bool shape = mat->
ps()->doShape();
2579 setVariable(vertCode,
"localPosition",
"a_position");
2588 in vec3 v_P_VS; // Interpol. point of illumination in view space (VS)
2589 in vec3 v_P_WS; // Interpol. point of illumination in world space (WS)
2590 in vec3 v_N_VS; // Interpol. normal at v_P_VS in view space
2615 for (
auto light : *lights)
2617 if (light->createsShadows())
2625 string u_lightSm = R
"(
2626 uniform vec4 u_lightPosWS[NUM_LIGHTS]; // position of light in world space
2627 uniform bool u_lightCreatesShadows[NUM_LIGHTS]; // flag if light creates shadows
2628 uniform int u_lightNumCascades[NUM_LIGHTS]; // number of cascades for cascaded shadowmap
2629 uniform bool u_lightDoSmoothShadows[NUM_LIGHTS]; // flag if percentage-closer filtering is enabled
2630 uniform int u_lightSmoothShadowLevel[NUM_LIGHTS]; // radius of area to sample for PCF
2631 uniform float u_lightShadowMinBias[NUM_LIGHTS]; // min. shadow bias value at 0° to N
2632 uniform float u_lightShadowMaxBias[NUM_LIGHTS]; // min. shadow bias value at 90° to N
2633 uniform bool u_lightUsesCubemap[NUM_LIGHTS]; // flag if light has a cube shadow map
2634 uniform bool u_lightsDoColoredShadows; // flag if shadows should be colored
2636 for (
SLuint i = 0; i < lights->size(); ++i)
2638 SLLight* light = lights->at(i);
2645 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
"[6];\n";
2649 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
"[" + std::to_string(shadowMap->
numCascades()) +
"];\n";
2653 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
";\n";
2662 string smDecl =
"\n";
2663 for (
SLuint i = 0; i < lights->size(); ++i)
2665 SLLight* light = lights->at(i);
2670 smDecl +=
"uniform samplerCube u_shadowMapCube_" + to_string(i) +
";\n";
2673 for (
int j = 0; j < light->
shadowMap()->depthBuffers().size(); j++)
2674 smDecl +=
"uniform sampler2D u_cascadedShadowMap_" + to_string(i) +
"_" + std::to_string(j) +
";\n";
2676 smDecl +=
"uniform float u_cascadesFactor_" + to_string(i) +
";\n";
2679 smDecl +=
"uniform sampler2D u_shadowMap_" + to_string(i) +
";\n";
2688 bool doCascadedSM =
false;
2689 for (
SLLight* light : *lights)
2691 if (light->doCascadedShadows())
2693 doCascadedSM =
true;
2698 string shadowTestCode = R
"(
2699 //-----------------------------------------------------------------------------
2700 int vectorToFace(vec3 vec) // Vector to process
2702 vec3 absVec = abs(vec);
2703 if (absVec.x > absVec.y && absVec.x > absVec.z)
2704 return vec.x > 0.0 ? 0 : 1;
2705 else if (absVec.y > absVec.x && absVec.y > absVec.z)
2706 return vec.y > 0.0 ? 2 : 3;
2708 return vec.z > 0.0 ? 4 : 5;
2710 //-----------------------------------------------------------------------------
2711 int getCascadesDepthIndex(in int i, int numCascades)
2716 for (
SLuint i = 0; i < lights->size(); ++i)
2718 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2721 shadowTestCode +=
" if (i == " + std::to_string(i) +
")\n";
2722 shadowTestCode +=
" {\n";
2723 shadowTestCode +=
" factor = u_cascadesFactor_" + std::to_string(i) +
";\n";
2724 shadowTestCode +=
" }\n";
2728 shadowTestCode += R
"(
2729 float fi = u_camClipNear;
2732 for (int i = 0; i < numCascades-1; i++)
2735 fi = factor * u_camClipNear * pow((u_camClipFar/(factor*u_camClipNear)), float(i+1)/float(numCascades));
2739 return numCascades-1;
2741 //-----------------------------------------------------------------------------
2742 float shadowTest(in int i, in vec3 N, in vec3 lightDir)
2744 if (u_lightCreatesShadows[i])
2746 // Calculate position in light space
2748 vec3 lightToFragment = v_P_WS - u_lightPosWS[i].xyz;
2751 if (doCascadedSM > 0)
2753 shadowTestCode += R
"(
2756 if (u_lightNumCascades[i] > 0)
2758 index = getCascadesDepthIndex(i, u_lightNumCascades[i]);
2760 for (
SLuint i = 0; i < lights->size(); ++i)
2762 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2764 shadowTestCode +=
" if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"[index]; }\n";
2766 shadowTestCode += R
"(
2768 else if (u_lightUsesCubemap[i])
2770 for (
SLuint i = 0; i < lights->size(); ++i)
2772 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2774 shadowTestCode +=
" if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"[vectorToFace(lightToFragment)]; }\n";
2776 shadowTestCode += R
"(
2781 for (
SLuint i = 0; i < lights->size(); ++i)
2783 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2785 shadowTestCode +=
"if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"}\n";
2787 shadowTestCode += R
"(
2793 shadowTestCode += R
"(
2794 if (u_lightUsesCubemap[i])
2797 for (
SLuint i = 0; i < lights->size(); ++i)
2799 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2801 shadowTestCode +=
" if (i == " + std::to_string(i) +
") lightSpace = u_lightSpace_" + std::to_string(i) +
"[vectorToFace(lightToFragment)];\n";
2803 shadowTestCode += R
"(
2808 for (
SLuint i = 0; i < lights->size(); ++i)
2810 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2812 shadowTestCode +=
" if (i == " + std::to_string(i) +
") lightSpace = u_lightSpace_" + std::to_string(i) +
";\n";
2814 shadowTestCode += R
"(
2819 shadowTestCode += R"(
2820 vec4 lightSpacePosition = lightSpace * vec4(v_P_WS, 1.0);
2822 // Normalize lightSpacePosition
2823 vec3 projCoords = lightSpacePosition.xyz / lightSpacePosition.w;
2825 // Convert to texture coordinates
2826 projCoords = projCoords * 0.5 + 0.5;
2828 float currentDepth = projCoords.z;
2830 // Look up depth from shadow map
2834 // calculate bias between min. and max. bias depending on the angle between N and lightDir
2835 float bias = max(u_lightShadowMaxBias[i] * (1.0 - dot(N, lightDir)), u_lightShadowMinBias[i]);
2837 // Use percentage-closer filtering (PCF) for softer shadows (if enabled)
2838 if (u_lightDoSmoothShadows[i])
2840 int level = u_lightSmoothShadowLevel[i];
2844 for (
SLuint i = 0; i < lights->size(); ++i)
2846 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2848 shadowTestCode +=
" if (i == " + to_string(i) +
") { texelSize = 1.0 / vec2(textureSize(u_shadowMap_" + to_string(i) +
", 0)); }\n";
2851 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2852 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2853 shadowTestCode +=
" if (index == " + to_string(j) +
") { texelSize = 1.0 / vec2(textureSize(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", 0)); }\n";
2855 shadowTestCode +=
" }\n";
2858 shadowTestCode += R
"(
2859 for (int x = -level; x <= level; ++x)
2861 for (int y = -level; y <= level; ++y)
2864 for (
SLuint i = 0; i < lights->size(); ++i)
2866 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2868 shadowTestCode +=
" if (i == " + to_string(i) +
") { closestDepth = texture(u_shadowMap_" + to_string(i) +
", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2871 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2872 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2873 shadowTestCode +=
" if (index == " + to_string(j) +
") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2874 shadowTestCode +=
" }\n";
2878 shadowTestCode += R
"(
2879 shadow += currentDepth - bias > closestDepth ? 1.0 : 0.0;
2882 shadow /= pow(1.0 + 2.0 * float(level), 2.0);
2886 if (u_lightUsesCubemap[i])
2889 for (
SLuint i = 0; i < lights->size(); ++i)
2891 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2893 shadowTestCode +=
" if (i == " + to_string(i) +
") closestDepth = texture(u_shadowMapCube_" + to_string(i) +
", lightToFragment).r;\n";
2895 shadowTestCode += R
"(
2897 else if (u_lightNumCascades[i] > 0)
2900 for (
SLuint i = 0; i < lights->size(); ++i)
2902 SLLight* light = lights->at(i);
2903 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2906 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2907 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2908 shadowTestCode +=
" if (index == " + to_string(j) +
") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", projCoords.xy).r; }\n";
2909 shadowTestCode +=
" }";
2913 shadowTestCode += R
"(
2919 for (
SLuint i = 0; i < lights->size(); ++i)
2921 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2923 shadowTestCode +=
" if (i == " + to_string(i) +
") closestDepth = texture(u_shadowMap_" + to_string(i) +
", projCoords.xy).r;\n";
2926 shadowTestCode += R
"(
2929 // The fragment is in shadow if the light doesn't "see" it
2930 if (currentDepth > closestDepth + bias)
2940 return shadowTestCode;
2949 #if defined(DEBUG) && defined(_DEBUG)
2956 #ifndef SL_EMSCRIPTEN
2960 SL_EXIT_MSG(
"SLGLProgramGenerated::addCodeToShader: SLGLProgramManager::configPath not existing");
2966 SL_EXIT_MSG(
"SLGLProgramGenerated::addCodeToShader: Failed to created SLGLProgramManager::configPath/generatedShaders");
2977 const std::string& name,
2978 const std::string& value)
2980 std::string placeholder =
"${" +
name +
"}";
2982 std::string::size_type pos = 0;
2983 while ((pos = code.find(placeholder)) != std::string::npos)
2985 code.replace(pos, placeholder.size(), value);
2986 pos += value.size();
2994 string header =
"\nprecision highp float;\n";
2995 header +=
"\n#define NUM_LIGHTS " + to_string(numLights) +
"\n";
3004 string header =
"\nprecision highp float;\n";
#define SL_EXIT_MSG(message)
Uses an OpenGL framebuffer object as a depth-buffer.
const string vertOutput_PS_tf_initP
const string vertInput_PS_a_v
const string vertMain_PS_instanced_v_t_begin
const string fragMainCook_3_FragColorSky
const string vertMain_EndAll
const string vertOutput_v_uv1
const string fragMain_1_matOccl_Om0
const string fragInput_v_uv0
const string vertMain_v_P_VS
const string fragOutputs_o_fragColor
const string vertMain_PS_v_age
const string fragMainVideoBkgd
const string fragMainBlinn_3_FragColor
const string fragMain_5_FogGammaStereo
const string vertInput_PS_u_row
const string geomMain_PS_fourCorners_horizBillboard
const string geomMain_PS_Flipbook_fourCorners
const string vertMain_PS_U_reset_v
const string vertInput_PS_u_g
const string vertMain_PS_U_v_rRange
const string vertMain_PS_instanced_v_s_curve
const string fragMainBlinn_2_LightLoopSm
const string fragInput_PS_u_wireFrame
const string geomMain_PS_v_rot
const string fragMain_1_matOccl_Om1
const string fragMain_1_matEmis_Em
const string vertMain_PS_U_reset_shape_p
const string fragMainCook_1_matRough
const string geomInput_PS_u_ScaRa
const string vertOutput_PS_struct_Begin
const string vertMain_PS_v_texNum
const string vertMain_PS_U_v_init_v
const string fragInput_PS_age
const string geomInput_u_matrix_vertBillboard
const string fragMainCook_1_matOcclu_ORMm
const string vertMain_PS_U_alive_a_const
const string fragInput_PS_v_pC
const string geomInput_PS_u_row
const string fragInput_u_matTexRm
const string fragInput_u_matTexRmMm
const string vertMain_PS_U_v_init_st
const string geomInput_PS_struct_s
const string vertMain_PS_U_EndAll
const string fragMain_1_EN_in_VS
const string fragInput_v_R_OS
const string vertMain_PS_U_reset_st
const string vertOutput_v_N_VS
const string vertMain_v_uv0
const string fragMainBlinn_2_LightLoopNm
const string geomInput_PS_struct_t
const string vertMain_PS_U_v_init_texNum
const string fragFunctionFogBlend
const string geomInput_PS_struct_texNum
const string vertMain_PS_EndAll
const string fragMain_PS_withoutColor
const string fragFunctionsLightingBlinnPhong
const string vertInput_PS_u_time
const string geomInput_PS_u_col
const string vertMain_PS_instanced_EndAll
const string vertMain_PS_U_Begin
const string vertMain_PS_instanced_v_sS
const string vertInput_PS_a_initP
const string vertInput_PS_u_ScaRa
const string geomMain_PS_EndAll
const string fragMainCook_3_FragColor
const string fragInput_PS_u_c
const string vertInput_a_tangent
const string vertInput_PS_u_deltaTime
const string vertMain_PS_instanced_v_t_curve
const string fragInput_u_matTexEm
const string vertInput_PS_u_al_bernstein_size
const string fragInput_u_lightAll
const string fragMainCook_1_matOcclu_Om0
const string geomOutput_PS_v_pC
const string vertMain_PS_v_t_end
const string vertInput_PS_a_p
const string fragInput_u_matMetal
const string fragMainCook_2_LightLoopNm
const string fragMainCook_1_matDiff
const string vertOutput_PS_tf_r
const string vertMain_PS_U_v_init_r
const string vertMain_v_N_VS
const string vertOutput_v_lightVecTS
const string vertInput_a_uv0
const string fragInput_u_matGetsSm
const string fragInput_u_matRough
const string vertFunction_PS_ColorOverLT
const string fragInput_u_matDiff
const string geomMain_PS_fourCorners_vertBillboard
const string fragInput_PS_u_colorOvLF
const string geomInput_PS_struct_r
const string fragMain_PS_endAll
const string fragInput_PS_u_tTL
const string fragMain_PS_instanced_transparency
const string vertMain_PS_v_t_curve
const string vertMain_PS_instanced_v_t_linear
const string fragInput_u_matAmbi
const string fragMainCook_1_matDiff_Dm
const string fragInput_u_cam
const string fragMainCook_1_matOcclu_1
const string vertInput_PS_u_a_diffDir
const string vertMain_PS_instanced_rotate
const string fragMainCook_2_LightLoop
const string vertOutput_PS_struct_texNum
const string vertInput_a_skinning
const string fragFunctionDoStereoSeparation
const string fragInput_u_matTexOm
const string fragMainCook_1_matMetal_RMm
const string vertMain_PS_instanced_v_t_default
const string vertInput_PS_u_pgPos
const string fragMainCook_1_matEmis_Em
const string vertInput_a_pn
const string vertMain_v_P_WS_Sm
const string vertMain_PS_v_t_default
const string fragInput_u_matBlinnAll
const string vertInput_PS_a_texNum
const string vertMain_PS_U_v_init_r_angularVelo
const string vertInput_u_matrix_p
const string geomMain_PS_fourCorners
const string vertInput_PS_u_angularVelo
const string vertMain_PS_U_reset_p
const string vertOutput_PS_struct_c
const string vertMain_PS_U_alive_g
const string vertInput_u_matrix_vOmv
const string vertOutput_PS_tf_p
const string vertMain_PS_EndAll_VertBillboard
const string geomMain_PS_v_withoutColor
const string vertInput_PS_u_colorOvLF
const string fragMainCook_1_matRough_RMm
const string fragMainCook_1_matMetal_Mm
const string fragMain_instanced_PS_end
const string fragMainCook_2_LightLoopSm
const string vertInput_PS_u_condFB
const string fragMainCook_1_matEmis
const string fragInput_u_skyCookEnvMaps
const string vertInput_u_skinning
const string fragInput_v_N_VS
const string fragFunction_PS_ColorOverLT
const string geomOutput_PS_v_tC
const string vertOutput_PS_tf_st
const string fragMain_PS_instanced_c
const string geomInput_u_matrix_p
const string fragInput_v_lightVecTS
const string geomMain_PS_v_p
const string fragMainBlinn_2_LightLoopNmSm
const string fragInput_u_matTexOmRmMm
const string vertMain_v_uv1
const string geomConfig_PS
const string vertConstant_PS_pi
const string vertOutput_PS_age
const string vertInput_PS_u_col
const string vertMain_PS_v_t_linear
const string vertInput_PS_u_a_const
const string vertOutput_PS_tf_r_angularVelo
const string vertInput_PS_a_r_angularVelo
const string fragInput_v_P_VS
const string fragMainCook_1_matMetal
const string geomMain_PS_v_cT
const string vertMain_PS_U_alive_a_diffDir
const string geomInput_PS_struct_Begin
const string vertMain_TBN_Nm
const string vertMain_skinning_Nm
const string fragInput_PS_u_overG
const string vertOutput_PS_struct_s
const string vertMain_PS_v_s_curve
const string vertMain_PS_instanced_v_s
const string vertMain_PS_instanced_EndAll_VertBillboard
const string vertOutput_PS_struct_End
const string geomMain_PS_v_doColorOverLT
const string vertInput_PS_a_st
const string vertInput_PS_a_initV
const string vertOutput_PS_tf_v
const string vertOutput_PS_v_tC
const string geomInput_PS_struct_c
const string vertOutput_v_uv0
const string vertOutput_PS_tf_texNum
const string vertMain_PS_U_alive_texNum
const string vertOutput_PS_struct_t
const string vertMain_PS_U_v_init_initP
const string fragInput_v_P_WS
const string vertOutput_v_P_WS
const string vertMain_PS_U_v_init_initV
const string vertInput_u_lightNm
const string fragFunctionsLightingCookTorrance
const string fragMain_4_ColoredShadows
const string geomMain_PS_Flipbook_fourCorners_horizBillboard
const string fragMainCook_1_matOcclu_Om1
const string vertMain_PS_v_a
const string geomMain_PS_v_c
const string vertMain_v_R_OS
const string vertMain_PS_U_alive_p
const string geomInput_PS_u_c
const string vertMain_PS_v_tC
const string geomMain_PS_v_sS
const string vertMain_PS_U_v_init_p
const string vertMain_PS_U_bornDead
const string fragMainCook_1_matRough_ORMm
const string vertMain_PS_v_doColorOverLT
const string fragInput_u_matEmis
const string vertMain_PS_U_v_rConst
const string vertMain_PS_instanced_position
const string vertInput_u_matrices_all
const string fragMain_1_EN_in_TS
const string vertOutput_v_R_OS
const string vertOutput_PS_tf_initV
const string fragMainCook_1_matMetal_ORMm
const string vertInput_PS_u_al_bernstein_alpha
const string fragFunctionDoColoredShadows
const string geomMain_PS_v_s
const string vertMain_PS_v_tC_flipbook
const string vertInput_u_matrix_vertBillboard
const string vertInput_a_uv1
const string fragInput_v_uv1
const string fragMain_PS_instanced_withoutColor
const string fragMainBlinn_2_LightLoop
const string fragMain_1_matEmis
const string vertMain_PS_instanced_scale
const string fragMainCook_1_matRough_Rm
const string fragInput_PS_instanced_transparency
const string fragMain_0_Intensities
const string vertInput_PS_a_InstPos
const string vertOutput_PS_struct_r
const string fragInput_u_matTexDm
const string fragMain_1_matOccl
const string vertMain_PS_v_t_begin
const string fragInput_PS_v_tC
const string vertMain_skinning
const string vertMain_PS_v_s
const string vertInput_PS_a_r
const string vertOutput_v_P_VS
const string geomMain_PS_v_rad
const string vertMain_PS_v_r
const string vertMain_PS_U_reset_st_counterGap
const string fragMainBlinn_3_FragColorDm
const string fragInput_u_matTexMm
const string fragMain_PS_TF
const string geomMain_PS_v_rotIden
const string fragMainCook_2_LightLoopNmSm
const string fragInput_u_matTexNm
const string geomInput_PS_struct_End
const string fragMain_PS_instanced_v_doColorOverLT
const string vertOutput_PS_instanced_transparency
const string geomMain_PS_Flipbook_fourCorners_vertBillboard
vector< SLLight * > SLVLight
STL vector of light pointers.
static string fragInput_u_lightSm(SLVLight *lights)
void buildPerPixParticleUpdate(SLMaterial *mat)
static bool lightsDoShadowMapping(SLVLight *lights)
Returns true if at least one of the light does shadow mapping.
static void addCodeToShader(SLGLShader *shader, const string &code, const string &name)
Add vertex shader code to the SLGLShader instance.
static void setVariable(std::string &code, const std::string &name, const std::string &value)
Sets a variable in the shader code.
void buildPerPixCook(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
void buildPerPixBlinn(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
static string generatedShaderPath
static string fragFunctionShadowTest(SLVLight *lights)
Adds the core shadow mapping test routine depending on the lights.
static string shaderHeader()
Adds shader header code.
void buildProgramCode(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning)
static void buildProgramNamePS(SLMaterial *mat, string &programName, bool isDrawProg, bool drawInstanced)
static void buildProgramName(SLMaterial *mat, SLVLight *lights, SLbool supportGPUSkinning, string &programName)
Builds unique program name that identifies shader program.
void buildProgramCodePS(SLMaterial *mat, bool isDrawProg, bool drawInstanced=false)
void buildPerPixParticle(SLMaterial *mat)
void buildPerPixParticleInstanced(SLMaterial *mat)
static string fragInput_u_shadowMaps(SLVLight *lights)
void buildPerPixVideoBkgdSm(SLVLight *lights)
Assemble shaders for video on background.
SLVGLShader _shaders
Vector of all shader objects.
static string configPath
Contains the global writable configuration path.
Encapsulation of an OpenGL shader object.
void file(SLstring strFile)
static SLstring removeComments(SLstring src)
SLGLShader::removeComments for C/C++ comments removal from shader code.
Abstract Light class for OpenGL light sources.
virtual SLbool doCascadedShadows() const
void createsShadows(SLbool createsShadows)
void shadowMap(SLShadowMap *shadowMap)
Defines a standard CG material with textures and a shader program.
void ps(SLParticleSystem *ps)
SLstring texturesString()
Returns a unique string that represent all textures used.
void reflectionModel(SLReflectionModel rm)
void skybox(SLSkybox *sb)
SLbool hasTextureTypeWithUVIndex(SLTextureType tt, SLuint texIndex, SLbyte uvIndex)
SLbool hasTextureType(SLTextureType tt)
SLbool usesUVIndex(SLbyte uvIndex)
Returns true if the specified uvIndex is used by one of the textures.
void name(const SLstring &Name)
SLstring _name
name of an object
const SLstring & name() const
Class for standard and cascaded shadow mapping.
void numCascades(int numCascades)
SLbool useCascaded() const
SLGLVDepthBuffer depthBuffers()
void useCubemap(SLbool useCubemap)
bool dirExists(const string &path)
Returns true if a directory exists.
bool makeDir(const string &path)
Creates a directory with given path.