Shaders
#
Son programas que se ejecutan en la GPU encargada de definir el color de los pixeles. Existen 3 tipos de shaders:
- Vertex shader: se ejecutan por cada vértice del elemento que se quiere renderizar. Retornan la posición del vértice deseada.
- Fragment Shader: se ejecutan por cada fragmento visible de la imagen. Retornan el color de cada pixel.
- Geometry shader (opcional): se ejecutan por cada cara del modelo que se desea renderizar, pueden crear nuevos vertices.
En OpenGL y OpenGL ES los shaders están escritos en GLSL.

P5 Nativo
#
Con la funcion LoadShader() se carga el vertex shader y fragment shader. Posteriormente con la funcion shader() se aplicar el shader.
Los shaders solo se pueden utilizar en el modo WEBGL
Tomado de p5.loadShader()
Script p5 mandelbrot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| let mandel;
function preload() {
// load the shader definitions from files
mandel = loadShader('/showcase/sketches/mandelbrot/shaders/shader.vert', '/showcase/sketches/mandelbrot/shaders/shader.frag');
}
function setup() {
createCanvas(725, 725, WEBGL);
// use the shader
shader(mandel);
noStroke();
mandel.setUniform('p', [-0.74364388703, 0.13182590421]);
describe('zooming Mandelbrot set. a colorful, infinitely detailed fractal.');
}
function draw() {
mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));
quad(-1, -1, 1, -1, 1, 1, -1, 1);
}
|
Vertex shader shader.vert
1
2
3
4
5
6
| precision highp float;
varying vec2 vPos;
attribute vec3 aPosition;
void main() {
vPos = (gl_Position = vec4(aPosition, 1.0)).xy;
}
|
Fragment shader shader.frag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| precision highp float;
varying vec2 vPos;
uniform vec2 p;
uniform float r;
const int I = 500;
void main() {
vec2 c = p + vPos * r, z = c;
float n = 0.0;
for(int i = I; i > 0; i--) {
if(z.x * z.x + z.y * z.y > 4.0) {
n = float(i) / float(I);
break;
}
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
}
gl_FragColor = vec4(0.5 - cos(n * 17.0) / 2.0, 0.5 - cos(n * 13.0) / 2.0, 0.5 - cos(n * 23.0) / 2.0, 1.0);
}
|
Setup Treegl
#
Con la función readShader() se especifica el fragment shader que se desea cargar y los parametros para generar el vertexShader, como las matrices de vista, modelo, perspectiva y varyings como position2, position3, textCoords.
Script p5 setupTreegl.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| let testShader;
let slider;
function preload() {
// Load shader with position2 varying
const params = {
precision: Tree.highp,
matrices: Tree.NONE,
varyings: Tree.position2
}
testShader = readShader('/showcase/sketches/mandelbulb/shader/setupTreegl/setup.frag', params);
}
function setup() {
let canvas = createCanvas(725, 725, WEBGL);
// Disable page scrolling when mouse over canvas
parent.disableScroll(canvas.canvas);
shader(testShader);
slider = createSlider(0, 255, 100);
slider.position(10, 10);
}
function draw() {
background(0);
testShader.setUniform('b', slider.value() / 255);
quad(-1, -1, 1, -1, 1, 1, -1, 1);
}
|
Fragment shader setup.frag
1
2
3
4
5
6
7
8
9
10
| precision highp float;
varying vec2 position2;
uniform float b;
void main() {
vec2 pos = (position2 + 1.) / 2.;
gl_FragColor = vec4(vec3(pos, b), 1.);
}
|
Referencias
#