Using a shader as a texture
PShader fx;
PShape cube;
PGraphics tex;
void setup() {
size(640, 360, P3D);
tex = createGraphics(200, 200, P3D);
fx = loadShader("frag.glsl");
tex.beginDraw();
tex.shader(fx);
tex.noStroke();
tex.rect(0, 0, tex.width, tex.height);
tex.endDraw();
cube = makeCube();
cube.setTexture(tex);
fill(255);
noStroke();
}
// We need a 3D model, ideally with UV coordinates for the shader texture.
// In this case we create a 3D cube, but we could replace this function just by
// loadShape() to load a 3D model from disk.
PShape makeCube() {
PShape s = createShape();
s.beginShape(QUADS);
// +Z "front" face
s.vertex(-1, -1, 1, 0, 0);
s.vertex( 1, -1, 1, 1, 0);
s.vertex( 1, 1, 1, 1, 1);
s.vertex(-1, 1, 1, 0, 1);
// -Z "back" face
s.vertex( 1, -1, -1, 0, 0);
s.vertex(-1, -1, -1, 1, 0);
s.vertex(-1, 1, -1, 1, 1);
s.vertex( 1, 1, -1, 0, 1);
// +Y "bottom" face
s.vertex(-1, 1, 1, 0, 0);
s.vertex( 1, 1, 1, 1, 0);
s.vertex( 1, 1, -1, 1, 1);
s.vertex(-1, 1, -1, 0, 1);
// -Y "top" face
s.vertex(-1, -1, -1, 0, 0);
s.vertex( 1, -1, -1, 1, 0);
s.vertex( 1, -1, 1, 1, 1);
s.vertex(-1, -1, 1, 0, 1);
// +X "right" face
s.vertex( 1, -1, 1, 0, 0);
s.vertex( 1, -1, -1, 1, 0);
s.vertex( 1, 1, -1, 1, 1);
s.vertex( 1, 1, 1, 0, 1);
// -X "left" face
s.vertex(-1, -1, -1, 0, 0);
s.vertex(-1, -1, 1, 1, 0);
s.vertex(-1, 1, 1, 1, 1);
s.vertex(-1, 1, -1, 0, 1);
s.endShape();
s.setStroke(false);
s.setTextureMode(NORMAL);
return s;
}
void draw() {
// the shader has a uniform called time
// to make change on every frame, otherwise we might
// as well just use an image loaded from disk instead of a shader :)
fx.set("time", millis()*0.01);
tex.beginDraw();
tex.rect(0, 0, tex.width, tex.height);
tex.endDraw();
// notice that for the tex pgraphics we just draw a rectangle
// covering it. The colors of that rectangle come from the shader.
background(255);
translate(width/2, height/2, -100);
rotateX(millis() * 0.001);
rotateY(millis() * 0.0005);
scale(90);
shape(cube);
}
A simple shader doing some rgb wavy nonsense
// frag.glsl
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform float time;
void main() {
vec2 p = (gl_FragCoord.xy - 100.0) * 0.03;
float r = 0.5 + 0.5 * sin(p.x * p.y * 1.1 + time);
float g = 0.5 + 0.5 * sin(p.x * p.y * 1.2 + time);
float b = 0.5 + 0.5 * sin(p.x * p.y * 1.3 + time);
gl_FragColor = vec4(r, g, b, 1.0);
}