Vuo  2.0.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 vec4 position;
19  attribute vec4 textureCoordinate;
20 
21  // Outputs to geometry shader
22  varying vec4 positionForGeometry;
23  varying vec4 textureCoordinateForGeometry;
24 
25  void main()
26  {
27  positionForGeometry = cameraMatrixInverse * modelviewMatrix * position;
28  textureCoordinateForGeometry = textureCoordinate;
29  gl_Position = VuoGlsl_projectPosition(modelviewMatrix * position);
30  }
31 );
32 
37 {
38  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
39  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
40 
41  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
42  // Inputs
43  varying vec4 fragmentTextureCoordinate;
44  uniform vec4 blah;
45 
46  void main()
47  {
48  // Work around ATI Radeon HD 5770 bug.
49  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
50  // https://b33p.net/kosada/node/11256
51  gl_FragColor = blah;
52 
53  // Based on the Gritz/Baldwin antialiased checkerboard shader.
54 
55  vec3 color0 = vec3(1 -fragmentTextureCoordinate.x, fragmentTextureCoordinate.y, 1 ) * (gl_FrontFacing ? 1 : .25);
56  vec3 color1 = vec3(0.75-fragmentTextureCoordinate.x, fragmentTextureCoordinate.y-0.25, 0.75) * (gl_FrontFacing ? 1 : .25);
57  float frequency = 8;
58  vec2 filterWidth = fwidth(fragmentTextureCoordinate.xy) * frequency;
59 
60  vec2 checkPos = fract(fragmentTextureCoordinate.xy * frequency);
61  vec2 p = smoothstep(vec2(0.5), filterWidth + vec2(0.5), checkPos) +
62  (1 - smoothstep(vec2(0), filterWidth, checkPos));
63 
64  gl_FragColor = vec4(mix(color0, color1, p.x*p.y + (1-p.x)*(1-p.y)), 1);
65  }
66  );
67 
68  const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
69  // Inputs
70  varying vec4 fragmentTextureCoordinate;
71  varying vec4 vertexPosition;
72  varying mat3 vertexPlaneToWorld;
73  uniform vec4 blah;
74 
75  void main()
76  {
77  // Work around ATI Radeon HD 5770 bug.
78  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
79  // https://b33p.net/kosada/node/11256
80  gl_FragColor = blah;
81 
82  vertexPosition;
83  vertexPlaneToWorld;
84 
85  // Based on the Gritz/Baldwin antialiased checkerboard shader.
86 
87  vec3 color0 = vec3(1 -fragmentTextureCoordinate.x, fragmentTextureCoordinate.y, 1);
88  vec3 color1 = vec3(0.75-fragmentTextureCoordinate.x, fragmentTextureCoordinate.y-0.25, 0.75);
89  float frequency = 8;
90  vec2 filterWidth = fwidth(fragmentTextureCoordinate.xy) * frequency;
91 
92  vec2 checkPos = fract(fragmentTextureCoordinate.xy * frequency);
93  // Add 0.00001 so that smoothstep() doesn't return NaN on ATI Radeon HD 5770.
94  // https://b33p.net/kosada/node/10467
95  vec2 p = smoothstep(vec2(0.5), filterWidth + vec2(0.5), checkPos) +
96  (1 - smoothstep(vec2(0), filterWidth, checkPos+0.00001));
97 
98  gl_FragColor = vec4(mix(color0, color1, p.x*p.y + (1-p.x)*(1-p.y)), 1);
99  }
100  );
101 
102  VuoShader shader = VuoShader_make("Default Shader (Checkerboard)");
103 
104  VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
106 
107  VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
109 
110  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
111 
112  VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
113 
114  return shader;
115 }
116 
125 {
126  static dispatch_once_t once = 0;
127  static VuoShader defaultShader;
128  dispatch_once(&once, ^{
129  defaultShader = VuoShader_makeDefaultShaderInternal();
130  VuoRegisterSingleton(defaultShader);
131  VuoRegisterSingleton(defaultShader->name);
132  VuoRegisterSingleton(defaultShader->pointProgram.vertexSource);
133  VuoRegisterSingleton(defaultShader->pointProgram.geometrySource);
134  VuoRegisterSingleton(defaultShader->pointProgram.fragmentSource);
135  VuoRegisterSingleton(defaultShader->lineProgram.vertexSource);
136  VuoRegisterSingleton(defaultShader->lineProgram.geometrySource);
137  VuoRegisterSingleton(defaultShader->lineProgram.fragmentSource);
138  VuoRegisterSingleton(defaultShader->triangleProgram.vertexSource);
139  VuoRegisterSingleton(defaultShader->triangleProgram.fragmentSource);
140  VuoRegisterSingleton(defaultShader->uniforms[0].name);
141  VuoRegisterSingleton(defaultShader->uniforms[0].type);
142  });
143  return defaultShader;
144 }
145 
154 {
155  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
156  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
157 
158  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
159  \n#include "VuoGlslAlpha.glsl"
160 
161  // Inputs from ports
162  uniform sampler2D texture;
163  uniform float alpha;
164  uniform vec4 blah;
165 
166  // Inputs from vertex/geometry shader
167  varying vec4 fragmentTextureCoordinate;
168 
169  void main()
170  {
171  // Work around ATI Radeon HD 5770 bug.
172  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
173  // https://b33p.net/kosada/node/11256
174  gl_FragColor = blah;
175 
176  vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate.xy);
177  color *= alpha;
178  VuoGlsl_discardInvisible(color.a);
179  gl_FragColor = color;
180  }
181  );
182 
183  const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
184  \n#include "VuoGlslAlpha.glsl"
185 
186  // Inputs from ports
187  uniform sampler2D texture;
188  uniform float alpha;
189  uniform vec4 blah;
190 
191  // Inputs from vertex/geometry shader
192  varying vec4 vertexPosition;
193  varying mat3 vertexPlaneToWorld;
194  varying vec4 fragmentTextureCoordinate;
195 
196  void main()
197  {
198  // Work around ATI Radeon HD 5770 bug.
199  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
200  // https://b33p.net/kosada/node/11256
201  gl_FragColor = blah;
202 
203  vertexPosition;
204  vertexPlaneToWorld;
205 
206  vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate.xy);
207  color *= alpha;
208  VuoGlsl_discardInvisible(color.a);
209  gl_FragColor = color;
210  }
211  );
212 
213  VuoShader shader = VuoShader_make("Image Shader (Unlit)");
214 
215  VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
217 
218  VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
220 
221  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
222 
223  VuoShader_setUniform_VuoImage(shader, "texture", image);
224  VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
225  VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
226 
227  return shader;
228 }
229 
241 {
242  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
243  \n#include "VuoGlslAlpha.glsl"
244 
245  // Inputs from ports
246  uniform sampler2D texture;
247 
248  // Inputs from vertex/geometry shader
249  varying vec4 fragmentTextureCoordinate;
250 
251  void main()
252  {
253  vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate.xy);
254  VuoGlsl_discardInvisible(color.a);
255  gl_FragColor = color;
256  }
257  );
258 
259  const char *fragmentShaderSourceFlipped = VUOSHADER_GLSL_SOURCE(120,
260  \n#include "VuoGlslAlpha.glsl"
261 
262  // Inputs from ports
263  uniform sampler2D texture;
264 
265  // Inputs from vertex/geometry shader
266  varying vec4 fragmentTextureCoordinate;
267 
268  void main()
269  {
270  vec4 color = VuoGlsl_sample(texture, vec2(fragmentTextureCoordinate.x, 1. - fragmentTextureCoordinate.y));
271  VuoGlsl_discardInvisible(color.a);
272  gl_FragColor = color;
273  }
274  );
275 
276  VuoShader shader = VuoShader_make("Image Shader (Unlit, AlphaPassthru)");
277  if (flipped)
278  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSourceFlipped);
279  else
280  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
281  VuoShader_setUniform_VuoImage(shader, "texture", image);
282  return shader;
283 }
284 
293 {
294  if (!image)
295  return NULL;
296 
297  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
298  \n#include "VuoGlslAlpha.glsl"
299 
300  // Inputs
301  uniform sampler2DRect texture;
302  uniform vec2 textureSize;
303  uniform float alpha;
304  varying vec4 fragmentTextureCoordinate;
305 
306  void main()
307  {
308  vec4 color = VuoGlsl_sampleRect(texture, fragmentTextureCoordinate.xy*textureSize);
309  color *= alpha;
310  VuoGlsl_discardInvisible(color.a);
311  gl_FragColor = color;
312  }
313  );
314 
315  VuoShader shader = VuoShader_make("Image Shader (GL_TEXTURE_RECTANGLE)");
316  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
317  VuoShader_setUniform_VuoImage (shader, "texture", image);
318  VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
319  VuoShader_setUniform_VuoPoint2d(shader, "textureSize", VuoPoint2d_make(image->pixelsWide, image->pixelsHigh));
320  return shader;
321 }
322 
334 {
335  if (!image)
336  return NULL;
337 
338  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
339  \n#include "VuoGlslAlpha.glsl"
340 
341  // Inputs
342  uniform sampler2DRect texture;
343  uniform vec2 textureSize;
344  varying vec4 fragmentTextureCoordinate;
345 
346  void main()
347  {
348  vec4 color = VuoGlsl_sampleRect(texture, fragmentTextureCoordinate.xy*textureSize);
349  VuoGlsl_discardInvisible(color.a);
350  gl_FragColor = color;
351  }
352  );
353 
354  const char *fragmentShaderSourceFlipped = VUOSHADER_GLSL_SOURCE(120,
355  \n#include "VuoGlslAlpha.glsl"
356 
357  // Inputs
358  uniform sampler2DRect texture;
359  uniform vec2 textureSize;
360  varying vec4 fragmentTextureCoordinate;
361 
362  void main()
363  {
364  vec4 color = VuoGlsl_sampleRect(texture, vec2(fragmentTextureCoordinate.x, 1. - fragmentTextureCoordinate.y) * textureSize);
365  VuoGlsl_discardInvisible(color.a);
366  gl_FragColor = color;
367  }
368  );
369 
370  VuoShader shader = VuoShader_make("Image Shader (GL_TEXTURE_RECTANGLE, AlphaPassthru)");
371  if (flipped)
372  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSourceFlipped);
373  else
374  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
375  VuoShader_setUniform_VuoImage (shader, "texture", image);
376  VuoShader_setUniform_VuoPoint2d(shader, "textureSize", VuoPoint2d_make(image->pixelsWide, image->pixelsHigh));
377  return shader;
378 }
379 
386 {
387  const char *vertexShaderSource = VUOSHADER_GLSL_SOURCE(120,
388  \n#include "VuoGlslProjection.glsl"
389 
390  // Inputs from VuoSceneRenderer
391  uniform mat4 modelviewMatrix;
392  attribute vec4 position;
393 
394  void main()
395  {
396  gl_Position = VuoGlsl_projectPosition(modelviewMatrix * position);
397  }
398  );
399 
400  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
401  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
402 
403  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
404  // Inputs from ports
405  uniform vec4 color;
406 
407  void main()
408  {
409  gl_FragColor = color;
410  }
411  );
412 
413  const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
414  // Inputs from ports
415  uniform vec4 color;
416 
417  // Inputs from vertex/geometry shader
418  varying vec4 vertexPosition;
419  varying mat3 vertexPlaneToWorld;
420  varying vec4 fragmentTextureCoordinate;
421 
422  void main()
423  {
424  vertexPosition;
425  vertexPlaneToWorld;
426  fragmentTextureCoordinate;
427 
428  gl_FragColor = color;
429  }
430  );
431 
432  VuoShader shader = VuoShader_make("Color Shader (Unlit)");
433 
434  VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
436 
437  VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
439 
440  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, vertexShaderSource, NULL, fragmentShaderSource);
441 
442  VuoShader_setUniform_VuoColor(shader, "color", color);
443 
444  return shader;
445 }
446 
458 {
459  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
460  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
461 
462  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
463  uniform vec4 color;
464  uniform float sharpness;
465  varying vec4 fragmentTextureCoordinate;
466 
467  void main(void)
468  {
469  float dist = distance(fragmentTextureCoordinate.xy, vec2(0.5,0.5));
470  float delta = fwidth(dist);
471  gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness/2 - delta, 1 - sharpness/2 + delta, dist*2));
472  }
473  );
474 
475  VuoShader shader = VuoShader_make("Circle Shader");
476  shader->objectScale = 0.5;
477 
478  VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSource);
480 
481  VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSource);
483 
484  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
485 
486  VuoShader_setUniform_VuoColor(shader, "color", color);
487  VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
488  return shader;
489 }
490 
498 {
499  // The VUOSHADER_GLSL_SOURCE macro gets hung up on the const vec2 (); declaration.
500  const char *fragmentShaderSource = "#version 120 \n\
501 varying vec4 fragmentTextureCoordinate;\
502 uniform vec4 color;\
503 uniform vec4 lineColor;\
504 uniform float thickness;\
505 const int CHECK_VERTICES = 6;\
506 const vec2 CHECK[CHECK_VERTICES] = vec2[] (\
507  vec2(.0, .47),\
508  vec2(.175, .66),\
509  vec2(.37, .46),\
510  vec2(.82, .9),\
511  vec2(1, .72),\
512  vec2(.37, .1)\
513 );\
514 \
515 bool doLineSegmentsIntersect(vec2 p0, vec2 p1, vec2 p2, vec2 p3)\
516 {\
517  vec2 s1 = p1 - p0;\
518  vec2 s2 = p3 - p2;\
519  float s, t;\
520  s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) / (-s2.x * s1.y + s1.x * s2.y);\
521  t = ( s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) / (-s2.x * s1.y + s1.x * s2.y);\
522 \
523  return (s >= 0 && s <= 1 && t >= 0 && t <= 1);\
524 }\
525 \
526 float drawLine(vec2 p1, vec2 p2)\
527 {\
528  vec2 uv = fragmentTextureCoordinate.xy;\
529  float a = abs(distance(p1, uv));\
530  float b = abs(distance(p2, uv));\
531  float c = abs(distance(p1, p2));\
532  if( a >= c || b >= c) return 0.;\
533  float p = (a + b + c) * .5;\
534  float h = 2. / c * sqrt(p * (p-a) * (p-b) * (p-c));\
535  return mix(1, 0, smoothstep(0.5 * thickness, 1.5 * thickness, h));\
536 }\
537 \
538 bool isPointInPolygon(vec2 point)\
539 {\
540  vec2 rayStart = vec2(0, .5);\
541  bool inPoly = false;\
542 \
543  for(int i = 0; i < CHECK_VERTICES; i += 1)\
544  {\
545  if(doLineSegmentsIntersect(rayStart, point, CHECK[i], CHECK[i == (CHECK_VERTICES-1) ? 0 : i+1]) )\
546  inPoly = !inPoly;\
547  }\
548 \
549  return inPoly;\
550 }\
551 \
552 void main(void)\
553 {\
554  float line = 0;\
555  for(int i = 0; i < CHECK_VERTICES; i++)\
556  line = max(drawLine(CHECK[i], CHECK[i < CHECK_VERTICES-1 ? i+1 : 0]), line);\
557  gl_FragColor = mix(isPointInPolygon(fragmentTextureCoordinate.xy) ? color : vec4(0), lineColor, line);\
558 }\
559 ";
560 
561  VuoShader shader = VuoShader_make("Checkmark Shader");
562  shader->objectScale = 1;
563  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
564  VuoShader_setUniform_VuoColor(shader, "color", color);
565  VuoShader_setUniform_VuoColor(shader, "lineColor", outline);
566  VuoShader_setUniform_VuoReal(shader, "thickness", thickness);
567  return shader;
568 }
569 
583 {
584  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
585  uniform vec4 color;
586  uniform float sharpness;
587  uniform float roundness;
588  uniform float aspect;
589  varying vec4 fragmentTextureCoordinate;
590 
591  void main(void)
592  {
593  float roundness2 = max(1. - sharpness, roundness);
594  roundness2 = min(aspect, roundness2);
595  float diameter = roundness2 / 2.;
596  diameter = max(diameter, 0.001);
597  float radius = diameter / 2.;
598  vec2 r = vec2(radius/aspect, radius);
599 
600  vec2 cornerCircleCenter = vec2(0.,0.);
601  if (fragmentTextureCoordinate.x > 0.75 - r.x)
602  {
603  if (fragmentTextureCoordinate.y > 0.75 - r.y)
604  // Top right corner
605  cornerCircleCenter = vec2(0.75, 0.75) + vec2(-r.x, -r.y);
606  else if (fragmentTextureCoordinate.y < 0.25 + r.y)
607  // Bottom right corner
608  cornerCircleCenter = vec2(0.75, 0.25) + vec2(-r.x, r.y);
609  }
610  else if (fragmentTextureCoordinate.x < 0.25 + r.x)
611  {
612  if (fragmentTextureCoordinate.y > 0.75 - r.y)
613  // Top left corner
614  cornerCircleCenter = vec2(0.25, 0.75) + vec2( r.x, -r.y);
615  else if (fragmentTextureCoordinate.y < 0.25 + radius)
616  // Bottom left corner
617  cornerCircleCenter = vec2(0.25, 0.25) + vec2( r.x, r.y);
618  }
619 
620  float dist = 0.;
621  if (cornerCircleCenter.x > 0.)
622  dist = distance((fragmentTextureCoordinate.xy - cornerCircleCenter) * vec2(aspect, 1.) + cornerCircleCenter, cornerCircleCenter) / diameter;
623  else
624  {
625  float f = 1. - (1. - sharpness) * (1. - sharpness);
626  if (aspect < 1.)
627  f = 1./f;
628  float n = (fragmentTextureCoordinate.x - 0.5) * f;
629 
630  if (fragmentTextureCoordinate.y < 0.5 + n)
631  {
632  if (fragmentTextureCoordinate.y > 0.5 - n)
633  // Right edge
634  dist = (fragmentTextureCoordinate.x - (0.75 - r.x)) * aspect;
635  else
636  // Bottom edge
637  dist = (0.25 + r.y) - fragmentTextureCoordinate.y;
638  }
639  else
640  {
641  if (fragmentTextureCoordinate.y > 0.5 - n)
642  // Top edge
643  dist = fragmentTextureCoordinate.y - (0.75 - r.y);
644  else
645  // Left edge
646  dist = ((0.25 + r.x) - fragmentTextureCoordinate.x) * aspect;
647  }
648 
649  dist /= diameter;
650  }
651 
652 // float delta = min(fwidth(fragmentTextureCoordinate.x), fwidth(fragmentTextureCoordinate.y));
653  float delta = fwidth(fragmentTextureCoordinate.y);
654  delta /= diameter;
655  delta /= 2.;
656 
657  gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness / 2. - delta, 1. - sharpness / 2. + delta, dist));
658  }
659  );
660 
661  VuoShader shader = VuoShader_make("Rounded Rectangle Shader");
662  shader->objectScale = 0.5;
663  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
664  VuoShader_setUniform_VuoColor(shader, "color", color);
665  VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
666  VuoShader_setUniform_VuoReal (shader, "roundness", VuoReal_clamp(roundness, 0, 1));
667  VuoShader_setUniform_VuoReal (shader, "aspect", aspect);
668  return shader;
669 }
670 
685  VuoColor backgroundColor,
686  VuoColor activeColor,
687  VuoReal sharpness,
688  VuoReal roundness,
689  VuoReal aspect,
690  VuoBoolean isHorizontal,
691  VuoReal value)
692 {
693  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
694  uniform vec4 backgroundColor;
695  uniform vec4 activeColor;
696  uniform float sharpness;
697  uniform float roundness;
698  uniform float aspect;
699  uniform float progress;
700  uniform bool isHorizontal;
701  varying vec4 fragmentTextureCoordinate;
702 
703  void main(void)
704  {
705  float roundness2 = max(1. - sharpness, roundness);
706  roundness2 = min(aspect, roundness2);
707  float diameter = roundness2 / 2.;
708  diameter = max(diameter, 0.001);
709  float radius = diameter / 2.;
710  vec2 r = vec2(radius/aspect, radius);
711 
712  vec2 cornerCircleCenter = vec2(0.,0.);
713  if (fragmentTextureCoordinate.x > 0.75 - r.x)
714  {
715  if (fragmentTextureCoordinate.y > 0.75 - r.y)
716  // Top right corner
717  cornerCircleCenter = vec2(0.75, 0.75) + vec2(-r.x, -r.y);
718  else if (fragmentTextureCoordinate.y < 0.25 + r.y)
719  // Bottom right corner
720  cornerCircleCenter = vec2(0.75, 0.25) + vec2(-r.x, r.y);
721  }
722  else if (fragmentTextureCoordinate.x < 0.25 + r.x)
723  {
724  if (fragmentTextureCoordinate.y > 0.75 - r.y)
725  // Top left corner
726  cornerCircleCenter = vec2(0.25, 0.75) + vec2( r.x, -r.y);
727  else if (fragmentTextureCoordinate.y < 0.25 + radius)
728  // Bottom left corner
729  cornerCircleCenter = vec2(0.25, 0.25) + vec2( r.x, r.y);
730  }
731 
732  float dist = 0.;
733  if (cornerCircleCenter.x > 0.)
734  dist = distance((fragmentTextureCoordinate.xy - cornerCircleCenter) * vec2(aspect, 1.) + cornerCircleCenter, cornerCircleCenter) / diameter;
735  else
736  {
737  float f = 1. - (1. - sharpness) * (1. - sharpness);
738  if (aspect < 1.)
739  f = 1./f;
740  float n = (fragmentTextureCoordinate.x - 0.5) * f;
741 
742  if (fragmentTextureCoordinate.y < 0.5 + n)
743  {
744  if (fragmentTextureCoordinate.y > 0.5 - n)
745  // Right edge
746  dist = (fragmentTextureCoordinate.x - (0.75 - r.x)) * aspect;
747  else
748  // Bottom edge
749  dist = (0.25 + r.y) - fragmentTextureCoordinate.y;
750  }
751  else
752  {
753  if (fragmentTextureCoordinate.y > 0.5 - n)
754  // Top edge
755  dist = fragmentTextureCoordinate.y - (0.75 - r.y);
756  else
757  // Left edge
758  dist = ((0.25 + r.x) - fragmentTextureCoordinate.x) * aspect;
759  }
760 
761  dist /= diameter;
762  }
763 
764  float delta = fwidth(dist) / 2.;
765 
766  // fwidth() seems to sometimes output invalid results; this hides most of it.
767  if (delta > 0.1)
768  delta = 0.;
769 
770  float val = (isHorizontal ? fragmentTextureCoordinate.x : fragmentTextureCoordinate.y);
771  val = (clamp(val, .25, .75) - .25) / .5;
772  vec4 color = val < progress ? activeColor : backgroundColor;
773  gl_FragColor = mix(color, vec4(0.), smoothstep(sharpness / 2. - delta, 1. - sharpness / 2. + delta, dist));
774  }
775  );
776 
777  VuoShader shader = VuoShader_make("Rounded Rectangle Track Shader");
778  shader->objectScale = 0.5;
779  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
780  VuoShader_setUniform_VuoColor(shader, "backgroundColor", backgroundColor);
781  VuoShader_setUniform_VuoColor(shader, "activeColor", activeColor);
782  VuoShader_setUniform_VuoReal (shader, "sharpness", VuoReal_clamp(sharpness, 0, 1));
783  VuoShader_setUniform_VuoReal (shader, "roundness", VuoReal_clamp(roundness, 0, 1));
784  VuoShader_setUniform_VuoReal (shader, "aspect", aspect);
785  VuoShader_setUniform_VuoBoolean (shader, "isHorizontal", isHorizontal);
786  VuoShader_setUniform_VuoReal (shader, "progress", value);
787  return shader;
788 }
789 
799 VuoShader VuoShader_makeLitColorShader(VuoColor diffuseColor, VuoColor highlightColor, VuoReal shininess)
800 {
801  const char *vertexShaderSource = VUOSHADER_GLSL_SOURCE(120,
802  \n#include "VuoGlslProjection.glsl"
803 
804  // Inputs provided by VuoSceneRenderer
805  uniform mat4 modelviewMatrix;
806  attribute vec4 position;
807  attribute vec4 normal;
808  attribute vec4 tangent;
809  attribute vec4 bitangent;
810 
811  // Outputs to fragment shader
812  varying vec4 vertexPosition;
813  varying mat3 vertexPlaneToWorld;
814  varying vec4 fragmentTextureCoordinate;
815 
816  void main()
817  {
818  fragmentTextureCoordinate;
819 
820  vertexPosition = modelviewMatrix * position;
821 
822  vertexPlaneToWorld[0] = normalize(vec3(modelviewMatrix * vec4(tangent.xyz, 0.)));
823  vertexPlaneToWorld[1] = normalize(vec3(modelviewMatrix * -vec4(bitangent.xyz, 0.)));
824  vertexPlaneToWorld[2] = normalize(vec3(modelviewMatrix * vec4(normal.xyz, 0.)));
825 
826  gl_Position = VuoGlsl_projectPosition(vertexPosition);
827  }
828  );
829 
830  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
831  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
832 
833  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
834  \n#include "lighting.glsl"
835 
836  // Inputs from ports
837  uniform vec4 diffuseColor;
838  uniform vec4 specularColor;
839  uniform float specularPower;
840 
841  // Inputs from vertex/geometry shader
842  varying vec4 fragmentTextureCoordinate;
843 
844  void main()
845  {
846  // Work around ATI Radeon HD 5770 bug.
847  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
848  // https://b33p.net/kosada/node/11256
849  gl_FragColor = diffuseColor;
850 
851  fragmentTextureCoordinate;
852 
853  vec3 ambientContribution = vec3(0.);
854  vec3 diffuseContribution = vec3(0.);
855  vec3 specularContribution = vec3(0.);
856 
857  calculateLighting(specularPower, vec3(0,0,1), ambientContribution, diffuseContribution, specularContribution);
858 
859  ambientContribution *= diffuseColor.rgb;
860  diffuseContribution *= diffuseColor.rgb;
861  specularContribution *= specularColor.rgb * specularColor.a;
862  gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, diffuseColor.a);
863  }
864  );
865 
866  VuoShader shader = VuoShader_make("Color Shader (Lit)");
867 
868  VuoShader_addSource (shader, VuoMesh_Points, defaultVertexShaderSourceForGeometryShader, pointGeometryShaderSource, fragmentShaderSource);
870 
871  VuoShader_addSource (shader, VuoMesh_IndividualLines, defaultVertexShaderSourceForGeometryShader, lineGeometryShaderSource, fragmentShaderSource);
873 
874  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, vertexShaderSource, NULL, fragmentShaderSource);
875 
876  VuoShader_setUniform_VuoColor(shader, "diffuseColor", diffuseColor);
877  VuoShader_setUniform_VuoColor(shader, "specularColor", highlightColor);
878  VuoShader_setUniform_VuoReal (shader, "specularPower", 1./(1.0001-shininess));
879  return shader;
880 }
881 
887  \n#include "VuoGlslProjection.glsl"
888 
889  // Inputs provided by VuoSceneRenderer
890  uniform mat4 modelviewMatrix;
891  attribute vec4 position;
892  attribute vec4 normal;
893  attribute vec4 tangent;
894  attribute vec4 bitangent;
895  attribute vec4 textureCoordinate;
896 
897  // Outputs to fragment shader
898  varying vec4 vertexPosition;
899  varying vec4 fragmentTextureCoordinate;
900  varying mat3 vertexPlaneToWorld;
901 
902  void main()
903  {
904  vertexPosition = modelviewMatrix * position;
905 
906  fragmentTextureCoordinate = textureCoordinate;
907 
908  vertexPlaneToWorld[0] = normalize(vec3(modelviewMatrix * vec4(tangent.xyz,0.)));
909  vertexPlaneToWorld[1] = normalize(vec3(modelviewMatrix * -vec4(bitangent.xyz,0.)));
910  vertexPlaneToWorld[2] = normalize(vec3(modelviewMatrix * vec4(normal.xyz,0.)));
911 
912  gl_Position = VuoGlsl_projectPosition(vertexPosition);
913  }
914 );
915 
921  \n#include "VuoGlslProjection.glsl"
922 
923  // Inputs provided by VuoSceneRenderer
924  uniform mat4 modelviewMatrix;
925  attribute vec4 position;
926  attribute vec4 normal;
927  attribute vec4 tangent;
928  attribute vec4 bitangent;
929  attribute vec4 textureCoordinate;
930 
931  // Outputs to geometry shader
932  varying vec4 positionForGeometry;
933  varying vec4 textureCoordinateForGeometry;
934 
935  void main()
936  {
937  positionForGeometry = modelviewMatrix * position;
938  textureCoordinateForGeometry = textureCoordinate;
939  gl_Position = VuoGlsl_projectPosition(positionForGeometry);
940  }
941 );
942 
953 VuoShader VuoShader_makeLitImageShader(VuoImage image, VuoReal alpha, VuoColor highlightColor, VuoReal shininess)
954 {
955  if (!image)
956  return NULL;
957 
958  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
959  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
960 
961  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
962  \n#include "VuoGlslAlpha.glsl"
963  \n#include "lighting.glsl"
964 
965  // Inputs from vertex shader
966  varying vec4 fragmentTextureCoordinate;
967 
968  // Inputs from ports
969  uniform sampler2D texture;
970  uniform float alpha;
971  uniform vec4 specularColor;
972  uniform float specularPower;
973 
974  void main()
975  {
976  // Work around ATI Radeon HD 5770 bug.
977  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
978  // https://b33p.net/kosada/node/11256
979  gl_FragColor = specularColor;
980 
981  vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate.xy);
982  color *= alpha;
983  VuoGlsl_discardInvisible(color.a);
984 
985  vec3 ambientContribution = vec3(0.);
986  vec3 diffuseContribution = vec3(0.);
987  vec3 specularContribution = vec3(0.);
988 
989  calculateLighting(specularPower, vec3(0,0,1), ambientContribution, diffuseContribution, specularContribution);
990 
991  ambientContribution *= color.rgb;
992  diffuseContribution *= color.rgb;
993  specularContribution *= specularColor.rgb * specularColor.a;
994  gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, color.a);
995  }
996  );
997 
998  VuoShader shader = VuoShader_make("Image Shader (Lit)");
999 
1000  VuoShader_addSource (shader, VuoMesh_Points, lightingVertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSource);
1002 
1003  VuoShader_addSource (shader, VuoMesh_IndividualLines, lightingVertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSource);
1005 
1006  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, lightingVertexShaderSource, NULL, fragmentShaderSource);
1007 
1008  VuoShader_setUniform_VuoImage(shader, "texture", image);
1009  VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
1010  VuoShader_setUniform_VuoColor(shader, "specularColor", highlightColor);
1011  VuoShader_setUniform_VuoReal (shader, "specularPower", 1./(1.0001-shininess));
1012 
1013  return shader;
1014 }
1015 
1027 {
1028  if (!image || !specularImage || !normalImage)
1029  return NULL;
1030 
1031  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
1032  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
1033 
1034  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1035  \n#include "VuoGlslAlpha.glsl"
1036  \n#include "lighting.glsl"
1037 
1038  // Inputs from vertex shader
1039  varying vec4 fragmentTextureCoordinate;
1040 
1041  // Inputs from ports
1042  uniform sampler2D texture;
1043  uniform float alpha;
1044  uniform sampler2D specularImage;
1045  uniform sampler2D normalImage;
1046  uniform vec4 blah;
1047 
1048  void main()
1049  {
1050  // Work around ATI Radeon HD 5770 bug.
1051  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
1052  // https://b33p.net/kosada/node/11256
1053  gl_FragColor = blah;
1054 
1055  vec4 color = VuoGlsl_sample(texture, fragmentTextureCoordinate.xy);
1056  color *= alpha;
1057  VuoGlsl_discardInvisible(color.a);
1058 
1059  vec3 ambientContribution = vec3(0.);
1060  vec3 diffuseContribution = vec3(0.);
1061  vec3 specularContribution = vec3(0.);
1062 
1063  vec4 specularColor = texture2D(specularImage, fragmentTextureCoordinate.xy);
1064  float specularPower = 1./(1.0001-specularColor.a);
1065 
1066  vec4 normalColor = texture2D(normalImage, fragmentTextureCoordinate.xy);
1067  vec3 normal = normalize(vec3(
1068  2. * normalColor.r - 1.,
1069  2. * normalColor.g - 1.,
1070  normalColor.b // Leave the blue channel as-is; the normal should never point inward.
1071  ));
1072 
1073  calculateLighting(specularPower, normal, ambientContribution, diffuseContribution, specularContribution);
1074 
1075  ambientContribution *= color.rgb;
1076  diffuseContribution *= color.rgb;
1077  specularContribution *= specularColor.rgb * specularColor.a;
1078  gl_FragColor = vec4(ambientContribution + diffuseContribution + specularContribution, color.a);
1079  }
1080  );
1081 
1082  VuoShader shader = VuoShader_make("Image Details Shader (Lit)");
1083 
1084  VuoShader_addSource (shader, VuoMesh_Points, lightingVertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSource);
1086 
1087  VuoShader_addSource (shader, VuoMesh_IndividualLines, lightingVertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSource);
1089 
1090  VuoShader_addSource (shader, VuoMesh_IndividualTriangles, lightingVertexShaderSource, NULL, fragmentShaderSource);
1091 
1092  VuoShader_setUniform_VuoImage(shader, "texture", image);
1093  VuoShader_setUniform_VuoReal (shader, "alpha", alpha);
1094  VuoShader_setUniform_VuoImage(shader, "specularImage", specularImage);
1095  VuoShader_setUniform_VuoImage(shader, "normalImage", normalImage);
1096  VuoShader_setUniform_VuoColor(shader, "blah", VuoColor_makeWithRGBA(42,42,42,42));
1097 
1098  return shader;
1099 }
1100 
1107 {
1108  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1109  \n#include "VuoGlslAlpha.glsl"
1110  \n#include "VuoGlslRandom.glsl"
1111 
1112  uniform float inputColorCount;
1113  uniform float stripColorCount;
1114  uniform sampler2D gradientStrip;
1115  uniform vec2 start;
1116  uniform vec2 end;
1117  uniform float aspect;
1118  uniform float noiseAmount;
1119 
1120  varying vec4 fragmentTextureCoordinate;
1121 
1122  float distSqr(vec2 a, vec2 b)
1123  {
1124  return (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y);
1125  }
1126 
1127  // https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
1128  // ...minus the segment part, of course.
1129  vec2 nearest_point_on_line(vec2 v, vec2 w, vec2 p)
1130  {
1131  // Return minimum distance between line segment vw and point p
1132  float l2 = distSqr(v, w); // i.e. |w-v|^2 - avoid a sqrt
1133  if (l2 == 0.0) return p;
1134  // Consider the line extending the segment, parameterized as v + t (w - v).
1135  // We find projection of point p onto the line.
1136  // It falls where t = [(p-v) . (w-v)] / |w-v|^2
1137  float t = dot(p - v, w - v) / l2;
1138  vec2 projection = v + t * (w - v);
1139  return projection;
1140  }
1141 
1142  void main(void)
1143  {
1144  vec2 tcAspect = fragmentTextureCoordinate.xy;
1145  tcAspect.y -= .5;
1146  tcAspect.y *= aspect;
1147  tcAspect.y += .5;
1148 
1149  vec2 pol = nearest_point_on_line(start, end, tcAspect);
1150  float x = dot(pol-start, end-start) > 0 ? distance(start, pol)/ distance(start, end) : 0;
1151 
1152  // Give x a smooth second-derivative, to reduce the ridges between colors.
1153  x *= inputColorCount - 1.;
1154  x = floor(x) + smoothstep(0.,1.,fract(x));
1155  x /= inputColorCount - 1.;
1156 
1157  float gradientWidth = (1./stripColorCount)/2.;
1158  x = x * (1-gradientWidth*2) + gradientWidth; // scale to account for the gradient/2 offsets
1159 
1160  vec4 color = VuoGlsl_sample(gradientStrip, vec2(clamp(x , gradientWidth, 1.-gradientWidth), .5));
1161  VuoGlsl_discardInvisible(color.a);
1162 
1163  color.rgb += (VuoGlsl_random2D3D(fragmentTextureCoordinate.xy) - 0.5) * noiseAmount;
1164 
1165  gl_FragColor = color;
1166  }
1167  );
1168 
1169  VuoShader shader = VuoShader_make("Linear Gradient Shader");
1170  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1171  return shader;
1172 }
1173 
1178 {
1179  // https://b33p.net/kosada/node/12582
1180  // Instead of creating an image with only one pixel per color stop,
1181  // create `gradientExpansion` pixels per stop, to compensate for GPUs
1182  // that have limited ability to interpolate between pixels.
1183  // E.g., the Intel HD Graphics 3000 GPU limits interpolation to 64 steps.
1184  // On Intel 3000, gradientExpansion=4 would result in 256 steps (64*4);
1185  // go beyond that to provide some extra detail when rendering to 16bpc textures.
1186  int gradientExpansion = 16;
1187 
1188  GLenum format = GL_BGRA;
1189  int bpp = 4;
1190  if (VuoColor_areAllOpaque(colors))
1191  {
1192  format = GL_BGR;
1193  bpp = 3;
1194  }
1195 
1196  int inputColorCount = VuoListGetCount_VuoColor(colors);
1197  int stripColorCount = (inputColorCount - 1) * gradientExpansion + 1;
1198 
1199  unsigned char *pixels = (unsigned char*)malloc(stripColorCount * bpp);
1200  int inputColor = 1;
1201  int step = 0;
1202  for (int i = 0; i < stripColorCount; ++i)
1203  {
1204  VuoColor col1 = VuoListGetValue_VuoColor(colors, inputColor);
1205  VuoColor col2 = VuoListGetValue_VuoColor(colors, inputColor+1);
1206 
1207  VuoColor col = VuoColor_lerp(col1, col2, (float)step / gradientExpansion);
1208 
1209  pixels[i * bpp ] = VuoInteger_clamp(col.a * col.b * 255, 0, 255);
1210  pixels[i * bpp + 1 ] = VuoInteger_clamp(col.a * col.g * 255, 0, 255);
1211  pixels[i * bpp + 2 ] = VuoInteger_clamp(col.a * col.r * 255, 0, 255);
1212  if (bpp == 4)
1213  pixels[i * bpp + 3] = VuoInteger_clamp(col.a * 255, 0, 255);
1214 
1215  ++step;
1216  if (step >= gradientExpansion)
1217  {
1218  step = 0;
1219  ++inputColor;
1220  }
1221  }
1222 
1223  VuoImage gradientStrip = VuoImage_makeFromBuffer(pixels, format, stripColorCount, 1, VuoImageColorDepth_8, ^(void *buffer){ free(buffer); });
1224 
1225  VuoShader_setUniform_VuoImage (shader, "gradientStrip", gradientStrip);
1226  VuoShader_setUniform_VuoReal (shader, "inputColorCount", inputColorCount);
1227  VuoShader_setUniform_VuoReal (shader, "stripColorCount", stripColorCount);
1228 }
1229 
1234 void VuoShader_setLinearGradientShaderValues(VuoShader shader, VuoList_VuoColor colors, VuoPoint2d start, VuoPoint2d end, VuoReal aspect, VuoReal noiseAmount)
1235 {
1236  VuoShader_setGradientStrip(shader, colors);
1237  VuoShader_setUniform_VuoPoint2d(shader, "start", VuoPoint2d_make((start.x+1)/2, (start.y+1)/2));
1238  VuoShader_setUniform_VuoPoint2d(shader, "end", VuoPoint2d_make((end.x+1)/2, (end.y+1)/2));
1239  VuoShader_setUniform_VuoReal (shader, "aspect", 1./aspect);
1240  VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1241 }
1242 
1249 {
1250  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1251  \n#include "VuoGlslAlpha.glsl"
1252  \n#include "VuoGlslRandom.glsl"
1253 
1254  uniform float inputColorCount;
1255  uniform float stripColorCount;
1256  uniform sampler2D gradientStrip;
1257  uniform vec2 center;
1258  uniform vec2 scale; // if image is not square, multiply texCoord by this to account for stretch
1259  uniform float radius;
1260  uniform float noiseAmount;
1261 
1262  varying vec4 fragmentTextureCoordinate;
1263 
1264  void main(void)
1265  {
1266  vec2 scaledTexCoord = fragmentTextureCoordinate.xy*scale;
1267  float x = distance(center*scale, scaledTexCoord)/radius;
1268 
1269  // Give x a smooth second-derivative, to reduce the ridges between colors.
1270  x *= inputColorCount - 1.;
1271  x = floor(x) + smoothstep(0.,1.,fract(x));
1272  x /= inputColorCount - 1.;
1273 
1274  float gradientWidth = (1./stripColorCount)/2.;
1275  x = x * (1-gradientWidth*2) + gradientWidth;
1276 
1277  vec4 color = VuoGlsl_sample(gradientStrip, vec2(clamp(x , gradientWidth, 1.-gradientWidth), .5));
1278  VuoGlsl_discardInvisible(color.a);
1279 
1280  color.rgb += (VuoGlsl_random2D3D(fragmentTextureCoordinate.xy) - 0.5) * noiseAmount;
1281 
1282  gl_FragColor = color;
1283  }
1284  );
1285 
1286  VuoShader shader = VuoShader_make("Radial Gradient Shader");
1287  VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1288  return shader;
1289 }
1290 
1296 void VuoShader_setRadialGradientShaderValues(VuoShader shader, VuoList_VuoColor colors, VuoPoint2d center, VuoReal radius, VuoReal width, VuoReal height, VuoReal noiseAmount)
1297 {
1298  // VuoPoint2d scale = width < height ? VuoPoint2d_make(1., height/(float)width) : VuoPoint2d_make(width/(float)height, 1.);
1299  VuoPoint2d scale = VuoPoint2d_make(1., height/(float)width);
1300 
1301  VuoShader_setGradientStrip(shader, colors);
1302  VuoShader_setUniform_VuoPoint2d(shader, "center", VuoPoint2d_make((center.x+1)/2, (center.y+1)/2));
1303  VuoShader_setUniform_VuoReal (shader, "radius", radius > 0. ? radius/2. : 0);
1304  VuoShader_setUniform_VuoPoint2d(shader, "scale", VuoPoint2d_make(scale.x, scale.y));
1305  VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1306 }
1307 
1312 {
1313  const char *vertexShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
1314  \n#include "VuoGlslProjection.glsl"
1315 
1316  // Inputs provided by VuoSceneRenderer
1317  uniform mat4 modelviewMatrix;
1318  attribute vec4 position;
1319  attribute vec4 normal;
1320  attribute vec4 textureCoordinate;
1321 
1322  // Outputs to geometry shader
1323  varying vec4 positionForGeometry;
1324  varying vec4 textureCoordinateForGeometry;
1325 
1326  void main()
1327  {
1328  positionForGeometry = modelviewMatrix * position;
1329  textureCoordinateForGeometry = textureCoordinate;
1330  gl_Position = VuoGlsl_projectPosition(positionForGeometry);
1331  }
1332  );
1333 
1334  const char *pointGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "trianglePoint.glsl");
1335  const char *lineGeometryShaderSource = VUOSHADER_GLSL_SOURCE(120, \n#include "triangleLine.glsl");
1336 
1337  const char *fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
1338  \n#include "VuoGlslAlpha.glsl"
1339  \n#include "noise3D.glsl"
1340 
1341  // Inputs provided by VuoSceneRenderer
1342  uniform sampler2D colorBuffer;
1343  uniform vec2 viewportSize;
1344 
1345  // Inputs from ports
1346  uniform vec4 color;
1347  uniform float aspectRatio;
1348  uniform vec2 noisePosition;
1349  uniform float noiseTime;
1350  uniform float noiseAmount;
1351  uniform float noiseScale;
1352  uniform float chromaticAberration;
1353  uniform int iterations;
1354  uniform int levels;
1355  uniform float roughness;
1356  uniform float spacing;
1357 
1358  // Inputs from vertex shader
1359  varying vec4 fragmentTextureCoordinate;
1360 
1361  void main()
1362  {
1363  vec2 viewportTextureCoordinate = gl_FragCoord.xy/viewportSize;
1364 
1365  vec4 accumulatedColor = vec4(0.);
1366  for (int i = 0; i < iterations; ++i)
1367  {
1368  // 3D noise, since we want a continuous 2D texture that moves continuously through time.
1369  // The iteration index needn't be continuous.
1370  vec3 noiseCoordinate = vec3(fragmentTextureCoordinate.x - .5 - noisePosition.x + float(i), (fragmentTextureCoordinate.y - .5 - noisePosition.y) / aspectRatio, noiseTime);
1371  noiseCoordinate.xy *= noiseScale;
1372  vec2 noiseOffset = snoise3D2DFractal(noiseCoordinate, levels, roughness, spacing);
1373 
1374  // Red
1375  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. - chromaticAberration/3.)) * vec4(1.,0.,0.,1./3.);
1376 
1377  // Green
1378  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount) * vec4(0.,1.,0.,1./3.);
1379 
1380  // Blue
1381  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. + chromaticAberration/3.)) * vec4(0.,0.,1.,1./3.);
1382  }
1383 
1384  vec4 c = accumulatedColor / float(iterations);
1385  c.rgb /= c.a;
1386  c *= color;
1387  c.rgb = clamp(c.rgb, 0., 1.);
1388  c.rgb *= c.a;
1389  gl_FragColor = c;
1390  }
1391  );
1392 
1393  const char *fragmentShaderSourceForGeometry = VUOSHADER_GLSL_SOURCE(120,
1394  \n#include "VuoGlslAlpha.glsl"
1395  \n#include "noise3D.glsl"
1396 
1397  // Inputs provided by VuoSceneRenderer
1398  uniform sampler2D colorBuffer;
1399  uniform vec2 viewportSize;
1400 
1401  // Inputs from ports
1402  uniform vec4 color;
1403  uniform float aspectRatio;
1404  uniform vec2 noisePosition;
1405  uniform float noiseTime;
1406  uniform float noiseAmount;
1407  uniform float noiseScale;
1408  uniform float chromaticAberration;
1409  uniform int iterations;
1410  uniform int levels;
1411  uniform float roughness;
1412  uniform float spacing;
1413 
1414  // Inputs from geometry shader
1415  varying vec4 vertexPosition;
1416  varying mat3 vertexPlaneToWorld;
1417  varying vec4 fragmentTextureCoordinate;
1418 
1419  void main()
1420  {
1421  // Work around ATI Radeon HD 5770 bug.
1422  // It seems that the rest of the shader isn't executed unless we initialize the output with a uniform.
1423  // https://b33p.net/kosada/node/11256
1424  gl_FragColor = color;
1425 
1426  vertexPosition;
1427  vertexPlaneToWorld;
1428 
1429  vec2 viewportTextureCoordinate = gl_FragCoord.xy/viewportSize;
1430 
1431  vec4 accumulatedColor = vec4(0.);
1432  for (int i = 0; i < iterations; ++i)
1433  {
1434  // 3D noise, since we want a continuous 2D texture that moves continuously through time.
1435  // The iteration index needn't be continuous.
1436  vec3 noiseCoordinate = vec3(fragmentTextureCoordinate.x - .5 - noisePosition.x + float(i), (fragmentTextureCoordinate.y - .5 - noisePosition.y) / aspectRatio, noiseTime);
1437  noiseCoordinate.xy *= noiseScale
1438  vec2 noiseOffset = snoise3D2DFractal(noiseCoordinate, levels, roughness, spacing);
1439 
1440  // Red
1441  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. - chromaticAberration/3.)) * vec4(1.,0.,0.,1./3.);
1442 
1443  // Green
1444  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount) * vec4(0.,1.,0.,1./3.);
1445 
1446  // Blue
1447  accumulatedColor += VuoGlsl_sample(colorBuffer, viewportTextureCoordinate + noiseOffset * noiseAmount * (1. + chromaticAberration/3.)) * vec4(0.,0.,1.,1./3.);
1448  }
1449 
1450  vec4 c = accumulatedColor / float(iterations);
1451  c.rgb /= c.a;
1452  c *= color;
1453  c.rgb = clamp(c.rgb, 0., 1.);
1454  c.rgb *= c.a;
1455  gl_FragColor = c;
1456  }
1457  );
1458 
1459  VuoShader s = VuoShader_make("Frosted Glass Shader");
1460  s->isTransparent = true;
1461 
1462  VuoShader_addSource (s, VuoMesh_Points, vertexShaderSourceForGeometry, pointGeometryShaderSource, fragmentShaderSourceForGeometry);
1464 
1465  VuoShader_addSource (s, VuoMesh_IndividualLines, vertexShaderSourceForGeometry, lineGeometryShaderSource, fragmentShaderSourceForGeometry);
1467 
1468  VuoShader_addSource (s, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
1469 
1470  return s;
1471 }
1472 
1478 void 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)
1479 {
1480  VuoShader_setUniform_VuoPoint4d(shader, "color", VuoPoint4d_make(color.r*brightness, color.g*brightness, color.b*brightness, color.a));
1481  VuoShader_setUniform_VuoPoint2d(shader, "noisePosition", (VuoPoint2d){(noisePosition.x+1)/2,
1482  (noisePosition.y+1)/2 * aspectRatio});
1483  VuoShader_setUniform_VuoReal (shader, "noiseTime", noiseTime);
1484  VuoShader_setUniform_VuoReal (shader, "noiseAmount", MAX(0.,noiseAmount/10.));
1485  VuoShader_setUniform_VuoReal (shader, "noiseScale", 1./VuoReal_makeNonzero(noiseScale));
1486  VuoShader_setUniform_VuoReal (shader, "chromaticAberration", VuoReal_clamp(chromaticAberration, 0, 2));
1487  VuoShader_setUniform_VuoInteger(shader, "iterations", MAX(1, iterations));
1488  VuoShader_setUniform_VuoInteger(shader, "levels", MAX(1, levels));
1489  VuoShader_setUniform_VuoReal (shader, "roughness", roughness);
1490  VuoShader_setUniform_VuoReal (shader, "spacing", spacing);
1491 }