29 layout (location = 0) in vec4 a_position; // Vertex position attribute
30 layout (location = 1) in vec3 a_normal; // Vertex normal attribute)";
32 layout (location = 0) in vec3 a_position; // Particle position attribute)";
34 layout (location = 1) in vec3 a_velocity; // Particle velocity attribute)";
36 layout (location = 2) in float a_startTime; // Particle start time attribute)";
38 layout (location = 3) in vec3 a_initialVelocity;// Particle initial velocity attribute)";
40 layout (location = 4) in float a_rotation; // Particle rotation attribute)";
42 layout (location = 5) in float a_angularVelo; // Particle rotation rate attribute)";
44 layout (location = 6) in uint a_texNum; // Particle rotation attribute)";
46 layout (location = 7) in vec3 a_initialPosition;// Particle initial position attribute)";
48 layout (location = 8) in vec3 a_instancePos; // Particle instance triangle vertex position attribute)";
50 layout (location = 2) in vec2 a_uv0; // Vertex tex.coord. 1 for diffuse color)";
52 layout (location = 3) in vec2 a_uv1; // Vertex tex.coord. 2 for AO)";
54 layout (location = 5) in vec4 a_tangent; // Vertex tangent attribute)";
56 layout (location = 6) in ivec4 a_jointIds; // Vertex joint indices attributes
57 layout (location = 7) in vec4 a_jointWeights; // Vertex joint weights attributes)";
61 uniform mat4 u_mMatrix; // Model matrix (object to world transform)
62 uniform mat4 u_vMatrix; // View matrix (world to camera transform)
63 uniform mat4 u_pMatrix; // Projection matrix (camera to normalize device coords.))";
65 uniform mat4 u_vOmvMatrix; // view or modelview matrix)";
69 uniform mat4 u_jointMatrices[100]; // Joint matrices for skinning
70 uniform bool u_skinningEnabled; // Flag if the shader should perform skinning
75 uniform vec4 u_lightPosVS[NUM_LIGHTS]; // position of light in view space
76 uniform vec3 u_lightSpotDir[NUM_LIGHTS]; // spot direction in view space
77 uniform float u_lightSpotDeg[NUM_LIGHTS]; // spot cutoff angle 1-180 degrees)";
81 #define PI 3.1415926538
82 #define TWOPI 6.2831853076
86 uniform float u_time; // Simulation time
87 uniform float u_difTime; // Simulation delta time after frustum culling
88 uniform float u_tTL; // Time to live of a particle)";
90 uniform float u_tTL; // Time to live of a particle)";
92 uniform vec4 u_al_bernstein; // Bernstein polynomial for alpha over time)";
94 uniform vec4 u_si_bernstein; // Bernstein polynomial for size over time)";
96 uniform float u_colorArr[256 * 3]; // Array of color value (for color over life))";
98 uniform float u_colorArr[256 * 3]; // Array of color value (for color over life))";
100 uniform float u_deltaTime; // Elapsed time between frames)";
102 uniform vec3 u_pGPosition; // Particle Generator position)";
104 uniform float u_accConst; // Particle acceleration constant)";
106 uniform vec3 u_acceleration; // Particle acceleration)";
108 uniform vec3 u_gravity; // Particle gravity)";
110 uniform float u_angularVelo; // Particle angular velocity)";
112 uniform int u_col; // Number of column of flipbook texture)";
114 uniform int u_row; // Number of row of flipbook texture)";
116 uniform int u_condFB; // Condition to update texNum)";
120 out vec3 v_P_VS; // Point of illumination in view space (VS))";
122 out vec3 v_P_WS; // Point of illumination in world space (WS))";
124 out vec3 v_N_VS; // Normal at P_VS in view space (VS))";
126 out vec3 v_R_OS; // Reflection vector in object space (WS))";
128 out vec2 v_uv0; // Texture coordinate 0 output)";
130 out vec2 v_uv1; // Texture coordinate 1 output)";
132 out vec3 v_eyeDirTS; // Vector to the eye in tangent space
133 out vec3 v_lightDirTS[NUM_LIGHTS]; // Vector to the light 0 in tangent space
134 out vec3 v_spotDirTS[NUM_LIGHTS]; // Spot direction in tangent space)";
137 vec3 colorByAge(float age)
139 int cachePos = int(clamp(age, 0.0, 1.0) * 255.0) * 3;
140 vec3 color = vec3(u_colorArr[cachePos], u_colorArr[cachePos + 1], u_colorArr[cachePos + 2]);
145 vec3 colorByAge(float age)
147 int cachePos = int(clamp(age, 0.0, 1.0) * 255.0) * 3;
148 vec3 color = vec3(u_colorArr[cachePos], u_colorArr[cachePos + 1], u_colorArr[cachePos + 2]);
157 float transparency; // Transparency of a particle)";
159 float rotation; // Rotation of a particle)";
161 float size; // Size of a particle )";
163 vec3 color; // Color of a particle )";
165 uint texNum; // Num of texture in flipbook)";
170 out float transparency; // transparency of a particle )";
172 in float transparency; // transparency of a particle )";
175 vec4 color = vec4(colorByAge(v_age/u_tTL), 1.0); // Particle color)";
177 vec4 color = u_color; // Particle color)";
179 color.w *= transparency; // Apply transparency)";
181 uniform mat4 u_pMatrix; // Projection matrix)";
183 uniform mat4 u_vYawPMatrix; // Projection matrix)";
185 uniform vec4 u_color; // Particle color)";
187 uniform float u_scale; // Particle scale
188 uniform float u_radiusW; // Particle width radius)
189 uniform float u_radiusH; // Particle height radius)";
194 out vec3 tf_position; // To transform feedback)";
196 out vec3 tf_velocity; // To transform feedback)";
198 out float tf_startTime; // To transform feedback)";
200 out vec3 tf_initialVelocity; // To transform feedback)";
202 out float tf_rotation; // To transform feedback)";
204 out float tf_angularVelo; // To transform feedback)";
206 flat out uint tf_texNum; // To transform feedback)";
208 out vec3 tf_initialPosition; // To transform feedback)";
212 //-----------------------------------------------------------------------------
217 mat4 mvMatrix = u_vMatrix * u_mMatrix;
218 v_P_VS = vec3(mvMatrix * ${localPosition}); // vertex position in view space)";
220 v_P_WS = vec3(u_mMatrix * ${localPosition}); // vertex position in world space)";
222 mat3 invMvMatrix = mat3(inverse(mvMatrix));
223 mat3 nMatrix = transpose(invMvMatrix);
224 v_N_VS = vec3(nMatrix * ${localNormal}); // vertex normal in view space)";
226 vec3 I = normalize(v_P_VS);
227 vec3 N = normalize(v_N_VS);
228 v_R_OS = invMvMatrix * reflect(I, N); // R = I-2.0*dot(N,I)*N;)";
230 v_uv0 = a_uv0; // pass diffuse color tex.coord. 0 for interpolation)";
232 v_uv1 = a_uv1; // pass diffuse color tex.coord. 1 for interpolation)";
234 vec4 skinnedPosition;
237 if (u_skinningEnabled)
239 // In skinned skeleton animation, every vertex of a mesh is transformed by
240 // max. four joints (bones) of a skeleton identified by indices. The joint
241 // matrix is a weighted sum of four joint matrices and can change per frame
242 // to animate the mesh.
243 mat4 jm = u_jointMatrices[int(a_jointIds.x)] * a_jointWeights.x
244 + u_jointMatrices[int(a_jointIds.y)] * a_jointWeights.y
245 + u_jointMatrices[int(a_jointIds.z)] * a_jointWeights.z
246 + u_jointMatrices[int(a_jointIds.w)] * a_jointWeights.w;
248 skinnedPosition = jm * a_position;
249 skinnedNormal = mat3(jm) * a_normal;
253 skinnedPosition = a_position;
254 skinnedNormal = a_normal;
258 vec4 skinnedPosition;
262 if (u_skinningEnabled)
264 // In skinned skeleton animation, every vertex of a mesh is transformed by
265 // max. four joints (bones) of a skeleton identified by indices. The joint
266 // matrix is a weighted sum of four joint matrices and can change per frame
267 // to animate the mesh.
268 mat4 jm = u_jointMatrices[int(a_jointIds.x)] * a_jointWeights.x
269 + u_jointMatrices[int(a_jointIds.y)] * a_jointWeights.y
270 + u_jointMatrices[int(a_jointIds.z)] * a_jointWeights.z
271 + u_jointMatrices[int(a_jointIds.w)] * a_jointWeights.w;
273 skinnedPosition = jm * a_position;
274 skinnedNormal = mat3(jm) * a_normal;
275 skinnedTangent = vec4(mat3(jm) * a_tangent.xyz, a_tangent.w);
279 skinnedPosition = a_position;
280 skinnedNormal = a_normal;
281 skinnedTangent = a_tangent;
286 // Building the matrix Eye Space -> Tangent Space
287 // See the math behind at: http://www.terathon.com/code/tangent.html
288 vec3 n = normalize(nMatrix * ${localNormal});
289 vec3 t = normalize(nMatrix * ${localTangent}.xyz);
290 vec3 b = cross(n, t) * ${localTangent}.w; // bitangent w. corrected handedness
291 mat3 TBN = mat3(t,b,n);
293 // Transform vector to the eye into tangent space
294 v_eyeDirTS = -v_P_VS; // eye vector in view space
297 for (int i = 0; i < NUM_LIGHTS; ++i)
299 // Transform spot direction into tangent space
300 v_spotDirTS[i] = u_lightSpotDir[i];
301 v_spotDirTS[i] *= TBN;
303 // Transform vector to the light 0 into tangent space
304 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
306 v_lightDirTS[i] *= TBN;
314 vert.transparency = 0.0; // To be discard, because the particle is to be born
316 vert.transparency = 1.0;)";
319 vert.transparency = 0.0; // To be discard, because the particle is to be born
322 vert.transparency = age / u_tTL; // Get by the ratio age:lifetime)";
324 vert.transparency = 1.0 - vert.transparency; // Linear)";
326 vert.transparency = pow(vert.transparency,3.0) * u_al_bernstein.x +
327 pow(vert.transparency,2.0) * u_al_bernstein.y +
328 vert.transparency * u_al_bernstein.z +
329 u_al_bernstein.w; // Get transparency by bezier curve)";
333 vert.rotation = a_rotation;)";
335 vert.size = age / u_tTL;)";
337 vert.size = pow(vert.size,3.0) * u_si_bernstein.x +
338 pow(vert.size,2.0) * u_si_bernstein.y +
339 vert.size * u_si_bernstein.z +
340 u_si_bernstein.w; // Get transparency by bezier curve)";
343 vert.color = colorByAge(age/u_tTL);)";
345 out float v_age; // Age of a particle)";
347 in float v_age; // Age of a particle)";
349 vert.texNum = a_texNum;)";
351 float age = u_time - a_startTime; // Get the age of the particle)";
353 v_texCoord = 0.5 * (a_instancePos.xy + vec2(1.0));)";
357 int actCI = int(mod(float(a_texNum), float(u_col)));
358 float actC = float(actCI);
359 float actR = floor(float(int(a_texNum) - actCI) / float(u_col));
361 vec2 p = 0.5 * (a_instancePos.xy + vec2(1.0));
362 v_texCoord = vec2((actC + p.x)/float(u_col), 1.0 - (actR - p.y)/float(u_row));
366 vec3 position = a_instancePos;
369 float size = age / u_tTL;)";
371 size = pow(size,3.0) * u_si_bernstein.x +
372 pow(size,2.0) * u_si_bernstein.y +
373 size * u_si_bernstein.z +
374 u_si_bernstein.w; // Get transparency by bezier curve)";
376 position = size * position;
380 transparency = 0.0; // To be discard, because the particle is to be born
382 transparency = 1.0;)";
385 transparency = 0.0; // To be discard, because the particle is to be born
388 transparency = age / u_tTL; // Get by the ratio age:lifetime)";
390 transparency = 1.0 - transparency; // Linear)";
392 transparency = pow(transparency,3.0) * u_al_bernstein.x +
393 pow(transparency,2.0) * u_al_bernstein.y +
394 transparency * u_al_bernstein.z +
395 u_al_bernstein.w; // Get transparency by bezier curve)";
397 position = vec3(u_radiusW * position.x, u_radiusH * position.y, position.z);
398 position = u_scale * position;
401 mat2 rot = mat2(cos(a_rotation),-sin(a_rotation),
402 sin(a_rotation), cos(a_rotation)); // Matrix of rotation
403 position = vec3(rot * position.xy, position.z);
407 // Modelview matrix multiplication with (particle position + particle generator position)
408 // Calculate position in view space
409 gl_Position = u_pMatrix * (u_vOmvMatrix * vec4(a_position, 1) + vec4(position, 0.0));
413 //gl_Position = vec4(a_position + a_instancePos, 1);
414 gl_Position = u_pMatrix * u_vYawPMatrix * vec4(a_position + position, 1.0);
420 // Modelview matrix multiplication with (particle position + particle generator position)
421 // Calculate position in view space
422 gl_Position = u_vOmvMatrix * vec4(a_position, 1);
426 gl_Position = vec4(a_position, 1);
431 // pass the vertex w. the fix-function transform
432 gl_Position = u_pMatrix * mvMatrix * ${localPosition};
437 vec4 P = vec4(a_position.xyz, 1.0); // Need to be here for the compilation
438 gl_Position = P; // Need to be here for the compilation)";
440 tf_position = a_position; // Init the output variable)";
442 tf_velocity = a_velocity; // Init the output variable)";
444 tf_startTime = a_startTime; // Init the output variable)";
446 tf_initialVelocity = a_initialVelocity; // Init the output variable)";
448 tf_rotation = a_rotation; // Init the output variable)";
450 tf_angularVelo = a_angularVelo; // Init the output variable)";
452 tf_texNum = a_texNum; // Init the output variable)";
454 tf_initialPosition = a_initialPosition; // Init the output variable)";
456 tf_startTime += u_difTime; // Add time to resume after frustum culling
458 if( u_time >= tf_startTime )
459 { // Check if the particle is born
460 float age = u_time - tf_startTime; // Get the age of the particle
464 // The particle is past its lifetime, recycle.
465 tf_position = u_pGPosition; // Reset position)";
467 // The particle is past its lifetime, recycle.
468 tf_position = a_initialPosition + u_pGPosition; // Reset position)";
470 tf_velocity = a_initialVelocity; // Reset velocity)";
472 tf_startTime = u_time + (age - u_tTL); // Reset start time to actual time with counter gap)";
474 tf_startTime = u_time; // Reset start time to actual time)";
478 // The particle is alive, update.
479 tf_position += tf_velocity * u_deltaTime; // Scale the translation by the delta time)";
481 tf_rotation = mod(tf_rotation + (u_angularVelo*u_deltaTime), TWOPI);)";
483 tf_rotation = mod(tf_rotation + (tf_angularVelo*u_deltaTime), TWOPI);)";
485 tf_velocity += tf_initialVelocity * u_deltaTime * u_accConst; // Amplify the velocity)";
487 tf_velocity += u_deltaTime * u_acceleration; // Amplify the velocity)";
489 tf_velocity += u_deltaTime * u_gravity; // Apply gravity)";
493 tf_texNum++; // Increment to draw next texture (flipbook)
494 tf_texNum = uint(mod(float(tf_texNum), float(u_col * u_row))); // Modulo to not exceed the max and reset
503 layout (points) in; // Primitives that we received from vertex shader
504 layout (triangle_strip, max_vertices = 4) out; // Primitives that we will output and number of vertex that will be output)";
508 float transparency; // Transparency of a particle)";
510 float rotation; // Rotation of a particle)";
512 float size; // Size of a particle )";
514 vec3 color; // Color of a particle )";
516 uint texNum; // Num of texture in flipbook)";
521 uniform mat4 u_pMatrix; // Projection matrix)";
523 uniform mat4 u_vYawPMatrix; // Projection matrix)";
525 uniform float u_scale; // Particle scale
526 uniform float u_radiusW; // Particle width radius)
527 uniform float u_radiusH; // Particle height radius)";
529 uniform vec4 u_color; // Particle color)";
531 uniform int u_col; // Number of column of flipbook texture)";
533 uniform int u_row; // Number of row of flipbook texture)";
536 out vec4 v_particleColor; // The resulting color per vertex)";
538 out vec2 v_texCoord; // Texture coordinate at vertex)";
540 out vec2 v_texCoord; // Texture coordinate at vertex)";
543 float scale = u_scale;)";
545 scale *= vert[0].size;)";
547 float radiusW = u_radiusW * scale;
548 float radiusH = u_radiusH * scale;)";
550 vec4 P = gl_in[0].gl_Position; // Position of the point that we received)";
552 mat2 rot = mat2(cos(vert[0].rotation),-sin(vert[0].rotation),
553 sin(vert[0].rotation), cos(vert[0].rotation)); // Matrix of rotation)";
555 mat2 rot = mat2(1.0, 0.0, 0.0, 1.0); // Matrix of rotation)";
557 vec4 color = u_color; // Particle color)";
559 vec4 color = vec4(vert[0].color, 1.0); // Particle color)";
561 vec4 color = vec4( 0.0, 0.0, 0.0, 1.0); // Particle color)";
563 color.w *= vert[0].transparency; // Apply transparency)";
567 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
568 gl_Position = u_pMatrix * va; // Calculate position in clip space
569 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
570 v_particleColor = color;
574 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
575 gl_Position = u_pMatrix * vd;
576 v_texCoord = vec2(1.0, 0.0);
577 v_particleColor = color;
581 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
582 gl_Position = u_pMatrix * vb;
583 v_texCoord = vec2(0.0, 1.0);
584 v_particleColor = color;
588 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
589 gl_Position = u_pMatrix * vc;
590 v_texCoord = vec2(1.0, 1.0);
591 v_particleColor = color;
596 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
597 gl_Position = u_pMatrix * (u_vYawPMatrix * va); // Calculate position in clip space
598 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
599 v_particleColor = color;
603 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
604 gl_Position = u_pMatrix * (u_vYawPMatrix *vd);
605 v_texCoord = vec2(1.0, 0.0);
606 v_particleColor = color;
610 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
611 gl_Position = u_pMatrix * (u_vYawPMatrix * vb);
612 v_texCoord = vec2(0.0, 1.0);
613 v_particleColor = color;
617 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
618 gl_Position = u_pMatrix * (u_vYawPMatrix * vc);
619 v_texCoord = vec2(1.0, 1.0);
620 v_particleColor = color;
625 vec4 va = vec4(P.xyz, 1); //Position in view space
626 va.xz = va.xz + (rot * vec2(-radiusW, -radiusH));
627 gl_Position = u_pMatrix * u_vOmvMatrix * va; // Calculate position in clip space
628 v_texCoord = vec2(0.0, 0.0); // Texture coordinate
629 v_particleColor = color;
633 vec4 vd = vec4(P.xyz,1);
634 vd.xz += (rot * vec2(radiusW, -radiusH));
635 gl_Position = u_pMatrix * u_vOmvMatrix * vd;
636 v_texCoord = vec2(1.0, 0.0);
637 v_particleColor = color;
641 vec4 vb = vec4(P.xyz,1);
642 vb.xz += (rot * vec2(-radiusW,radiusH));
643 gl_Position = u_pMatrix * u_vOmvMatrix * vb;
644 v_texCoord = vec2(0.0, 1.0);
645 v_particleColor = color;
649 vec4 vc = vec4(P.xyz,1);
650 vc.xz += (rot * vec2(radiusW, radiusH));
651 gl_Position = u_pMatrix * u_vOmvMatrix * vc;
652 v_texCoord = vec2(1.0, 1.0);
653 v_particleColor = color;
656 uint actCI = uint(mod(float(uint(vert[0].texNum), float(u_col)));
657 uint actRI = (vert[0].texNum - actCI) / u_col;
658 float actC = float(actCI);
659 float actR = float(actRI);
662 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
663 gl_Position = u_pMatrix * va; // Calculate position in clip space
664 v_texCoord = vec2(actC/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
665 v_particleColor = color;
669 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
670 gl_Position = u_pMatrix * vd;
671 v_texCoord = vec2((actC+1.0)/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
672 v_particleColor = color;
676 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
677 gl_Position = u_pMatrix * vb;
678 v_texCoord = vec2(actC/u_col, 1.0-(actR/u_row)); // Texture coordinate
679 v_particleColor = color;
683 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
684 gl_Position = u_pMatrix * vc;
685 v_texCoord = vec2((actC+1.0)/u_col, 1.0-(actR/u_row)); // Texture coordinate
686 v_particleColor = color;
689 uint actCI = uint(mod(float(vert[0].texNum), float(u_col)));
690 uint actRI = uint((float(vert[0].texNum) - float(actCI)) / float(u_col));
691 float actC = float(actCI);
692 float actR = float(actRI);
695 vec4 va = vec4(P.xyz, 1); //Position in view space
696 va.xz = va.xz + (rot * vec2(-radiusW, -radiusH));
697 gl_Position = u_pMatrix * u_vOmvMatrix * va; // Calculate position in clip space
698 v_texCoord = vec2(actC/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
699 v_particleColor = color;
703 vec4 vd = vec4(P.xyz,1);
704 vd.xz += (rot * vec2(radiusW, -radiusH));
705 gl_Position = u_pMatrix * u_vOmvMatrix * vd;
706 v_texCoord = vec2((actC+1.0)/u_col, 1.0-((actR+1.0)/u_row)); // Texture coordinate
707 v_particleColor = color;
711 vec4 vb = vec4(P.xyz,1);
712 vb.xz += (rot * vec2(-radiusW,radiusH));
713 gl_Position = u_pMatrix * u_vOmvMatrix * vb;
714 v_texCoord = vec2(actC/u_col, 1.0-(actR/u_row)); // Texture coordinate
715 v_particleColor = color;
719 vec4 vc = vec4(P.xyz,1);
720 vc.xz += (rot * vec2(radiusW, radiusH));
721 gl_Position = u_pMatrix * u_vOmvMatrix * vc;
722 v_texCoord = vec2((actC+1.0)/u_col, 1.0-(actR/u_row)); // Texture coordinate
723 v_particleColor = color;
726 uint actCI = uint(mod(float(vert[0].texNum), float(u_col)));
727 uint actRI = uint((float(vert[0].texNum) - float(actCI)) / float(u_col));
728 float actC = float(actCI);
729 float actR = float(actRI);
732 vec4 va = vec4(P.xy + (rot * vec2(-radiusW, -radiusH)), P.z, 1); //Position in view space
733 gl_Position = u_pMatrix * (u_vYawPMatrix * va); // Calculate position in clip space
734 v_texCoord = vec2(actC/float(u_col), 1.0-((actR+1.0)/float(u_row))); // Texture coordinate
735 v_particleColor = color;
739 vec4 vd = vec4(P.xy + (rot * vec2(radiusW, -radiusH)), P.z,1);
740 gl_Position = u_pMatrix * (u_vYawPMatrix * vd);
741 v_texCoord = vec2((actC+1.0)/float(u_col), 1.0-((actR+1.0)/float(u_row))); // Texture coordinate
742 v_particleColor = color;
746 vec4 vb = vec4(P.xy + (rot * vec2(-radiusW,radiusH)) , P.z,1);
747 gl_Position = u_pMatrix * (u_vYawPMatrix * vb);
748 v_texCoord = vec2(actC/float(u_col), 1.0-(actR/float(u_row))); // Texture coordinate
749 v_particleColor = color;
753 vec4 vc = vec4(P.xy + (rot *vec2(radiusW, radiusH)), P.z,1);
754 gl_Position =u_pMatrix * (u_vYawPMatrix * vc);
755 v_texCoord = vec2((actC+1.0)/float(u_col), 1.0-(actR/float(u_row))); // Texture coordinate
756 v_particleColor = color;
761 EndPrimitive(); // Send primitives to fragment shader
765 in vec3 v_P_VS; // Interpol. point of illumination in view space (VS))";
767 in vec3 v_P_WS; // Interpol. point of illumination in world space (WS))";
769 in vec3 v_N_VS; // Interpol. normal at v_P_VS in view space)";
771 in vec3 v_R_OS; // Interpol. reflect in object space)";
773 in vec2 v_uv0; // Texture coordinate varying for uv 0)";
775 in vec2 v_uv1; // Texture coordinate varying for uv 1)";
777 in vec3 v_eyeDirTS; // Vector to the eye in tangent space
778 in vec3 v_lightDirTS[NUM_LIGHTS]; // Vector to light 0 in tangent space
779 in vec3 v_spotDirTS[NUM_LIGHTS]; // Spot direction in tangent space)";
782 in vec4 v_particleColor; // interpolated color from the geometry shader)";
784 in vec2 v_texCoord; // interpolated texture coordinate)";
787 uniform float u_oneOverGamma; // 1.0f / Gamma correction value)";
789 uniform bool u_doWireFrame; // Boolean for wireFrame)";
792 o_fragColor = vec4(0,0,0,0); // Need to be here for the compilation
797 // Just set the interpolated color from the vertex shader
798 o_fragColor = v_particleColor;
800 // componentwise multiply w. texture color
802 o_fragColor *= texture(u_matTextureDiffuse0, v_texCoord);
804 if(o_fragColor.a < 0.001)
808 // componentwise multiply w. texture color
810 o_fragColor = texture(u_matTextureDiffuse0, v_texCoord);
812 o_fragColor = vec4(0,0,0,1.0);
814 o_fragColor.a *= v_particleColor.a;
816 if(o_fragColor.a < 0.001)
820 // componentwise multiply w. texture color
822 o_fragColor = texture(u_matTextureDiffuse0, v_texCoord);
824 o_fragColor = vec4(0,0,0,1.0);
826 o_fragColor.a *= transparency;
828 if(o_fragColor.a < 0.001)
832 // Just set the interpolated color from the vertex shader
834 // componentwise multiply w. texture color
836 o_fragColor *= texture(u_matTextureDiffuse0, v_texCoord);
838 if(o_fragColor.a < 0.001)
842 //Same color for each wireframe
844 o_fragColor = vec4(0,0,0,1.0);
846 o_fragColor.rgb = pow(o_fragColor.rgb, vec3(u_oneOverGamma));
851 uniform bool u_lightIsOn[NUM_LIGHTS]; // flag if light is on
852 uniform vec4 u_lightPosVS[NUM_LIGHTS]; // position of light in view space
853 uniform vec4 u_lightAmbi[NUM_LIGHTS]; // ambient light intensity (Ia)
854 uniform vec4 u_lightDiff[NUM_LIGHTS]; // diffuse light intensity (Id)
855 uniform vec4 u_lightSpec[NUM_LIGHTS]; // specular light intensity (Is)
856 uniform vec3 u_lightSpotDir[NUM_LIGHTS]; // spot direction in view space
857 uniform float u_lightSpotDeg[NUM_LIGHTS]; // spot cutoff angle 1-180 degrees
858 uniform float u_lightSpotCos[NUM_LIGHTS]; // cosine of spot cutoff angle
859 uniform float u_lightSpotExp[NUM_LIGHTS]; // spot exponent
860 uniform vec3 u_lightAtt[NUM_LIGHTS]; // attenuation (const,linear,quadr.)
861 uniform bool u_lightDoAtt[NUM_LIGHTS]; // flag if att. must be calc.
862 uniform vec4 u_globalAmbi; // Global ambient scene color
863 uniform float u_oneOverGamma; // 1.0f / Gamma correction value
866 uniform vec4 u_matAmbi; // ambient color reflection coefficient (ka)
867 uniform vec4 u_matDiff; // diffuse color reflection coefficient (kd)
868 uniform vec4 u_matSpec; // specular color reflection coefficient (ks)
869 uniform vec4 u_matEmis; // emissive color for self-shining materials
870 uniform float u_matShin; // shininess exponent
873 uniform vec4 u_matAmbi; // ambient color reflection coefficient (ka))";
875 uniform vec4 u_matDiff; // diffuse color reflection coefficient (kd))";
877 uniform vec4 u_matEmis; // emissive color (ke))";
879 uniform float u_matRough; // roughness factor (0-1))";
881 uniform float u_matMetal; // metalness factor (0-1)";
884 uniform sampler2D u_matTextureDiffuse0; // Diffuse color map)";
886 uniform sampler2D u_matTextureNormal0; // Normal bump map)";
888 uniform sampler2D u_matTextureEmissive0; // PBR material emissive texture)";
890 uniform sampler2D u_matTextureOcclusion0; // Ambient occlusion map)";
892 uniform sampler2D u_matTextureRoughness0; // PBR material roughness texture)";
894 uniform sampler2D u_matTextureMetallic0; // PBR material metallic texture)";
896 uniform sampler2D u_matTextureRoughMetal0; // PBR material roughness-metallic texture)";
898 uniform sampler2D u_matTextureOccluRoughMetal0; // PBR material occlusion-roughness-metalic texture)";
901 uniform bool u_matGetsShadows; // flag if material receives shadows)";
903 uniform samplerCube u_skyIrradianceCubemap; // PBR skybox irradiance light
904 uniform samplerCube u_skyRoughnessCubemap; // PBR skybox cubemap for rough reflections
905 uniform sampler2D u_skyBrdfLutTexture; // PBR lighting lookup table for BRDF
906 uniform float u_skyExposure; // PBR skybox exposure)";
910 uniform int u_camProjType; // type of stereo
911 uniform int u_camStereoEye; // -1=left, 0=center, 1=right
912 uniform mat3 u_camStereoColors; // color filter matrix
913 uniform bool u_camFogIsOn; // flag if fog is on
914 uniform int u_camFogMode; // 0=LINEAR, 1=EXP, 2=EXP2
915 uniform float u_camFogDensity; // fog density value
916 uniform float u_camFogStart; // fog start distance
917 uniform float u_camFogEnd; // fog end distance
918 uniform vec4 u_camFogColor; // fog color (usually the background)
919 uniform float u_camClipNear; // camera near plane
920 uniform float u_camClipFar; // camera far plane
921 uniform float u_camBkgdWidth; // camera background width
922 uniform float u_camBkgdHeight; // camera background height
923 uniform float u_camBkgdLeft; // camera background left
924 uniform float u_camBkgdBottom; // camera background bottom)";
928 out vec4 o_fragColor; // output fragment color)";
931 //-----------------------------------------------------------------------------
932 void directLightBlinnPhong(in int i, // Light number between 0 and NUM_LIGHTS
933 in vec3 N, // Normalized normal at v_P
934 in vec3 E, // Normalized direction at v_P to the eye
935 in vec3 S, // Normalized light spot direction
936 in float shadow, // shadow factor
937 inout vec4 Ia, // Ambient light intensity
938 inout vec4 Id, // Diffuse light intensity
939 inout vec4 Is) // Specular light intensity
941 // Calculate diffuse & specular factors
942 float diffFactor = max(dot(N, S), 0.0);
943 float specFactor = 0.0;
947 vec3 H = normalize(S + E);// Half vector H between S and E
948 specFactor = pow(max(dot(N, H), 0.0), u_matShin);
951 // accumulate directional light intensities w/o attenuation
952 Ia += u_lightAmbi[i];
953 Id += u_lightDiff[i] * diffFactor * (1.0 - shadow);
954 Is += u_lightSpec[i] * specFactor * (1.0 - shadow);
956 //-----------------------------------------------------------------------------
957 void pointLightBlinnPhong( in int i,
967 // Calculate attenuation over distance & normalize L
973 att_dist.z = dot(L, L);// = distance * distance
974 att_dist.y = sqrt(att_dist.z);// = distance
975 att = min(1.0 / dot(att_dist, u_lightAtt[i]), 1.0);
976 L /= att_dist.y;// = normalize(L)
981 // Calculate diffuse & specular factors
982 vec3 H = normalize(E + L); // Blinn's half vector is faster than Phongs reflected vector
983 float diffFactor = max(dot(N, L), 0.0); // Lambertian downscale factor for diffuse reflection
984 float specFactor = 0.0;
985 if (diffFactor!=0.0) // specular reflection is only possible if surface is lit from front
986 specFactor = pow(max(dot(N, H), 0.0), u_matShin); // specular shininess
988 // Calculate spot attenuation
989 float spotAtt = 1.0;// Spot attenuation
990 if (u_lightSpotDeg[i] < 180.0)
992 float spotDot;// Cosine of angle between L and spotdir
993 spotDot = dot(-L, S);
994 if (spotDot < u_lightSpotCos[i]) // if outside spot cone
997 spotAtt = max(pow(spotDot, u_lightSpotExp[i]), 0.0);
1000 // Accumulate light intensities
1001 Ia += att * u_lightAmbi[i];
1002 Id += att * spotAtt * u_lightDiff[i] * diffFactor * (1.0 - shadow);
1003 Is += att * spotAtt * u_lightSpec[i] * specFactor * (1.0 - shadow);
1007 //-----------------------------------------------------------------------------
1008 vec3 fresnelSchlick(float cosTheta, vec3 F0)
1010 return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
1012 // ----------------------------------------------------------------------------
1013 vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
1015 return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
1017 //-----------------------------------------------------------------------------
1018 float distributionGGX(vec3 N, vec3 H, float roughness)
1020 float PI = 3.14159265;
1021 float a = roughness*roughness;
1023 float NdotH = max(dot(N, H), 0.0);
1024 float NdotH2 = NdotH*NdotH;
1027 float denom = (NdotH2 * (a2 - 1.0) + 1.0);
1028 denom = PI * denom * denom;
1032 //-----------------------------------------------------------------------------
1033 float geometrySchlickGGX(float NdotV, float roughness)
1035 float r = (roughness + 1.0);
1036 float k = (r*r) / 8.0;
1039 float denom = NdotV * (1.0 - k) + k;
1043 //-----------------------------------------------------------------------------
1044 float geometrySmith(vec3 N, vec3 E, vec3 L, float roughness)
1046 float NdotV = max(dot(N, E), 0.0);
1047 float NdotL = max(dot(N, L), 0.0);
1048 float ggx2 = geometrySchlickGGX(NdotV, roughness);
1049 float ggx1 = geometrySchlickGGX(NdotL, roughness);
1052 //-----------------------------------------------------------------------------
1053 void directLightCookTorrance(in int i, // Light index
1054 in vec3 N, // Normalized normal at v_P_VS
1055 in vec3 E, // Normalized vector from v_P to the eye
1056 in vec3 S, // Normalized light spot direction
1057 in vec3 F0, // Fresnel reflection at 90 deg. (0 to N)
1058 in vec3 matDiff, // diffuse material reflection
1059 in float matMetal, // diffuse material reflection
1060 in float matRough, // diffuse material reflection
1061 in float shadow, // shadow factor (0.0 - 1.0)
1062 inout vec3 Lo) // reflected intensity
1064 float PI = 3.14159265;
1065 vec3 H = normalize(E + S); // Normalized halfvector between eye and light vector
1067 vec3 radiance = u_lightDiff[i].rgb; // Per light radiance without attenuation
1069 // cook-torrance brdf
1070 float NDF = distributionGGX(N, H, matRough);
1071 float G = geometrySmith(N, E, S, matRough);
1072 vec3 F = fresnelSchlick(max(dot(H, E), 0.0), F0);
1075 vec3 kD = vec3(1.0) - kS;
1076 kD *= 1.0 - matMetal;
1078 vec3 nominator = NDF * G * F;
1079 float denominator = 4.0 * max(dot(N, E), 0.0) * max(dot(N, S), 0.0) + 0.001;
1080 vec3 specular = nominator / denominator;
1082 // add to outgoing radiance Lo
1083 float NdotL = max(dot(N, S), 0.0);
1085 Lo += (kD*matDiff.rgb/PI + specular) * radiance * NdotL * (1.0 - shadow);
1087 //-----------------------------------------------------------------------------
1088 void pointLightCookTorrance(in int i, // Light index
1089 in vec3 N, // Normalized normal at v_P_VS
1090 in vec3 E, // Normalized vector from v_P to the eye
1091 in vec3 L, // Vector from v_P to the light
1092 in vec3 S, // Normalized light spot direction
1093 in vec3 F0, // Fresnel reflection at 90 deg. (0 to N)
1094 in vec3 matDiff, // diffuse material reflection
1095 in float matMetal, // diffuse material reflection
1096 in float matRough, // diffuse material reflection
1097 in float shadow, // shadow factor (0.0 - 1.0)
1098 inout vec3 Lo) // reflected intensity
1100 float PI = 3.14159265;
1101 float distance = length(L); // distance to light
1102 L /= distance; // normalize light vector
1103 float att = 1.0 / (distance*distance); // quadratic light attenuation
1105 // Calculate spot attenuation
1106 if (u_lightSpotDeg[i] < 180.0)
1108 float spotAtt; // Spot attenuation
1109 float spotDot; // Cosine of angle between L and spotdir
1110 spotDot = dot(-L, S);
1111 if (spotDot < u_lightSpotCos[i]) spotAtt = 0.0;
1112 else spotAtt = max(pow(spotDot, u_lightSpotExp[i]), 0.0);
1116 vec3 radiance = u_lightDiff[i].rgb * att; // per light radiance
1118 // cook-torrance brdf
1119 vec3 H = normalize(E + L); // Normalized halfvector between eye and light vector
1120 float NDF = distributionGGX(N, H, matRough);
1121 float G = geometrySmith(N, E, L, matRough);
1122 vec3 F = fresnelSchlick(max(dot(H, E), 0.0), F0);
1125 vec3 kD = vec3(1.0) - kS;
1126 kD *= 1.0 - matMetal;
1128 vec3 nominator = NDF * G * F;
1129 float denominator = 4.0 * max(dot(N, E), 0.0) * max(dot(N, L), 0.0) + 0.001;
1130 vec3 specular = nominator / denominator;
1132 // add to outgoing radiance Lo
1133 float NdotL = max(dot(N, L), 0.0);
1135 Lo += (kD*matDiff.rgb/PI + specular) * radiance * NdotL * (1.0 - shadow);
1139 //-----------------------------------------------------------------------------
1140 void doStereoSeparation()
1142 // See SLProjType in SLEnum.h
1143 if (u_camProjType > 8) // stereoColors
1145 // Apply color filter but keep alpha
1146 o_fragColor.rgb = u_camStereoColors * o_fragColor.rgb;
1148 else if (u_camProjType == 6) // stereoLineByLine
1150 if (mod(floor(gl_FragCoord.y), 2.0) < 0.5)// even
1152 if (u_camStereoEye ==-1)
1156 if (u_camStereoEye == 1)
1160 else if (u_camProjType == 7) // stereoColByCol
1162 if (mod(floor(gl_FragCoord.x), 2.0) < 0.5)// even
1164 if (u_camStereoEye ==-1)
1168 if (u_camStereoEye == 1)
1172 else if (u_camProjType == 8) // stereoCheckerBoard
1174 bool h = (mod(floor(gl_FragCoord.x), 2.0) < 0.5);
1175 bool v = (mod(floor(gl_FragCoord.y), 2.0) < 0.5);
1176 if (h==v)// both even or odd
1178 if (u_camStereoEye ==-1)
1182 if (u_camStereoEye == 1)
1189 //-----------------------------------------------------------------------------
1190 vec4 fogBlend(vec3 P_VS, vec4 inColor)
1192 float factor = 0.0f;
1193 float distance = length(P_VS);
1195 switch (u_camFogMode)
1198 factor = (u_camFogEnd - distance) / (u_camFogEnd - u_camFogStart);
1201 factor = exp(-u_camFogDensity * distance);
1204 factor = exp(-u_camFogDensity * distance * u_camFogDensity * distance);
1208 vec4 outColor = factor * inColor + (1.0 - factor) * u_camFogColor;
1209 outColor = clamp(outColor, 0.0, 1.0);
1214 //-----------------------------------------------------------------------------
1215 void doColoredShadows(in vec3 N)
1217 const vec3 SHADOW_COLOR[6] = vec3[6](vec3(1.0, 0.0, 0.0),
1218 vec3(0.0, 1.0, 0.0),
1219 vec3(0.0, 0.0, 1.0),
1220 vec3(1.0, 1.0, 0.0),
1221 vec3(0.0, 1.0, 1.0),
1222 vec3(1.0, 0.0, 1.0));
1224 for (int i = 0; i < NUM_LIGHTS; ++i)
1228 if (u_lightPosVS[i].w == 0.0)
1230 // We use the spot light direction as the light direction vector
1231 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1233 // Test if the current fragment is in shadow
1234 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1235 if (u_lightNumCascades[i] > 0)
1237 int casIndex = getCascadesDepthIndex(i, u_lightNumCascades[i]);
1238 o_fragColor.rgb += shadow * SHADOW_COLOR[casIndex];
1240 o_fragColor.rgb += shadow * SHADOW_COLOR[0];
1244 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1246 // Test if the current fragment is in shadow
1247 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1248 o_fragColor.rgb += shadow * SHADOW_COLOR[0];
1255 vec4 Ia = vec4(0.0); // Accumulated ambient light intensity at v_P_VS
1256 vec4 Id = vec4(0.0); // Accumulated diffuse light intensity at v_P_VS
1257 vec4 Is = vec4(0.0); // Accumulated specular light intensity at v_P_VS
1261 vec3 E = normalize(-v_P_VS); // Interpolated vector from p to the eye
1262 vec3 N = normalize(v_N_VS); // A input normal has not anymore unit length
1265 vec3 E = normalize(v_eyeDirTS); // normalized interpolated eye direction
1267 // Get normal from normal map, move from [0,1] to [-1, 1] range & normalize
1268 vec3 N = normalize(texture(u_matTextureNormal0, v_uv0).rgb * 2.0 - 1.0);
1271 vec4 matEmis = u_matEmis;)";
1273 vec4 matEmis = texture(u_matTextureEmissive0, v_uv0);)";
1275 float matOccl = 1.0;)";
1277 float matOccl = texture(u_matTextureOcclusion0, v_uv0).r;)";
1279 float matOccl = texture(u_matTextureOcclusion0, v_uv1).r;)";
1283 // Get the reflection from all lights into Ia, Id & Is
1284 for (int i = 0; i < NUM_LIGHTS; ++i)
1288 if (u_lightPosVS[i].w == 0.0)
1290 // We use the spot light direction as the light direction vector
1291 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1292 directLightBlinnPhong(i, N, E, S, 0.0, Ia, Id, Is);
1296 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1297 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1298 pointLightBlinnPhong(i, N, E, S, L, 0.0, Ia, Id, Is);
1305 // Get the reflection from all lights into Ia, Id & Is
1306 for (int i = 0; i < NUM_LIGHTS; ++i)
1310 if (u_lightPosVS[i].w == 0.0)
1312 // We use the spot light direction as the light direction vector
1313 vec3 S = normalize(-v_spotDirTS[i]);
1314 directLightBlinnPhong(i, N, E, S, 0.0, Ia, Id, Is);
1318 vec3 S = normalize(v_spotDirTS[i]); // normalized spot direction in TS
1319 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1320 pointLightBlinnPhong(i, N, E, S, L, 0.0, Ia, Id, Is);
1327 // Get the reflection from all lights into Ia, Id & Is
1328 for (int i = 0; i < NUM_LIGHTS; ++i)
1332 if (u_lightPosVS[i].w == 0.0)
1334 // We use the spot light direction as the light direction vector
1335 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1337 // Test if the current fragment is in shadow
1338 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1339 directLightBlinnPhong(i, N, E, S, shadow, Ia, Id, Is);
1343 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1344 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1346 // Test if the current fragment is in shadow
1347 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1348 pointLightBlinnPhong(i, N, E, S, L, shadow, Ia, Id, Is);
1355 // Get the reflection from all lights into Ia, Id & Is
1356 for (int i = 0; i < NUM_LIGHTS; ++i)
1360 if (u_lightPosVS[i].w == 0.0)
1362 // We use the spot light direction as the light direction vector
1363 vec3 S = normalize(-v_spotDirTS[i]);
1365 // Test if the current fragment is in shadow
1366 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1367 directLightBlinnPhong(i, N, E, S, shadow, Ia, Id, Is);
1371 vec3 S = normalize(v_spotDirTS[i]); // normalized spot direction in TS
1372 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1374 // Test if the current fragment is in shadow
1375 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1376 pointLightBlinnPhong(i, N, E, S, L, shadow, Ia, Id, Is);
1382 // Sum up all the reflected color components
1383 o_fragColor = u_matEmis +
1385 Ia * u_matAmbi * matOccl +
1389 // For correct alpha blending overwrite alpha component
1390 o_fragColor.a = u_matDiff.a;
1393 // Sum up all the reflected color components
1394 o_fragColor = u_matEmis +
1396 Ia * u_matAmbi * matOccl +
1399 // Componentwise multiply w. texture color
1400 o_fragColor *= texture(u_matTextureDiffuse0, v_uv0);
1402 // add finally the specular RGB-part
1403 vec4 specColor = Is * u_matSpec;
1404 o_fragColor.rgb += specColor.rgb;
1408 // Colorize cascaded shadows for debugging purpose
1409 if (u_lightsDoColoredShadows)
1410 doColoredShadows(N);
1414 // Apply fog by blending over distance
1416 o_fragColor = fogBlend(v_P_VS, o_fragColor);
1418 // Apply gamma correction
1419 o_fragColor.rgb = pow(o_fragColor.rgb, vec3(u_oneOverGamma));
1421 // Apply stereo eye separation
1422 if (u_camProjType > 1)
1423 doStereoSeparation();
1428 vec4 matDiff = u_matDiff;)";
1430 vec4 matDiff = pow(texture(u_matTextureDiffuse0, v_uv0), vec4(2.2));)";
1432 vec4 matEmis = u_matEmis;)";
1434 vec4 matEmis = pow(texture(u_matTextureEmissive0, v_uv0), vec4(2.2));)";
1436 float matRough = u_matRough;)";
1438 float matRough = texture(u_matTextureRoughness0, v_uv0).r;)";
1440 float matRough = texture(u_matTextureRoughMetal0, v_uv0).g;)";
1442 float matRough = texture(u_matTextureOccluRoughMetal0, v_uv0).g;)";
1444 float matMetal = u_matMetal;)";
1446 float matMetal = texture(u_matTextureMetallic0, v_uv0).r;)";
1448 float matMetal = texture(u_matTextureRoughMetal0, v_uv0).b;)";
1450 float matMetal = texture(u_matTextureOccluRoughMetal0, v_uv0).b;)";
1452 float matOccl = 1.0;)";
1454 float matOccl = texture(u_matTextureOcclusion0, v_uv0).r;)";
1456 float matOccl = texture(u_matTextureOcclusion0, v_uv1).r;)";
1458 float matOccl = texture(u_matTextureOccluRoughMetal0, v_uv0).r;)";
1461 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1462 F0 = mix(F0, matDiff.rgb, matMetal);
1464 // Get the reflection from all lights into Lo
1465 vec3 Lo = vec3(0.0);
1466 for (int i = 0; i < NUM_LIGHTS; ++i)
1470 if (u_lightPosVS[i].w == 0.0)
1472 // We use the spot light direction as the light direction vector
1473 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1474 directLightCookTorrance(i, N, E, S, F0,
1483 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
1484 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1485 pointLightCookTorrance( i, N, E, L, S, F0,
1497 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1498 F0 = mix(F0, matDiff.rgb, matMetal);
1500 // Get the reflection from all lights into Lo
1501 vec3 Lo = vec3(0.0);
1502 for (int i = 0; i < NUM_LIGHTS; ++i)
1506 if (u_lightPosVS[i].w == 0.0)
1508 // We use the spot light direction as the light direction vector
1509 vec3 S = normalize(-v_spotDirTS[i]);
1510 directLightCookTorrance(i, N, E, S, F0,
1519 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1520 vec3 S = normalize(-v_spotDirTS[i]);
1521 pointLightCookTorrance( i, N, E, L, S, F0,
1533 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1534 F0 = mix(F0, matDiff.rgb, matMetal);
1536 // Get the reflection from all lights into Lo
1537 vec3 Lo = vec3(0.0);
1538 for (int i = 0; i < NUM_LIGHTS; ++i)
1542 if (u_lightPosVS[i].w == 0.0)
1544 // We use the spot light direction as the light direction vector
1545 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1547 // Test if the current fragment is in shadow
1548 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1549 directLightCookTorrance(i, N, E, S, F0,
1558 vec3 L = u_lightPosVS[i].xyz - v_P_VS;
1559 vec3 S = u_lightSpotDir[i]; // normalized spot direction in VS
1561 // Test if the current fragment is in shadow
1562 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1563 pointLightCookTorrance( i, N, E, L, S, F0,
1575 vec3 F0 = vec3(0.04); // Init Fresnel reflection at 90 deg. (0 to N)
1576 F0 = mix(F0, matDiff.rgb, matMetal);
1578 // Get the reflection from all lights into Lo
1579 vec3 Lo = vec3(0.0);
1580 for (int i = 0; i < NUM_LIGHTS; ++i)
1584 if (u_lightPosVS[i].w == 0.0)
1586 // We use the spot light direction as the light direction vector
1587 vec3 S = normalize(-v_spotDirTS[i]);
1589 // Test if the current fragment is in shadow
1590 float shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1591 directLightCookTorrance(i, N, E, S, F0,
1600 vec3 L = v_lightDirTS[i]; // Vector from v_P to light in TS
1601 vec3 S = normalize(-v_spotDirTS[i]);
1603 // Test if the current fragment is in shadow
1604 float shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1605 pointLightCookTorrance( i, N, E, L, S, F0,
1616 // ambient lighting (note that the next IBL tutorial will replace
1617 // this ambient lighting with environment lighting).
1618 vec3 ambient = vec3(0.03) * matDiff.rgb * matOccl;
1620 vec3 color = ambient + matEmis.rgb + Lo;
1623 color = color / (color + vec3(1.0));
1624 o_fragColor = vec4(color, 1.0);
1626 // For correct alpha blending overwrite alpha component
1627 o_fragColor.a = matDiff.a;
1630 // Build diffuse reflection from environment light map
1631 vec3 F = fresnelSchlickRoughness(max(dot(N, E), 0.0), F0, matRough);
1634 kD *= 1.0 - matMetal;
1635 vec3 irradiance = texture(u_skyIrradianceCubemap, N).rgb;
1636 vec3 diffuse = kD * irradiance * matDiff.rgb;
1638 // 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.
1639 const float MAX_REFLECTION_LOD = 4.0;
1640 vec3 prefilteredColor = textureLod(u_skyRoughnessCubemap, v_R_OS, matRough * MAX_REFLECTION_LOD).rgb;
1641 vec2 brdf = texture(u_skyBrdfLutTexture, vec2(max(dot(N, E), 0.0), matRough)).rg;
1642 vec3 specular = prefilteredColor * (F * brdf.x + brdf.y);
1643 vec3 ambient = (diffuse + specular) * matOccl;
1645 vec3 color = ambient + matEmis.rgb + Lo;
1647 // Exposure tone mapping
1648 vec3 mapped = vec3(1.0) - exp(-color * u_skyExposure);
1649 o_fragColor = vec4(mapped, 1.0);
1651 // For correct alpha blending overwrite alpha component
1652 o_fragColor.a = matDiff.a;
1656 float x = (gl_FragCoord.x - u_camBkgdLeft) / u_camBkgdWidth;
1657 float y = (gl_FragCoord.y - u_camBkgdBottom) / u_camBkgdHeight;
1659 if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f)
1660 o_fragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
1662 o_fragColor = texture(u_matTextureDiffuse0, vec2(x, y));
1664 vec3 N = normalize(v_N_VS); // A input normal has not anymore unit length
1667 // Colorize cascaded shadows for debugging purpose
1668 if (u_lightsDoColoredShadows)
1669 doColoredShadows(N);
1672 for (int i = 0; i < NUM_LIGHTS; ++i)
1676 if (u_lightPosVS[i].w == 0.0)
1678 // We use the spot light direction as the light direction vector
1679 vec3 S = normalize(-u_lightSpotDir[i].xyz);
1681 // Test if the current fragment is in shadow
1682 shadow = u_matGetsShadows ? shadowTest(i, N, S) : 0.0;
1686 vec3 L = u_lightPosVS[i].xyz - v_P_VS; // Vector from v_P to light in VS
1688 // Test if the current fragment is in shadow
1689 shadow = u_matGetsShadows ? shadowTest(i, N, L) : 0.0;
1691 o_fragColor = o_fragColor * min(1.0 - shadow + u_matAmbi.r, 1.0);
1725 SLbool supportGPUSkinning,
1726 string& programName)
1728 assert(mat &&
"No material pointer passed!");
1729 assert(lights && !lights->empty() &&
"No lights passed!");
1731 programName =
"gen";
1734 programName +=
"VideoBkgdDm";
1736 programName +=
"Blinn";
1738 programName +=
"Cook";
1740 programName +=
"Custom";
1746 for (
auto light : *lights)
1748 if (light->positionWS().w == 0.0f)
1750 if (light->doCascadedShadows())
1751 programName +=
"C" + std::to_string(light->shadowMap()->numCascades());
1755 else if (light->spotCutOffDEG() < 180.0f)
1759 if (light->createsShadows())
1763 if (supportGPUSkinning)
1764 programName +=
"-S";
1789 string& programName,
1793 assert(mat &&
"No material pointer passed!");
1794 programName =
"gen";
1797 programName +=
"Particle";
1799 programName +=
"Custom";
1804 programName +=
"-Draw";
1807 programName +=
"-Inst";
1810 GLint billboardType = mat->
ps()->billboardType();
1811 bool AlOvLi = mat->
ps()->doAlphaOverLT();
1812 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
1813 bool SiOvLi = mat->
ps()->doSizeOverLT();
1814 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
1815 bool Co = mat->
ps()->doColor();
1816 bool CoOvLi = mat->
ps()->doColorOverLT();
1817 bool FlBoTex = mat->
ps()->doFlipBookTexture();
1818 bool WS = mat->
ps()->doWorldSpace();
1819 bool rot = mat->
ps()->doRotation();
1820 programName +=
"-B" + std::to_string(billboardType);
1821 if (rot) programName +=
"-RT";
1822 if (AlOvLi) programName +=
"-AL";
1823 if (AlOvLi && AlOvLiCu) programName +=
"cu";
1824 if (SiOvLi) programName +=
"-SL";
1825 if (SiOvLi && SiOvLiCu) programName +=
"cu";
1826 if (Co) programName +=
"-CO";
1827 if (Co && CoOvLi) programName +=
"cl";
1828 if (FlBoTex) programName +=
"-FB";
1829 if (WS) programName +=
"-WS";
1833 bool counterGap = mat->
ps()->doCounterGap();
1834 bool acc = mat->
ps()->doAcc();
1835 bool accDiffDir = mat->
ps()->doAccDiffDir();
1836 bool gravity = mat->
ps()->doGravity();
1837 bool FlBoTex = mat->
ps()->doFlipBookTexture();
1838 bool rot = mat->
ps()->doRotation();
1839 bool rotRange = mat->
ps()->doRotRange();
1840 bool shape = mat->
ps()->doShape();
1841 programName +=
"-Update";
1842 if (counterGap) programName +=
"-CG";
1843 if (rot) programName +=
"-RT";
1844 if (rot) programName += rotRange ?
"ra" :
"co";
1847 programName +=
"-AC";
1848 programName += accDiffDir ?
"di" :
"co";
1850 if (gravity) programName +=
"-GR";
1851 if (FlBoTex) programName +=
"-FB";
1852 if (shape) programName +=
"-SH";
1864 SLbool supportGPUSkinning)
1866 assert(mat &&
"No material pointer passed!");
1867 assert(!lights->empty() &&
"No lights passed!");
1878 bool env = mat->
skybox() !=
nullptr;
1896 SL_EXIT_MSG(
"SLGLProgramGenerated::buildProgramCode: Unknown program for RM_Custom.");
1899 SL_EXIT_MSG(
"SLGLProgramGenerated::buildProgramCode: Unknown Lighting Model.");
1912 if (mat->
name() ==
"IBLMat")
1914 std::cout <<
"build program code for IBLMat" << std::endl;
1916 assert(mat &&
"No material pointer passed!");
1936 SLbool supportGPUSkinning)
1938 assert(mat && lights);
1958 bool sky = mat->
skybox() !=
nullptr;
1996 setVariable(vertCode,
"localPosition", supportGPUSkinning ?
"skinnedPosition" :
"a_position");
1997 setVariable(vertCode,
"localNormal", supportGPUSkinning ?
"skinnedNormal" :
"a_normal");
1998 if (Nm)
setVariable(vertCode,
"localTangent", supportGPUSkinning ?
"skinnedTangent" :
"a_tangent");
2070 SLbool supportGPUSkinning)
2072 assert(mat && lights);
2122 setVariable(vertCode,
"localPosition", supportGPUSkinning ?
"skinnedPosition" :
"a_position");
2123 setVariable(vertCode,
"localNormal", supportGPUSkinning ?
"skinnedNormal" :
"a_normal");
2124 if (Nm)
setVariable(vertCode,
"localTangent", supportGPUSkinning ?
"skinnedTangent" :
"a_tangent");
2189 GLint billboardType = mat->
ps()->billboardType();
2190 bool rot = mat->
ps()->doRotation();
2191 bool AlOvLi = mat->
ps()->doAlphaOverLT();
2192 bool Co = mat->
ps()->doColor();
2193 bool CoOvLi = mat->
ps()->doColorOverLT();
2194 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
2195 bool SiOvLi = mat->
ps()->doSizeOverLT();
2196 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
2197 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2324 GLint billboardType = mat->
ps()->billboardType();
2325 bool rot = mat->
ps()->doRotation();
2326 bool AlOvLi = mat->
ps()->doAlphaOverLT();
2327 bool Co = mat->
ps()->doColor();
2328 bool CoOvLi = mat->
ps()->doColorOverLT();
2329 bool AlOvLiCu = mat->
ps()->doAlphaOverLTCurve();
2330 bool SiOvLi = mat->
ps()->doSizeOverLT();
2331 bool SiOvLiCu = mat->
ps()->doSizeOverLTCurve();
2332 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2475 bool counterGap = mat->
ps()->doCounterGap();
2476 bool acc = mat->
ps()->doAcc();
2477 bool accDiffDir = mat->
ps()->doAccDiffDir();
2478 bool gravity = mat->
ps()->doGravity();
2479 bool FlBoTex = mat->
ps()->doFlipBookTexture();
2480 bool rot = mat->
ps()->doRotation();
2481 bool rotRange = mat->
ps()->doRotRange();
2482 bool shape = mat->
ps()->doShape();
2578 setVariable(vertCode,
"localPosition",
"a_position");
2587 in vec3 v_P_VS; // Interpol. point of illumination in view space (VS)
2588 in vec3 v_P_WS; // Interpol. point of illumination in world space (WS)
2589 in vec3 v_N_VS; // Interpol. normal at v_P_VS in view space
2614 for (
auto light : *lights)
2616 if (light->createsShadows())
2624 string u_lightSm = R
"(
2625 uniform vec4 u_lightPosWS[NUM_LIGHTS]; // position of light in world space
2626 uniform bool u_lightCreatesShadows[NUM_LIGHTS]; // flag if light creates shadows
2627 uniform int u_lightNumCascades[NUM_LIGHTS]; // number of cascades for cascaded shadowmap
2628 uniform bool u_lightDoSmoothShadows[NUM_LIGHTS]; // flag if percentage-closer filtering is enabled
2629 uniform int u_lightSmoothShadowLevel[NUM_LIGHTS]; // radius of area to sample for PCF
2630 uniform float u_lightShadowMinBias[NUM_LIGHTS]; // min. shadow bias value at 0° to N
2631 uniform float u_lightShadowMaxBias[NUM_LIGHTS]; // min. shadow bias value at 90° to N
2632 uniform bool u_lightUsesCubemap[NUM_LIGHTS]; // flag if light has a cube shadow map
2633 uniform bool u_lightsDoColoredShadows; // flag if shadows should be colored
2635 for (
SLuint i = 0; i < lights->size(); ++i)
2637 SLLight* light = lights->at(i);
2644 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
"[6];\n";
2648 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
"[" + std::to_string(shadowMap->
numCascades()) +
"];\n";
2652 u_lightSm +=
"uniform mat4 u_lightSpace_" + std::to_string(i) +
";\n";
2661 string smDecl =
"\n";
2662 for (
SLuint i = 0; i < lights->size(); ++i)
2664 SLLight* light = lights->at(i);
2669 smDecl +=
"uniform samplerCube u_shadowMapCube_" + to_string(i) +
";\n";
2672 for (
int j = 0; j < light->
shadowMap()->depthBuffers().size(); j++)
2673 smDecl +=
"uniform sampler2D u_cascadedShadowMap_" + to_string(i) +
"_" + std::to_string(j) +
";\n";
2675 smDecl +=
"uniform float u_cascadesFactor_" + to_string(i) +
";\n";
2678 smDecl +=
"uniform sampler2D u_shadowMap_" + to_string(i) +
";\n";
2687 bool doCascadedSM =
false;
2688 for (
SLLight* light : *lights)
2690 if (light->doCascadedShadows())
2692 doCascadedSM =
true;
2697 string shadowTestCode = R
"(
2698 //-----------------------------------------------------------------------------
2699 int vectorToFace(vec3 vec) // Vector to process
2701 vec3 absVec = abs(vec);
2702 if (absVec.x > absVec.y && absVec.x > absVec.z)
2703 return vec.x > 0.0 ? 0 : 1;
2704 else if (absVec.y > absVec.x && absVec.y > absVec.z)
2705 return vec.y > 0.0 ? 2 : 3;
2707 return vec.z > 0.0 ? 4 : 5;
2709 //-----------------------------------------------------------------------------
2710 int getCascadesDepthIndex(in int i, int numCascades)
2715 for (
SLuint i = 0; i < lights->size(); ++i)
2717 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2720 shadowTestCode +=
" if (i == " + std::to_string(i) +
")\n";
2721 shadowTestCode +=
" {\n";
2722 shadowTestCode +=
" factor = u_cascadesFactor_" + std::to_string(i) +
";\n";
2723 shadowTestCode +=
" }\n";
2727 shadowTestCode += R
"(
2728 float fi = u_camClipNear;
2731 for (int i = 0; i < numCascades-1; i++)
2734 fi = factor * u_camClipNear * pow((u_camClipFar/(factor*u_camClipNear)), float(i+1)/float(numCascades));
2738 return numCascades-1;
2740 //-----------------------------------------------------------------------------
2741 float shadowTest(in int i, in vec3 N, in vec3 lightDir)
2743 if (u_lightCreatesShadows[i])
2745 // Calculate position in light space
2747 vec3 lightToFragment = v_P_WS - u_lightPosWS[i].xyz;
2750 if (doCascadedSM > 0)
2752 shadowTestCode += R
"(
2755 if (u_lightNumCascades[i] > 0)
2757 index = getCascadesDepthIndex(i, u_lightNumCascades[i]);
2759 for (
SLuint i = 0; i < lights->size(); ++i)
2761 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2763 shadowTestCode +=
" if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"[index]; }\n";
2765 shadowTestCode += R
"(
2767 else if (u_lightUsesCubemap[i])
2769 for (
SLuint i = 0; i < lights->size(); ++i)
2771 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2773 shadowTestCode +=
" if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"[vectorToFace(lightToFragment)]; }\n";
2775 shadowTestCode += R
"(
2780 for (
SLuint i = 0; i < lights->size(); ++i)
2782 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2784 shadowTestCode +=
"if (i == " + std::to_string(i) +
") { lightSpace = u_lightSpace_" + std::to_string(i) +
"}\n";
2786 shadowTestCode += R
"(
2792 shadowTestCode += R
"(
2793 if (u_lightUsesCubemap[i])
2796 for (
SLuint i = 0; i < lights->size(); ++i)
2798 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2800 shadowTestCode +=
" if (i == " + std::to_string(i) +
") lightSpace = u_lightSpace_" + std::to_string(i) +
"[vectorToFace(lightToFragment)];\n";
2802 shadowTestCode += R
"(
2807 for (
SLuint i = 0; i < lights->size(); ++i)
2809 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2811 shadowTestCode +=
" if (i == " + std::to_string(i) +
") lightSpace = u_lightSpace_" + std::to_string(i) +
";\n";
2813 shadowTestCode += R
"(
2818 shadowTestCode += R"(
2819 vec4 lightSpacePosition = lightSpace * vec4(v_P_WS, 1.0);
2821 // Normalize lightSpacePosition
2822 vec3 projCoords = lightSpacePosition.xyz / lightSpacePosition.w;
2824 // Convert to texture coordinates
2825 projCoords = projCoords * 0.5 + 0.5;
2827 float currentDepth = projCoords.z;
2829 // Look up depth from shadow map
2833 // calculate bias between min. and max. bias depending on the angle between N and lightDir
2834 float bias = max(u_lightShadowMaxBias[i] * (1.0 - dot(N, lightDir)), u_lightShadowMinBias[i]);
2836 // Use percentage-closer filtering (PCF) for softer shadows (if enabled)
2837 if (u_lightDoSmoothShadows[i])
2839 int level = u_lightSmoothShadowLevel[i];
2843 for (
SLuint i = 0; i < lights->size(); ++i)
2845 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2847 shadowTestCode +=
" if (i == " + to_string(i) +
") { texelSize = 1.0 / vec2(textureSize(u_shadowMap_" + to_string(i) +
", 0)); }\n";
2850 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2851 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2852 shadowTestCode +=
" if (index == " + to_string(j) +
") { texelSize = 1.0 / vec2(textureSize(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", 0)); }\n";
2854 shadowTestCode +=
" }\n";
2857 shadowTestCode += R
"(
2858 for (int x = -level; x <= level; ++x)
2860 for (int y = -level; y <= level; ++y)
2863 for (
SLuint i = 0; i < lights->size(); ++i)
2865 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2867 shadowTestCode +=
" if (i == " + to_string(i) +
") { closestDepth = texture(u_shadowMap_" + to_string(i) +
", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2870 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2871 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2872 shadowTestCode +=
" if (index == " + to_string(j) +
") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", projCoords.xy + vec2(x, y) * texelSize).r; }\n";
2873 shadowTestCode +=
" }\n";
2877 shadowTestCode += R
"(
2878 shadow += currentDepth - bias > closestDepth ? 1.0 : 0.0;
2881 shadow /= pow(1.0 + 2.0 * float(level), 2.0);
2885 if (u_lightUsesCubemap[i])
2888 for (
SLuint i = 0; i < lights->size(); ++i)
2890 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2892 shadowTestCode +=
" if (i == " + to_string(i) +
") closestDepth = texture(u_shadowMapCube_" + to_string(i) +
", lightToFragment).r;\n";
2894 shadowTestCode += R
"(
2896 else if (u_lightNumCascades[i] > 0)
2899 for (
SLuint i = 0; i < lights->size(); ++i)
2901 SLLight* light = lights->at(i);
2902 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2905 shadowTestCode +=
" if (i == " + to_string(i) +
")\n {\n";
2906 for (
int j = 0; j < shadowMap->
depthBuffers().size(); j++)
2907 shadowTestCode +=
" if (index == " + to_string(j) +
") { closestDepth = texture(u_cascadedShadowMap_" + to_string(i) +
"_" + to_string(j) +
", projCoords.xy).r; }\n";
2908 shadowTestCode +=
" }";
2912 shadowTestCode += R
"(
2918 for (
SLuint i = 0; i < lights->size(); ++i)
2920 SLShadowMap* shadowMap = lights->at(i)->shadowMap();
2922 shadowTestCode +=
" if (i == " + to_string(i) +
") closestDepth = texture(u_shadowMap_" + to_string(i) +
", projCoords.xy).r;\n";
2925 shadowTestCode += R
"(
2928 // The fragment is in shadow if the light doesn't "see" it
2929 if (currentDepth > closestDepth + bias)
2939 return shadowTestCode;
2948 #if defined(DEBUG) && defined(_DEBUG)
2955 #ifndef SL_EMSCRIPTEN
2959 SL_EXIT_MSG(
"SLGLProgramGenerated::addCodeToShader: SLGLProgramManager::configPath not existing");
2965 SL_EXIT_MSG(
"SLGLProgramGenerated::addCodeToShader: Failed to created SLGLProgramManager::configPath/generatedShaders");
2976 const std::string& name,
2977 const std::string& value)
2979 std::string placeholder =
"${" +
name +
"}";
2981 std::string::size_type pos = 0;
2982 while ((pos = code.find(placeholder)) != std::string::npos)
2984 code.replace(pos, placeholder.size(), value);
2985 pos += value.size();
2993 string header =
"\nprecision highp float;\n";
2994 header +=
"\n#define NUM_LIGHTS " + to_string(numLights) +
"\n";
3003 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.