Vuo  2.4.0
VuoShaderShaders.h
Go to the documentation of this file.
1
14 \n#include "VuoGlslProjection.glsl"
15
16 // Inputs provided by VuoSceneRenderer
17 uniform mat4 modelviewMatrix;
18 attribute vec3 position;
19 attribute vec3 normal;
20 attribute vec2 textureCoordinate;
21 attribute vec4 vertexColor;
22 uniform bool hasVertexColors;
23
24 // Outputs to geometry shader
25 varying vec3 geometryPosition;
26 varying vec3 geometryNormal;
27 varying vec2 geometryTextureCoordinate;
28 varying vec4 geometryVertexColor;
29
30 void main()
31 {
32 geometryPosition = (cameraMatrixInverse * modelviewMatrix * vec4(position, 1.)).xyz;
33 geometryNormal = (cameraMatrixInverse * modelviewMatrix * vec4(normal, 0.)).xyz;
34 geometryTextureCoordinate = textureCoordinate;
35 geometryVertexColor = hasVertexColors ? vertexColor : vec4(1.);
36 gl_Position = VuoGlsl_projectPosition(modelviewMatrix * vec4(position, 1.));
37 }
38);
39
44{
45 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
46 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
47
48 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
49 // Inputs
50 varying vec2 fragmentTextureCoordinate;
51 uniform vec4 blah;
52
53 void main()
54 {
55 // Work around ATI Radeon HD 5770 bug.
56 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
57 // https://b33p.net/kosada/node/11256
58 gl_FragColor = blah;
59
60 // Based on the Gritz/Baldwin antialiased checkerboard shader.
61
62 vec3 color0 = vec3(1 -fragmentTextureCoordinate.x, fragmentTextureCoordinate.y, 1 ) * (gl_FrontFacing ? 1 : .25);
63 vec3 color1 = vec3(0.75-fragmentTextureCoordinate.x, fragmentTextureCoordinate.y-0.25, 0.75) * (gl_FrontFacing ? 1 : .25);
64 float frequency = 8;
65 vec2 filterWidth = fwidth(fragmentTextureCoordinate) * frequency;
66
67 vec2 checkPos = fract(fragmentTextureCoordinate * frequency);
68 vec2 p = smoothstep(vec2(0.5), filterWidth + vec2(0.5), checkPos) +
69 (1 - smoothstep(vec2(0), filterWidth, checkPos));
70
71 gl_FragColor = vec4(mix(color0, color1, p.x*p.y + (1-p.x)*(1-p.y)), 1);
72 }
73 );
74
75 const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
76 // Inputs
77 varying vec3 fragmentPosition;
78 varying vec3 fragmentNormal;
79 varying vec2 fragmentTextureCoordinate;
80 varying vec4 fragmentVertexColor;
81 uniform vec4 blah;
82
83 void main()
84 {
85 // Work around ATI Radeon HD 5770 bug.
86 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
87 // https://b33p.net/kosada/node/11256
88 gl_FragColor = blah;
89
90 fragmentPosition;
91 fragmentNormal;
92 fragmentTextureCoordinate;
93 fragmentVertexColor;
94
95 // Based on the Gritz/Baldwin antialiased checkerboard shader.
96
97 vec3 color0 = vec3(1 -fragmentTextureCoordinate.x, fragmentTextureCoordinate.y, 1);
98 vec3 color1 = vec3(0.75-fragmentTextureCoordinate.x, fragmentTextureCoordinate.y-0.25, 0.75);
99 float frequency = 8;
100 vec2 filterWidth = fwidth(fragmentTextureCoordinate) * frequency;
101
102 vec2 checkPos = fract(fragmentTextureCoordinate * frequency);
103 // Add 0.00001 so that smoothstep() doesn't return NaN on ATI Radeon HD 5770.
104 // https://b33p.net/kosada/node/10467
105 vec2 p = smoothstep(vec2(0.5), filterWidth + vec2(0.5), checkPos) +
106 (1 - smoothstep(vec2(0), filterWidth, checkPos+0.00001));
107
108 gl_FragColor = vec4(mix(color0, color1, p.x*p.y + (1-p.x)*(1-p.y)), 1);
109 }
110 );
111
112 VuoShader shader = VuoShader_make("Default Shader (Checkerboard)");
113
114 VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
116
117 VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
119
120 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
121
122 VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
123
124 return shader;
125}
126
135{
136 static dispatch_once_t once = 0;
137 static VuoShader defaultShader;
138 dispatch_once(&once, ^{
139 defaultShader = VuoShader_makeDefaultShaderInternal();
140 VuoRegisterSingleton(defaultShader);
141 VuoRegisterSingleton(defaultShader->name);
142 VuoRegisterSingleton(defaultShader->pointProgram.vertexSource);
143 VuoRegisterSingleton(defaultShader->pointProgram.geometrySource);
144 VuoRegisterSingleton(defaultShader->pointProgram.fragmentSource);
145 VuoRegisterSingleton(defaultShader->lineProgram.vertexSource);
146 VuoRegisterSingleton(defaultShader->lineProgram.geometrySource);
147 VuoRegisterSingleton(defaultShader->lineProgram.fragmentSource);
148 VuoRegisterSingleton(defaultShader->triangleProgram.vertexSource);
149 VuoRegisterSingleton(defaultShader->triangleProgram.fragmentSource);
150 VuoRegisterSingleton(defaultShader->uniforms[0].name);
151 VuoRegisterSingleton(defaultShader->uniforms[0].type);
152 });
153 return defaultShader;
154}
155
164{
165 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
166 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
167
168 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
169 \n#include "VuoGlslAlpha.glsl"
170
171 // Inputs from ports
172 uniform sampler2D texture;
173 uniform float alpha;
174 uniform vec4 blah;
175
176 // Inputs from vertex/geometry shader
177 varying vec2 fragmentTextureCoordinate;
178 varying vec4 fragmentVertexColor;
179
180 void main()
181 {
182 // Work around ATI Radeon HD 5770 bug.
183 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
184 // https://b33p.net/kosada/node/11256
185 gl_FragColor = blah;
186
187 vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate) * fragmentVertexColor;
188 color *= alpha;
189 VuoGlsl_discardInvisible(color.a);
190 gl_FragColor = color;
191 }
192 );
193
194 const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
195 \n#include "VuoGlslAlpha.glsl"
196
197 // Inputs from ports
198 uniform sampler2D texture;
199 uniform float alpha;
200 uniform vec4 blah;
201
202 // Inputs from vertex/geometry shader
203 varying vec3 fragmentPosition;
204 varying vec2 fragmentTextureCoordinate;
205 varying vec4 fragmentVertexColor;
206
207 void main()
208 {
209 // Work around ATI Radeon HD 5770 bug.
210 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
211 // https://b33p.net/kosada/node/11256
212 gl_FragColor = blah;
213
214 fragmentPosition;
215
216 vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate) * fragmentVertexColor;
217 color *= alpha;
218 VuoGlsl_discardInvisible(color.a);
219 gl_FragColor = color;
220 }
221 );
222
223 VuoShader shader = VuoShader_make("Image Shader (Unlit)");
224
225 VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
227
228 VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
230
231 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
232
233 VuoShader_setUniform_VuoImage(shader, "texture", image);
234 VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
235 VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
236
237 return shader;
238}
239
251{
252 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
253 \n#include "VuoGlslAlpha.glsl"
254
255 // Inputs from ports
256 uniform sampler2D texture;
257
258 // Inputs from vertex/geometry shader
259 varying vec2 fragmentTextureCoordinate;
260
261 void main()
262 {
263 vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate);
264 VuoGlsl_discardInvisible(color.a);
265 gl_FragColor = color;
266 }
267 );
268
269 const char *fragmentShaderSourceFlipped = VUOSHADER_GLSL_SOURCE(120,
270 \n#include "VuoGlslAlpha.glsl"
271
272 // Inputs from ports
273 uniform sampler2D texture;
274
275 // Inputs from vertex/geometry shader
276 varying vec2 fragmentTextureCoordinate;
277
278 void main()
279 {
280 vec4 color = VuoGlsl_sample(texture, vec2(fragmentTextureCoordinate.x, 1. - fragmentTextureCoordinate.y));
281 VuoGlsl_discardInvisible(color.a);
282 gl_FragColor = color;
283 }
284 );
285
286 VuoShader shader = VuoShader_make("Image Shader (Unlit, AlphaPassthru)");
287 if (flipped)
288 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSourceFlipped);
289 else
290 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
291 VuoShader_setUniform_VuoImage(shader, "texture", image);
292 return shader;
293}
294
303{
304 if (!image)
305 return NULL;
306
307 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
308 \n#include "VuoGlslAlpha.glsl"
309
310 // Inputs
311 uniform sampler2DRect texture;
312 uniform vec2 textureSize;
313 uniform float alpha;
314 varying vec2 fragmentTextureCoordinate;
315
316 void main()
317 {
318 vec4 color = VuoGlsl_sampleRect(texture, fragmentTextureCoordinate*textureSize);
319 color *= alpha;
320 VuoGlsl_discardInvisible(color.a);
321 gl_FragColor = color;
322 }
323 );
324
325 VuoShader shader = VuoShader_make("Image Shader (GL_TEXTURE_RECTANGLE)");
326 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
327 VuoShader_setUniform_VuoImage (shader, "texture", image);
328 VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
329 VuoShader_setUniform_VuoPoint2d(shader, "textureSize", VuoPoint2d_make(image->pixelsWide, image->pixelsHigh));
330 return shader;
331}
332
344{
345 if (!image)
346 return NULL;
347
348 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
349 \n#include "VuoGlslAlpha.glsl"
350
351 // Inputs
352 uniform sampler2DRect texture;
353 uniform vec2 textureSize;
354 varying vec2 fragmentTextureCoordinate;
355
356 void main()
357 {
358 vec4 color = VuoGlsl_sampleRect(texture, fragmentTextureCoordinate*textureSize);
359 VuoGlsl_discardInvisible(color.a);
360 gl_FragColor = color;
361 }
362 );
363
364 const char *fragmentShaderSourceFlipped = VUOSHADER_GLSL_SOURCE(120,
365 \n#include "VuoGlslAlpha.glsl"
366
367 // Inputs
368 uniform sampler2DRect texture;
369 uniform vec2 textureSize;
370 varying vec2 fragmentTextureCoordinate;
371
372 void main()
373 {
374 vec4 color = VuoGlsl_sampleRect(texture, vec2(fragmentTextureCoordinate.x, 1. - fragmentTextureCoordinate.y) * textureSize);
375 VuoGlsl_discardInvisible(color.a);
376 gl_FragColor = color;
377 }
378 );
379
380 VuoShader shader = VuoShader_make("Image Shader (GL_TEXTURE_RECTANGLE, AlphaPassthru)");
381 if (flipped)
382 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSourceFlipped);
383 else
384 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
385 VuoShader_setUniform_VuoImage (shader, "texture", image);
386 VuoShader_setUniform_VuoPoint2d(shader, "textureSize", VuoPoint2d_make(image->pixelsWide, image->pixelsHigh));
387 return shader;
388}
389
396{
397 const char *vertexShaderSource = VUOSHADER_GLSL_SOURCE(120,
398 \n#include "VuoGlslProjection.glsl"
399
400 // Inputs from VuoSceneRenderer
401 uniform mat4 modelviewMatrix;
402 attribute vec3 position;
403 attribute vec4 vertexColor;
404 uniform bool hasVertexColors;
405
406 // Outputs to fragment shader
407 varying vec3 fragmentPosition;
408 varying vec3 fragmentNormal;
409 varying vec2 fragmentTextureCoordinate;
410 varying vec4 fragmentVertexColor;
411
412 void main()
413 {
414 gl_Position = VuoGlsl_projectPosition(modelviewMatrix * vec4(position, 1.));
415 fragmentVertexColor = hasVertexColors ? vertexColor : vec4(1.);
416 }
417 );
418
419 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
420 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
421
422 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
423 // Inputs from ports
424 uniform vec4 color;
425
426 // Inputs from vertex/geometry shader
427 varying vec4 fragmentVertexColor;
428
429 void main()
430 {
431 gl_FragColor = color * fragmentVertexColor;
432 }
433 );
434
435 const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
436 // Inputs from ports
437 uniform vec4 color;
438
439 // Inputs from vertex/geometry shader
440 varying vec3 fragmentPosition;
441 varying vec3 fragmentNormal;
442 varying vec2 fragmentTextureCoordinate;
443 varying vec4 fragmentVertexColor;
444
445 void main()
446 {
447 fragmentPosition;
448 fragmentNormal;
449 fragmentTextureCoordinate;
450
451 gl_FragColor = color * fragmentVertexColor;
452 }
453 );
454
455 VuoShader shader = VuoShader_make("Color Shader (Unlit)");
456
457 VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
459
460 VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
462
463 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, vertexShaderSource, NULL, fragmentShaderSource);
464
465 VuoShader_setUniform_VuoColor(shader, "color", color);
466
467 return shader;
468}
469
481{
482 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
483 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
484
485 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
486 uniform vec4 color;
487 uniform float sharpness;
488 varying vec2 fragmentTextureCoordinate;
489
490 void main(void)
491 {
492 float dist = distance(fragmentTextureCoordinate, vec2(0.5,0.5));
493 float delta = fwidth(dist);
494 gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness/2 - delta, 1 - sharpness/2 + delta, dist*2));
495 }
496 );
497
498 VuoShader shader = VuoShader_make("Circle Shader");
499 shader->objectScale = 0.5;
500
501 VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSource);
503
504 VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSource);
506
507 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
508
509 VuoShader_setUniform_VuoColor(shader, "color", color);
510 VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
511 return shader;
512}
513
521{
522 // The VUOSHADER_GLSL_SOURCE macro gets hung up on the const vec2 (); declaration.
523 const char *fragmentShaderSource = "#version 120 \n\
524varying vec2 fragmentTextureCoordinate;\
525uniform vec4 color;\
526uniform vec4 lineColor;\
527uniform float thickness;\
528const int CHECK_VERTICES = 6;\
529const vec2 CHECK[CHECK_VERTICES] = vec2[] (\
530 vec2(.0, .47),\
531 vec2(.175, .66),\
532 vec2(.37, .46),\
533 vec2(.82, .9),\
534 vec2(1, .72),\
535 vec2(.37, .1)\
536);\
537\
538bool doLineSegmentsIntersect(vec2 p0, vec2 p1, vec2 p2, vec2 p3)\
539{\
540 vec2 s1 = p1 - p0;\
541 vec2 s2 = p3 - p2;\
542 float s, t;\
543 s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) / (-s2.x * s1.y + s1.x * s2.y);\
544 t = ( s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) / (-s2.x * s1.y + s1.x * s2.y);\
545\
546 return (s >= 0 && s <= 1 && t >= 0 && t <= 1);\
547}\
548\
549float drawLine(vec2 p1, vec2 p2)\
550{\
551 vec2 uv = fragmentTextureCoordinate;\
552 float a = abs(distance(p1, uv));\
553 float b = abs(distance(p2, uv));\
554 float c = abs(distance(p1, p2));\
555 if( a >= c || b >= c) return 0.;\
556 float p = (a + b + c) * .5;\
557 float h = 2. / c * sqrt(p * (p-a) * (p-b) * (p-c));\
558 return mix(1, 0, smoothstep(0.5 * thickness, 1.5 * thickness, h));\
559}\
560\
561bool isPointInPolygon(vec2 point)\
562{\
563 vec2 rayStart = vec2(0, .5);\
564 bool inPoly = false;\
565\
566 for(int i = 0; i < CHECK_VERTICES; i += 1)\
567 {\
568 if(doLineSegmentsIntersect(rayStart, point, CHECK[i], CHECK[i == (CHECK_VERTICES-1) ? 0 : i+1]) )\
569 inPoly = !inPoly;\
570 }\
571\
572 return inPoly;\
573}\
574\
575void main(void)\
576{\
577 float line = 0;\
578 for(int i = 0; i < CHECK_VERTICES; i++)\
579 line = max(drawLine(CHECK[i], CHECK[i < CHECK_VERTICES-1 ? i+1 : 0]), line);\
580 gl_FragColor = mix(isPointInPolygon(fragmentTextureCoordinate) ? color : vec4(0), lineColor, line);\
581}\
582";
583
584 VuoShader shader = VuoShader_make("Checkmark Shader");
585 shader->objectScale = 1;
586 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
587 VuoShader_setUniform_VuoColor(shader, "color", color);
588 VuoShader_setUniform_VuoColor(shader, "lineColor", outline);
589 VuoShader_setUniform_VuoReal(shader, "thickness", thickness);
590 return shader;
591}
592
606{
607 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
608 uniform vec4 color;
609 uniform float sharpness;
610 uniform float roundness;
611 uniform float aspect;
612 varying vec2 fragmentTextureCoordinate;
613
614 void main(void)
615 {
616 float roundness2 = max(1. - sharpness, roundness);
617 roundness2 = min(aspect, roundness2);
618 float diameter = roundness2 / 2.;
619 diameter = max(diameter, 0.001);
620 float radius = diameter / 2.;
621 vec2 r = vec2(radius/aspect, radius);
622
623 vec2 cornerCircleCenter = vec2(0.,0.);
624 if (fragmentTextureCoordinate.x > 0.75 - r.x)
625 {
626 if (fragmentTextureCoordinate.y > 0.75 - r.y)
627 // Top right corner
628 cornerCircleCenter = vec2(0.75, 0.75) + vec2(-r.x, -r.y);
629 else if (fragmentTextureCoordinate.y < 0.25 + r.y)
630 // Bottom right corner
631 cornerCircleCenter = vec2(0.75, 0.25) + vec2(-r.x, r.y);
632 }
633 else if (fragmentTextureCoordinate.x < 0.25 + r.x)
634 {
635 if (fragmentTextureCoordinate.y > 0.75 - r.y)
636 // Top left corner
637 cornerCircleCenter = vec2(0.25, 0.75) + vec2( r.x, -r.y);
638 else if (fragmentTextureCoordinate.y < 0.25 + radius)
639 // Bottom left corner
640 cornerCircleCenter = vec2(0.25, 0.25) + vec2( r.x, r.y);
641 }
642
643 float dist = 0.;
644 if (cornerCircleCenter.x > 0.)
645 dist = distance((fragmentTextureCoordinate - cornerCircleCenter) * vec2(aspect, 1.) + cornerCircleCenter, cornerCircleCenter) / diameter;
646 else
647 {
648 float f = 1. - (1. - sharpness) * (1. - sharpness);
649 if (aspect < 1.)
650 f = 1./f;
651 float n = (fragmentTextureCoordinate.x - 0.5) * f;
652
653 if (fragmentTextureCoordinate.y < 0.5 + n)
654 {
655 if (fragmentTextureCoordinate.y > 0.5 - n)
656 // Right edge
657 dist = (fragmentTextureCoordinate.x - (0.75 - r.x)) * aspect;
658 else
659 // Bottom edge
660 dist = (0.25 + r.y) - fragmentTextureCoordinate.y;
661 }
662 else
663 {
664 if (fragmentTextureCoordinate.y > 0.5 - n)
665 // Top edge
666 dist = fragmentTextureCoordinate.y - (0.75 - r.y);
667 else
668 // Left edge
669 dist = ((0.25 + r.x) - fragmentTextureCoordinate.x) * aspect;
670 }
671
672 dist /= diameter;
673 }
674
675// float delta = min(fwidth(fragmentTextureCoordinate.x), fwidth(fragmentTextureCoordinate.y));
676 float delta = fwidth(fragmentTextureCoordinate.y);
677 delta /= diameter;
678 delta /= 2.;
679
680 gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness / 2. - delta, 1. - sharpness / 2. + delta, dist));
681 }
682 );
683
684 VuoShader shader = VuoShader_make("Rounded Rectangle Shader");
685 shader->objectScale = 0.5;
686 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
687 VuoShader_setUniform_VuoColor(shader, "color", color);
688 VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
689 VuoShader_setUniform_VuoReal (shader, "roundness", VuoReal_clamp(roundness, 0, 1));
690 VuoShader_setUniform_VuoReal (shader, "aspect", aspect);
691 return shader;
692}
693
708 VuoColor backgroundColor,
709 VuoColor activeColor,
710 VuoReal sharpness,
711 VuoReal roundness,
712 VuoReal aspect,
713 VuoBoolean isHorizontal,
714 VuoReal value)
715{
716 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
717 uniform vec4 backgroundColor;
718 uniform vec4 activeColor;
719 uniform float sharpness;
720 uniform float roundness;
721 uniform float aspect;
722 uniform float progress;
723 uniform bool isHorizontal;
724 varying vec2 fragmentTextureCoordinate;
725
726 void main(void)
727 {
728 float roundness2 = max(1. - sharpness, roundness);
729 roundness2 = min(aspect, roundness2);
730 float diameter = roundness2 / 2.;
731 diameter = max(diameter, 0.001);
732 float radius = diameter / 2.;
733 vec2 r = vec2(radius/aspect, radius);
734
735 vec2 cornerCircleCenter = vec2(0.,0.);
736 if (fragmentTextureCoordinate.x > 0.75 - r.x)
737 {
738 if (fragmentTextureCoordinate.y > 0.75 - r.y)
739 // Top right corner
740 cornerCircleCenter = vec2(0.75, 0.75) + vec2(-r.x, -r.y);
741 else if (fragmentTextureCoordinate.y < 0.25 + r.y)
742 // Bottom right corner
743 cornerCircleCenter = vec2(0.75, 0.25) + vec2(-r.x, r.y);
744 }
745 else if (fragmentTextureCoordinate.x < 0.25 + r.x)
746 {
747 if (fragmentTextureCoordinate.y > 0.75 - r.y)
748 // Top left corner
749 cornerCircleCenter = vec2(0.25, 0.75) + vec2( r.x, -r.y);
750 else if (fragmentTextureCoordinate.y < 0.25 + radius)
751 // Bottom left corner
752 cornerCircleCenter = vec2(0.25, 0.25) + vec2( r.x, r.y);
753 }
754
755 float dist = 0.;
756 if (cornerCircleCenter.x > 0.)
757 dist = distance((fragmentTextureCoordinate - cornerCircleCenter) * vec2(aspect, 1.) + cornerCircleCenter, cornerCircleCenter) / diameter;
758 else
759 {
760 float f = 1. - (1. - sharpness) * (1. - sharpness);
761 if (aspect < 1.)
762 f = 1./f;
763 float n = (fragmentTextureCoordinate.x - 0.5) * f;
764
765 if (fragmentTextureCoordinate.y < 0.5 + n)
766 {
767 if (fragmentTextureCoordinate.y > 0.5 - n)
768 // Right edge
769 dist = (fragmentTextureCoordinate.x - (0.75 - r.x)) * aspect;
770 else
771 // Bottom edge
772 dist = (0.25 + r.y) - fragmentTextureCoordinate.y;
773 }
774 else
775 {
776 if (fragmentTextureCoordinate.y > 0.5 - n)
777 // Top edge
778 dist = fragmentTextureCoordinate.y - (0.75 - r.y);
779 else
780 // Left edge
781 dist = ((0.25 + r.x) - fragmentTextureCoordinate.x) * aspect;
782 }
783
784 dist /= diameter;
785 }
786
787 float delta = fwidth(dist) / 2.;
788
789 // fwidth() seems to sometimes output invalid results; this hides most of it.
790 if (delta > 0.1)
791 delta = 0.;
792
793 float val = (isHorizontal ? fragmentTextureCoordinate.x : fragmentTextureCoordinate.y);
794 val = (clamp(val, .25, .75) - .25) / .5;
795 vec4 color = val < progress ? activeColor : backgroundColor;
796 gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness / 2. - delta, 1. - sharpness / 2. + delta, dist));
797 }
798 );
799
800 VuoShader shader = VuoShader_make("Rounded Rectangle Track Shader");
801 shader->objectScale = 0.5;
802 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
803 VuoShader_setUniform_VuoColor(shader, "backgroundColor", backgroundColor);
804 VuoShader_setUniform_VuoColor(shader, "activeColor", activeColor);
805 VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
806 VuoShader_setUniform_VuoReal (shader, "roundness", VuoReal_clamp(roundness, 0, 1));
807 VuoShader_setUniform_VuoReal (shader, "aspect", aspect);
808 VuoShader_setUniform_VuoBoolean (shader, "isHorizontal", isHorizontal);
809 VuoShader_setUniform_VuoReal (shader, "progress", value);
810 return shader;
811}
812
822VuoShader VuoShader_makeLitColorShader(VuoColor diffuseColor, VuoColor highlightColor, VuoReal shininess)
823{
824 const char *vertexShaderSource = VUOSHADER_GLSL_SOURCE(120,
825 \n#include "VuoGlslProjection.glsl"
826
827 // Inputs provided by VuoSceneRenderer
828 uniform mat4 modelviewMatrix;
829 attribute vec3 position;
830 attribute vec3 normal;
831 attribute vec4 vertexColor;
832 uniform bool hasVertexColors;
833
834 // Outputs to fragment shader
835 varying vec3 fragmentPosition;
836 varying vec3 fragmentNormal;
837 varying vec2 fragmentTextureCoordinate;
838 varying vec4 fragmentVertexColor;
839
840 void main()
841 {
842 fragmentTextureCoordinate;
843
844 fragmentPosition = (modelviewMatrix * vec4(position, 1.)).xyz;
845 fragmentNormal = (modelviewMatrix * vec4(normal, 0.)).xyz;
846 fragmentVertexColor = hasVertexColors ? vertexColor : vec4(1.);
847 gl_Position = VuoGlsl_projectPosition(fragmentPosition);
848 }
849 );
850
851 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
852 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
853
854 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
855 \n#include "lighting.glsl"
856
857 // Inputs from ports
858 uniform vec4 diffuseColor;
859 uniform vec4 specularColor;
860 uniform float specularPower;
861
862 // Inputs from vertex/geometry shader
863 varying vec3 fragmentNormal;
864 varying vec2 fragmentTextureCoordinate;
865 varying vec4 fragmentVertexColor;
866
867 void main()
868 {
869 // Work around ATI Radeon HD 5770 bug.
870 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
871 // https://b33p.net/kosada/node/11256
872 gl_FragColor = diffuseColor;
873
874 fragmentTextureCoordinate;
875
876 vec3 ambientContribution = vec3(0.);
877 vec3 diffuseContribution = vec3(0.);
878 vec3 specularContribution = vec3(0.);
879
880 calculateLighting(specularPower, fragmentNormal, ambientContribution, diffuseContribution, specularContribution);
881
882 ambientContribution *= diffuseColor.rgb * fragmentVertexColor.rgb;
883 diffuseContribution *= diffuseColor.rgb * fragmentVertexColor.rgb;
884 specularContribution *= specularColor.rgb * specularColor.a;
885 gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, diffuseColor.a * fragmentVertexColor.a);
886 }
887 );
888
889 VuoShader shader = VuoShader_make("Color Shader (Lit)");
890
891 VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSource);
893
894 VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSource);
896
897 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, vertexShaderSource, NULL, fragmentShaderSource);
898
899 VuoShader_setUniform_VuoColor(shader, "diffuseColor", diffuseColor);
900 VuoShader_setUniform_VuoColor(shader, "specularColor", highlightColor);
901 VuoShader_setUniform_VuoReal (shader, "specularPower", 1./(1.0001-shininess));
902 return shader;
903}
904
909 \n#include "VuoGlslProjection.glsl"
910
911 // Inputs provided by VuoSceneRenderer
912 uniform mat4 modelviewMatrix;
913 attribute vec3 position;
914 attribute vec3 normal;
915 attribute vec2 textureCoordinate;
916 attribute vec4 vertexColor;
917 uniform bool hasVertexColors;
918
919 // Outputs to fragment shader
920 varying vec3 fragmentPosition;
921 varying vec3 fragmentNormal;
922 varying vec2 fragmentTextureCoordinate;
923 varying vec4 fragmentVertexColor;
924
925 void main()
926 {
927 fragmentPosition = (modelviewMatrix * vec4(position, 1.)).xyz;
928 fragmentNormal = normalize(vec3(modelviewMatrix * vec4(normal, 0.)));
929 fragmentTextureCoordinate = textureCoordinate;
930 fragmentVertexColor = hasVertexColors ? vertexColor : vec4(1.);
931 gl_Position = VuoGlsl_projectPosition(fragmentPosition);
932 }
933);
934
939 \n#include "VuoGlslProjection.glsl"
940
941 // Inputs provided by VuoSceneRenderer
942 uniform mat4 modelviewMatrix;
943 attribute vec3 position;
944 attribute vec3 normal;
945 attribute vec2 textureCoordinate;
946 attribute vec4 vertexColor;
947 uniform bool hasVertexColors;
948
949 // Outputs to geometry shader
950 varying vec3 geometryPosition;
951 varying vec3 geometryNormal;
952 varying vec2 geometryTextureCoordinate;
953 varying vec4 geometryVertexColor;
954
955 void main()
956 {
957 geometryPosition = (modelviewMatrix * vec4(position, 1.)).xyz;
958 geometryNormal = normalize((modelviewMatrix * vec4(normal, 0.)).xyz);
959 geometryTextureCoordinate = textureCoordinate;
960 geometryVertexColor = hasVertexColors ? vertexColor : vec4(1.);
961 gl_Position = VuoGlsl_projectPosition(geometryPosition);
962 }
963);
964
976{
977 if (!image)
978 return NULL;
979
980 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
981 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
982
983 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
984 \n#include "VuoGlslAlpha.glsl"
985 \n#include "lighting.glsl"
986
987 // Inputs from vertex shader
988 varying vec3 fragmentNormal;
989 varying vec2 fragmentTextureCoordinate;
990 varying vec4 fragmentVertexColor;
991
992 // Inputs from ports
993 uniform sampler2D texture;
994 uniform float alpha;
995 uniform vec4 specularColor;
996 uniform float specularPower;
997
998 void main()
999 {
1000 // Work around ATI Radeon HD 5770 bug.
1001 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
1002 // https://b33p.net/kosada/node/11256
1003 gl_FragColor = specularColor;
1004
1005 vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate) * fragmentVertexColor;
1006 color *= alpha;
1007 VuoGlsl_discardInvisible(color.a);
1008
1009 vec3 ambientContribution = vec3(0.);
1010 vec3 diffuseContribution = vec3(0.);
1011 vec3 specularContribution = vec3(0.);
1012
1013 calculateLighting(specularPower, fragmentNormal, ambientContribution, diffuseContribution, specularContribution);
1014
1015 ambientContribution *= color.rgb;
1016 diffuseContribution *= color.rgb;
1017 specularContribution *= specularColor.rgb * specularColor.a;
1018 gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, color.a);
1019 }
1020 );
1021
1022 VuoShader shader = VuoShader_make("Image Shader (Lit)");
1023
1024 VuoShader_addSource (shader, VuoMesh_Points, lightingVertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSource);
1026
1027 VuoShader_addSource (shader, VuoMesh_IndividualLines, lightingVertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSource);
1029
1030 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, lightingVertexShaderSource, NULL, fragmentShaderSource);
1031
1032 VuoShader_setUniform_VuoImage(shader, "texture", image);
1033 VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
1034 VuoShader_setUniform_VuoColor(shader, "specularColor", highlightColor);
1035 VuoShader_setUniform_VuoReal (shader, "specularPower", 1./(1.0001-shininess));
1036
1037 return shader;
1038}
1039
1051{
1052 if (!image || !specularImage || !normalImage)
1053 return NULL;
1054
1055 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
1056 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
1057
1058 static const char *triangleGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120,
1059 \n#include "VuoGlslTangent.glsl"
1060
1061 uniform mat4 modelviewMatrix;
1062
1063 // Inputs
1064 varying in vec3 geometryPosition[3];
1065 varying in vec3 geometryNormal[3];
1066 varying in vec2 geometryTextureCoordinate[3];
1067 varying in vec4 geometryVertexColor[3];
1068
1069 // Outputs
1070 varying out vec3 fragmentPosition;
1071 varying out vec2 fragmentTextureCoordinate;
1072 varying out vec4 fragmentVertexColor;
1073 varying out mat3 vertexPlaneToWorld;
1074
1075 void main()
1076 {
1077 VuoGlslTangent_In ti;
1078 for (int i = 0; i < 3; ++i)
1079 {
1080 ti.position[i] = geometryPosition[i];
1081 ti.normal[i] = geometryNormal[i];
1082 ti.textureCoordinate[i] = geometryTextureCoordinate[i];
1083 }
1084 VuoGlslTangent_Out to;
1085 VuoGlsl_calculateTangent(ti, to);
1086
1087 for (int i = 0; i < 3; ++i)
1088 {
1089 gl_Position = gl_PositionIn[i];
1090 fragmentPosition = geometryPosition[i];
1091 fragmentTextureCoordinate = geometryTextureCoordinate[i];
1092 fragmentVertexColor = geometryVertexColor[i];
1093
1094 vertexPlaneToWorld[0] = normalize(vec3(modelviewMatrix * vec4(to.tangent[i], 0.)));
1095 vertexPlaneToWorld[1] = normalize(vec3(modelviewMatrix * -vec4(to.bitangent[i], 0.)));
1096 vertexPlaneToWorld[2] = normalize(vec3(modelviewMatrix * vec4(geometryNormal[i], 0.)));
1097
1098 EmitVertex();
1099 }
1100 EndPrimitive();
1101 }
1102 );
1103
1104 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1105 \n#include "VuoGlslAlpha.glsl"
1106 \n#include "lighting.glsl"
1107
1108 // Inputs from vertex shader
1109 varying vec2 fragmentTextureCoordinate;
1110 varying vec4 fragmentVertexColor;
1111 varying mat3 vertexPlaneToWorld;
1112
1113 // Inputs from ports
1114 uniform sampler2D texture;
1115 uniform float alpha;
1116 uniform sampler2D specularImage;
1117 uniform sampler2D normalImage;
1118 uniform vec4 blah;
1119
1120 void main()
1121 {
1122 // Work around ATI Radeon HD 5770 bug.
1123 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
1124 // https://b33p.net/kosada/node/11256
1125 gl_FragColor = blah;
1126
1127 vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate);
1128 color *= alpha;
1129 VuoGlsl_discardInvisible(color.a);
1130
1131 vec3 ambientContribution = vec3(0.);
1132 vec3 diffuseContribution = vec3(0.);
1133 vec3 specularContribution = vec3(0.);
1134
1135 vec4 specularColor = texture2D(specularImage, fragmentTextureCoordinate);
1136 float specularPower = 1./(1.0001-specularColor.a);
1137
1138 vec4 normalColor = texture2D(normalImage, fragmentTextureCoordinate);
1139 vec3 normal = normalize(vec3(
1140 2. * normalColor.r - 1.,
1141 2. * normalColor.g - 1.,
1142 normalColor.b // Leave the blue channel as-is; the normal should never point inward.
1143 ));
1144
1145 vec3 normalDirection = vertexPlaneToWorld * normal;
1146
1147 calculateLighting(specularPower, normalDirection, ambientContribution, diffuseContribution, specularContribution);
1148
1149 ambientContribution *= color.rgb * fragmentVertexColor.rgb;
1150 diffuseContribution *= color.rgb * fragmentVertexColor.rgb;
1151 specularContribution *= specularColor.rgb * specularColor.a;
1152 gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, color.a * fragmentVertexColor.a);
1153 }
1154 );
1155
1156 VuoShader shader = VuoShader_make("Image Details Shader (Lit)");
1157
1158 VuoShader_addSource (shader, VuoMesh_Points, lightingVertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSource);
1160
1161 VuoShader_addSource (shader, VuoMesh_IndividualLines, lightingVertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSource);
1163
1164 VuoShader_addSource (shader, VuoMesh_IndividualTriangles, lightingVertexShaderSourceForGeometry, triangleGeometryShaderSource, fragmentShaderSource);
1165
1166 VuoShader_setUniform_VuoImage(shader, "texture", image);
1167 VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
1168 VuoShader_setUniform_VuoImage(shader, "specularImage", specularImage);
1169 VuoShader_setUniform_VuoImage(shader, "normalImage", normalImage);
1170 VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
1171
1172 return shader;
1173}
1174
1181{
1182 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1183 \n#include "VuoGlslAlpha.glsl"
1184 \n#include "VuoGlslRandom.glsl"
1185
1186 uniform float inputColorCount;
1187 uniform float stripColorCount;
1188 uniform sampler2D gradientStrip;
1189 uniform vec2 start;
1190 uniform vec2 end;
1191 uniform float aspect;
1192 uniform float noiseAmount;
1193
1194 varying vec2 fragmentTextureCoordinate;
1195
1196 float distSqr(vec2 a, vec2 b)
1197 {
1198 return (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y);
1199 }
1200
1201 // https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
1202 // ...minus the segment part, of course.
1203 vec2 nearest_point_on_line(vec2 v, vec2 w, vec2 p)
1204 {
1205 // Return minimum distance between line segment vw and point p
1206 float l2 = distSqr(v, w); // i.e. |w-v|^2 - avoid a sqrt
1207 if (l2 == 0.0) return p;
1208 // Consider the line extending the segment, parameterized as v + t (w - v).
1209 // We find projection of point p onto the line.
1210 // It falls where t = [(p-v) . (w-v)] / |w-v|^2
1211 float t = dot(p - v, w - v) / l2;
1212 vec2 projection = v + t * (w - v);
1213 return projection;
1214 }
1215
1216 void main(void)
1217 {
1218 vec2 tcAspect = fragmentTextureCoordinate;
1219 tcAspect.y -= .5;
1220 tcAspect.y *= aspect;
1221 tcAspect.y += .5;
1222
1223 vec2 pol = nearest_point_on_line(start, end, tcAspect);
1224 float x = dot(pol-start, end-start) > 0 ? distance(start, pol)/ distance(start, end) : 0;
1225
1226 // Give x a smooth second-derivative, to reduce the ridges between colors.
1227 x *= inputColorCount - 1.;
1228 x = floor(x) + smoothstep(0.,1.,fract(x));
1229 x /= inputColorCount - 1.;
1230
1231 float gradientWidth = (1./stripColorCount)/2.;
1232 x = x * (1-gradientWidth*2) + gradientWidth; // scale to account for the gradient/2 offsets
1233
1234 vec4 color = VuoGlsl_sample(gradientStrip, vec2(clamp(x , gradientWidth, 1.-gradientWidth), .5));
1235 VuoGlsl_discardInvisible(color.a);
1236
1237 color.rgb += (VuoGlsl_random2D3D(fragmentTextureCoordinate) - 0.5) * noiseAmount;
1238
1239 gl_FragColor = color;
1240 }
1241 );
1242
1243 VuoShader shader = VuoShader_make("Linear Gradient Shader");
1244 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1245 return shader;
1246}
1247
1252{
1253 // https://b33p.net/kosada/node/12582
1254 // Instead of creating an image with only one pixel per color stop,
1255 // create `gradientExpansion` pixels per stop, to compensate for GPUs
1256 // that have limited ability to interpolate between pixels.
1257 // E.g., the Intel HD Graphics 3000 GPU limits interpolation to 64 steps.
1258 // On Intel 3000, gradientExpansion=4 would result in 256 steps (64*4);
1259 // go beyond that to provide some extra detail when rendering to 16bpc textures.
1260 int gradientExpansion = 16;
1261
1262 GLenum format = GL_BGRA;
1263 int bpp = 4;
1264 if (VuoColor_areAllOpaque(colors))
1265 {
1266 format = GL_BGR;
1267 bpp = 3;
1268 }
1269
1270 int inputColorCount = VuoListGetCount_VuoColor(colors);
1271 int stripColorCount = (inputColorCount - 1) * gradientExpansion + 1;
1272
1273 unsigned char *pixels = (unsigned char*)malloc(stripColorCount * bpp);
1274 int inputColor = 1;
1275 int step = 0;
1276 for (int i = 0; i < stripColorCount; ++i)
1277 {
1278 VuoColor col1 = VuoListGetValue_VuoColor(colors, inputColor);
1279 VuoColor col2 = VuoListGetValue_VuoColor(colors, inputColor+1);
1280
1281 VuoColor col = VuoColor_lerp(col1, col2, (float)step / gradientExpansion);
1282
1283 pixels[i * bpp ] = VuoInteger_clamp(col.a * col.b * 255, 0, 255);
1284 pixels[i * bpp + 1 ] = VuoInteger_clamp(col.a * col.g * 255, 0, 255);
1285 pixels[i * bpp + 2 ] = VuoInteger_clamp(col.a * col.r * 255, 0, 255);
1286 if (bpp == 4)
1287 pixels[i * bpp + 3] = VuoInteger_clamp(col.a * 255, 0, 255);
1288
1289 ++step;
1290 if (step >= gradientExpansion)
1291 {
1292 step = 0;
1293 ++inputColor;
1294 }
1295 }
1296
1297 VuoImage gradientStrip = VuoImage_makeFromBuffer(pixels, format, stripColorCount, 1, VuoImageColorDepth_8, ^(void *buffer){ free(buffer); });
1298
1299 VuoShader_setUniform_VuoImage (shader, "gradientStrip", gradientStrip);
1300 VuoShader_setUniform_VuoReal (shader, "inputColorCount", inputColorCount);
1301 VuoShader_setUniform_VuoReal (shader, "stripColorCount", stripColorCount);
1302}
1303
1308void VuoShader_setLinearGradientShaderValues(VuoShader shader, VuoList_VuoColor colors, VuoPoint2d start, VuoPoint2d end, VuoReal aspect, VuoReal noiseAmount)
1309{
1310 VuoShader_setGradientStrip(shader, colors);
1311 VuoShader_setUniform_VuoPoint2d(shader, "start", VuoPoint2d_make((start.x+1)/2, (start.y+1)/2));
1312 VuoShader_setUniform_VuoPoint2d(shader, "end", VuoPoint2d_make((end.x+1)/2, (end.y+1)/2));
1313 VuoShader_setUniform_VuoReal (shader, "aspect", 1./aspect);
1314 VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1315}
1316
1323{
1324 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1325 \n#include "VuoGlslAlpha.glsl"
1326 \n#include "VuoGlslRandom.glsl"
1327
1328 uniform float inputColorCount;
1329 uniform float stripColorCount;
1330 uniform sampler2D gradientStrip;
1331 uniform vec2 center;
1332 uniform vec2 scale; // if image is not square, multiply texCoord by this to account for stretch
1333 uniform float radius;
1334 uniform float noiseAmount;
1335
1336 varying vec2 fragmentTextureCoordinate;
1337
1338 void main(void)
1339 {
1340 vec2 scaledTexCoord = fragmentTextureCoordinate*scale;
1341 float x = distance(center*scale, scaledTexCoord)/radius;
1342
1343 // Give x a smooth second-derivative, to reduce the ridges between colors.
1344 x *= inputColorCount - 1.;
1345 x = floor(x) + smoothstep(0.,1.,fract(x));
1346 x /= inputColorCount - 1.;
1347
1348 float gradientWidth = (1./stripColorCount)/2.;
1349 x = x * (1-gradientWidth*2) + gradientWidth;
1350
1351 vec4 color = VuoGlsl_sample(gradientStrip, vec2(clamp(x , gradientWidth, 1.-gradientWidth), .5));
1352 VuoGlsl_discardInvisible(color.a);
1353
1354 color.rgb += (VuoGlsl_random2D3D(fragmentTextureCoordinate) - 0.5) * noiseAmount;
1355
1356 gl_FragColor = color;
1357 }
1358 );
1359
1360 VuoShader shader = VuoShader_make("Radial Gradient Shader");
1361 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1362 return shader;
1363}
1364
1370void VuoShader_setRadialGradientShaderValues(VuoShader shader, VuoList_VuoColor colors, VuoPoint2d center, VuoReal radius, VuoReal width, VuoReal height, VuoReal noiseAmount)
1371{
1372 // VuoPoint2d scale = width < height ? VuoPoint2d_make(1., height/(float)width) : VuoPoint2d_make(width/(float)height, 1.);
1373 VuoPoint2d scale = VuoPoint2d_make(1., height/(float)width);
1374
1375 VuoShader_setGradientStrip(shader, colors);
1376 VuoShader_setUniform_VuoPoint2d(shader, "center", VuoPoint2d_make((center.x+1)/2, (center.y+1)/2));
1377 VuoShader_setUniform_VuoReal (shader, "radius", radius > 0. ? radius/2. : 0);
1378 VuoShader_setUniform_VuoPoint2d(shader, "scale", VuoPoint2d_make(scale.x, scale.y));
1379 VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1380}
1381
1386{
1387 const char *vertexShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
1388 \n#include "VuoGlslProjection.glsl"
1389
1390 // Inputs provided by VuoSceneRenderer
1391 uniform mat4 modelviewMatrix;
1392 attribute vec3 position;
1393 attribute vec3 normal;
1394 attribute vec2 textureCoordinate;
1395 attribute vec4 vertexColor;
1396 uniform bool hasVertexColors;
1397
1398 // Outputs to geometry shader
1399 varying vec3 geometryPosition;
1400 varying vec3 geometryNormal;
1401 varying vec2 geometryTextureCoordinate;
1402 varying vec4 geometryVertexColor;
1403
1404 void main()
1405 {
1406 geometryPosition = (modelviewMatrix * vec4(position, 1.)).xyz;
1407 geometryNormal = (modelviewMatrix * vec4(normal, 0.)).xyz;
1408 geometryTextureCoordinate = textureCoordinate;
1409 geometryVertexColor = hasVertexColors ? vertexColor : vec4(1.);
1410 gl_Position = VuoGlsl_projectPosition(geometryPosition);
1411 }
1412 );
1413
1414 const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
1415 const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
1416
1417 const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1418 \n#include "VuoGlslAlpha.glsl"
1419 \n#include "noise3D.glsl"
1420
1421 // Inputs provided by VuoSceneRenderer
1422 uniform sampler2D colorBuffer;
1423 uniform vec2 viewportSize;
1424
1425 // Inputs from ports
1426 uniform vec4 color;
1427 uniform float aspectRatio;
1428 uniform vec2 noisePosition;
1429 uniform float noiseTime;
1430 uniform float noiseAmount;
1431 uniform float noiseScale;
1432 uniform float chromaticAberration;
1433 uniform int iterations;
1434 uniform int levels;
1435 uniform float roughness;
1436 uniform float spacing;
1437
1438 // Inputs from vertex shader
1439 varying vec2 fragmentTextureCoordinate;
1440 varying vec4 fragmentVertexColor;
1441
1442 void main()
1443 {
1444 vec2 viewportTextureCoordinate = gl_FragCoord.xy/viewportSize;
1445
1446 vec4 accumulatedColor = vec4(0.);
1447 for (int i = 0; i < iterations; ++i)
1448 {
1449 // 3D noise, since we want a continuous 2D texture that moves continuously through time.
1450 // The iteration index needn't be continuous.
1451 vec3 noiseCoordinate = vec3(fragmentTextureCoordinate.x - .5 - noisePosition.x + float(i), (fragmentTextureCoordinate.y - .5 - noisePosition.y) / aspectRatio, noiseTime);
1452 noiseCoordinate.xy *= noiseScale;
1453 vec2 noiseOffset = snoise3D2DFractal(noiseCoordinate, levels, roughness, spacing);
1454
1455 // Red
1456 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. - chromaticAberration/3.)) * vec4(1.,0.,0.,1./3.);
1457
1458 // Green
1459 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount) * vec4(0.,1.,0.,1./3.);
1460
1461 // Blue
1462 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. + chromaticAberration/3.)) * vec4(0.,0.,1.,1./3.);
1463 }
1464
1465 vec4 c = accumulatedColor / float(iterations);
1466 c.rgb /= c.a;
1467 c *= color * fragmentVertexColor;
1468 c.rgb = clamp(c.rgb, 0., 1.);
1469 c.rgb *= c.a;
1470 gl_FragColor = c;
1471 }
1472 );
1473
1474 const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
1475 \n#include "VuoGlslAlpha.glsl"
1476 \n#include "noise3D.glsl"
1477
1478 // Inputs provided by VuoSceneRenderer
1479 uniform sampler2D colorBuffer;
1480 uniform vec2 viewportSize;
1481
1482 // Inputs from ports
1483 uniform vec4 color;
1484 uniform float aspectRatio;
1485 uniform vec2 noisePosition;
1486 uniform float noiseTime;
1487 uniform float noiseAmount;
1488 uniform float noiseScale;
1489 uniform float chromaticAberration;
1490 uniform int iterations;
1491 uniform int levels;
1492 uniform float roughness;
1493 uniform float spacing;
1494
1495 // Inputs from geometry shader
1496 varying vec3 fragmentPosition;
1497 varying vec2 fragmentTextureCoordinate;
1498
1499 void main()
1500 {
1501 // Work around ATI Radeon HD 5770 bug.
1502 // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
1503 // https://b33p.net/kosada/node/11256
1504 gl_FragColor = color;
1505
1506 fragmentPosition;
1507
1508 vec2 viewportTextureCoordinate = gl_FragCoord.xy/viewportSize;
1509
1510 vec4 accumulatedColor = vec4(0.);
1511 for (int i = 0; i < iterations; ++i)
1512 {
1513 // 3D noise, since we want a continuous 2D texture that moves continuously through time.
1514 // The iteration index needn't be continuous.
1515 vec3 noiseCoordinate = vec3(fragmentTextureCoordinate.x - .5 - noisePosition.x + float(i), (fragmentTextureCoordinate.y - .5 - noisePosition.y) / aspectRatio, noiseTime);
1516 noiseCoordinate.xy *= noiseScale;
1517 vec2 noiseOffset = snoise3D2DFractal(noiseCoordinate, levels, roughness, spacing);
1518
1519 // Red
1520 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. - chromaticAberration/3.)) * vec4(1.,0.,0.,1./3.);
1521
1522 // Green
1523 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount) * vec4(0.,1.,0.,1./3.);
1524
1525 // Blue
1526 accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. + chromaticAberration/3.)) * vec4(0.,0.,1.,1./3.);
1527 }
1528
1529 vec4 c = accumulatedColor / float(iterations);
1530 c.rgb /= c.a;
1531 c *= color;
1532 c.rgb = clamp(c.rgb, 0., 1.);
1533 c.rgb *= c.a;
1534 gl_FragColor = c;
1535 }
1536 );
1537
1538 VuoShader s = VuoShader_make("Frosted Glass Shader");
1539 s->isTransparent = true;
1540
1541 VuoShader_addSource (s, VuoMesh_Points, vertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
1543
1544 VuoShader_addSource (s, VuoMesh_IndividualLines, vertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
1546
1547 VuoShader_addSource (s, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1548
1549 return s;
1550}
1551
1557void VuoShader_setFrostedGlassShaderValues(VuoShader shader, VuoColor color, VuoReal brightness, VuoPoint2d noisePosition, VuoReal noiseTime, VuoReal noiseAmount, VuoReal noiseScale, VuoReal chromaticAberration, VuoInteger levels, VuoReal roughness, VuoReal spacing, VuoInteger iterations, float aspectRatio)
1558{
1559 VuoShader_setUniform_VuoPoint4d(shader, "color", VuoPoint4d_make(color.r*brightness, color.g*brightness, color.b*brightness, color.a));
1560 VuoShader_setUniform_VuoPoint2d(shader, "noisePosition", (VuoPoint2d){(noisePosition.x+1)/2,
1561 (noisePosition.y+1)/2 * aspectRatio});
1562 VuoShader_setUniform_VuoReal (shader, "noiseTime", noiseTime);
1563 VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1564 VuoShader_setUniform_VuoReal (shader, "noiseScale", 1./VuoReal_makeNonzero(noiseScale));
1565 VuoShader_setUniform_VuoReal (shader, "chromaticAberration", VuoReal_clamp(chromaticAberration, 0, 2));
1566 VuoShader_setUniform_VuoInteger(shader, "iterations", MAX(1, iterations));
1567 VuoShader_setUniform_VuoInteger(shader, "levels", MAX(1, levels));
1568 VuoShader_setUniform_VuoReal (shader, "roughness", roughness);
1569 VuoShader_setUniform_VuoReal (shader, "spacing", spacing);
1570}