Adding the shader examples

This commit is contained in:
Casey Reas
2012-08-31 17:13:27 +00:00
parent 8b1e862c35
commit 86d96c363d
25 changed files with 1128 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
// Bad-print shader. Adapted from rom Fluxus Shader Library:
// http://www.pawfal.org/index.php?page=FluxusHardwareShaderLibrary
import controlP5.*;
ControlP5 controlP5;
PShader badPrint;
boolean enabled = true;
float scaleR = 1.0, scaleG = 1.0, scaleB = 1.0;
float offsetR = 0.2, offsetG = 0.2, offsetB = 0.2;
float registerR = 0.2, registerG = 0.2, registerB = 0.2;
float sizeR = 0.1, sizeG = 0.2, sizeB = 0.1;
public void setup() {
size(800, 800, P3D);
noStroke();
fill(204);
badPrint = loadShader("BadPrintFrag.glsl", "BadPrintVert.glsl");
sphereDetail(60);
controlP5 = new ControlP5(this);
controlP5.addToggle("enabled").linebreak();
controlP5.addSlider("scaleR", 0, 1);
controlP5.addSlider("scaleG", 0, 1);
controlP5.addSlider("scaleB", 0, 1).linebreak();
controlP5.addSlider("offsetR", 0, 1);
controlP5.addSlider("offsetG", 0, 1);
controlP5.addSlider("offsetB", 0, 1).linebreak();
controlP5.addSlider("registerR", 0, 1);
controlP5.addSlider("registerG", 0, 1);
controlP5.addSlider("registerB", 0, 1).linebreak();
controlP5.addSlider("sizeR", 0, 1);
controlP5.addSlider("sizeG", 0, 1);
controlP5.addSlider("sizeB", 0, 1).linebreak();
}
public void draw() {
background(0);
if (enabled) {
shader(badPrint);
badPrint.set("Scale", scaleR, scaleG, scaleB);
badPrint.set("Offset", offsetR, offsetG, offsetB);
badPrint.set("Register", registerR, registerG, registerB);
badPrint.set("Size", sizeR, sizeG, sizeB);
} else {
resetShader();
}
noStroke();
pointLight(204, 204, 204, 1000, 1000, 1000);
pushMatrix();
translate(width/2, height/2);
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
sphere(200);
popMatrix();
hint(DISABLE_DEPTH_TEST);
noLights();
resetShader();
controlP5.draw();
hint(ENABLE_DEPTH_TEST);
}

View File

@@ -0,0 +1,41 @@
// Copyright (C) 2007 Dave Griffiths
// Licence: GPLv2 (see COPYING)
// Fluxus Shader Library
// ---------------------
// BadPrint NPR Shader
// This shader tries to emulate the effect
// of a bad printing process. Can be controlled
// with different settings for RGB
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform vec3 Scale;
uniform vec3 Offset;
uniform vec3 Register;
uniform vec3 Size;
varying vec3 N;
varying vec3 P;
varying vec4 S;
varying vec3 L;
void main() {
vec3 l = normalize(L);
vec3 n = normalize(N);
vec2 p = S.xy;
vec2 sr = p * Size.r + Register.r;
vec2 sg = p * Size.g + Register.g;
vec2 sb = p * Size.b + Register.b;
float diffuse = dot(l,n);
float r = (sin(sr.x) + cos(sr.y)) * Scale.r + Offset.r + diffuse;
float g = (sin(sg.x) + cos(sg.y)) * Scale.g + Offset.g + diffuse;
float b = (sin(sb.x) + cos(sb.y)) * Scale.b + Offset.b + diffuse;
gl_FragColor = vec4(step(0.5, r), step(0.5, g), step(0.5, b), 1);
}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2007 Dave Griffiths
// Licence: GPLv2 (see COPYING)
// Fluxus Shader Library
// ---------------------
// BadPrint NPR Shader
// This shader tries to emulate the effect
// of a bad printing process. Can be controlled
// with different settings for RGB
uniform mat4 projectionMatrix;
uniform mat4 projmodelviewMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition[8];
attribute vec4 inVertex;
attribute vec3 inNormal;
varying vec3 N;
varying vec3 P;
varying vec4 S;
varying vec3 L;
void main() {
N = normalize(normalMatrix * inNormal);
P = inVertex.xyz;
gl_Position = projmodelviewMatrix * inVertex;
L = vec3(lightPosition[0] - gl_Position);
S = projectionMatrix * gl_Position;
}

View File

@@ -0,0 +1,24 @@
/**
* Blur Filter
*
* Change the default shader to apply a simple, custom blur filter.
*
* Press the mouse to switch between the custom and default shader.
*/
PShader blur;
void setup() {
size(640, 360, P2D);
blur = loadShader("blur.glsl");
stroke(255, 0, 0);
}
void draw() {
filter(blur);
rect(mouseX, mouseY, 150, 150);
line(mouseX, mouseY, mouseX+150, mouseY+150);
}

View File

@@ -0,0 +1,48 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
#define KERNEL_SIZE 9
// Gaussian kernel
// 1 2 1
// 2 4 2
// 1 2 1
float kernel[KERNEL_SIZE];
vec2 offset[KERNEL_SIZE];
void main(void) {
int i = 0;
vec4 sum = vec4(0.0);
offset[0] = vec2(-texcoordOffset.s, -texcoordOffset.t);
offset[1] = vec2(0.0, -texcoordOffset.t);
offset[2] = vec2(texcoordOffset.s, -texcoordOffset.t);
offset[3] = vec2(-texcoordOffset.s, 0.0);
offset[4] = vec2(0.0, 0.0);
offset[5] = vec2(texcoordOffset.s, 0.0);
offset[6] = vec2(-texcoordOffset.s, texcoordOffset.t);
offset[7] = vec2(0.0, texcoordOffset.t);
offset[8] = vec2(texcoordOffset.s, texcoordOffset.t);
kernel[0] = 1.0/16.0; kernel[1] = 2.0/16.0; kernel[2] = 1.0/16.0;
kernel[3] = 2.0/16.0; kernel[4] = 4.0/16.0; kernel[5] = 2.0/16.0;
kernel[6] = 1.0/16.0; kernel[7] = 2.0/16.0; kernel[8] = 1.0/16.0;
for(i = 0; i < KERNEL_SIZE; i++) {
vec4 tmp = texture2D(textureSampler, vertTexcoord.st + offset[i]);
sum += tmp * kernel[i];
}
gl_FragColor = vec4(sum.rgb, 1.0) * vertColor;
}

View File

@@ -0,0 +1,31 @@
/**
* Edge Detection
*
* Change the default shader to apply a simple, custom edge detection filter.
*
* Press the mouse to switch between the custom and default shader.
*/
PShader edges;
PImage img;
boolean enabled = true;
void setup() {
size(640, 360, P2D);
img = loadImage("leaves.jpg");
edges = loadShader("edges.glsl");
}
void draw() {
if (enabled == true) {
shader(edges);
}
image(img, 0, 0);
}
void mousePressed() {
enabled = !enabled;
if (!enabled == true) {
resetShader();
}
}

View File

@@ -0,0 +1,48 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
#define KERNEL_SIZE 9
// Edge detection kernel
// -1 -1 -1
// -1 +8 -1
// -1 -1 -1
float kernel[KERNEL_SIZE];
vec2 offset[KERNEL_SIZE];
void main(void) {
int i = 0;
vec4 sum = vec4(0.0);
offset[0] = vec2(-texcoordOffset.s, -texcoordOffset.t);
offset[1] = vec2(0.0, -texcoordOffset.t);
offset[2] = vec2(texcoordOffset.s, -texcoordOffset.t);
offset[3] = vec2(-texcoordOffset.s, 0.0);
offset[4] = vec2(0.0, 0.0);
offset[5] = vec2(texcoordOffset.s, 0.0);
offset[6] = vec2(-texcoordOffset.s, texcoordOffset.t);
offset[7] = vec2(0.0, texcoordOffset.t);
offset[8] = vec2(texcoordOffset.s, texcoordOffset.t);
kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0;
kernel[3] = -1.0; kernel[4] = 8.0; kernel[5] = -1.0;
kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0;
for(i = 0; i < KERNEL_SIZE; i++) {
vec4 tmp = texture2D(textureSampler, vertTexcoord.st + offset[i]);
sum += tmp * kernel[i];
}
gl_FragColor = vec4(sum.rgb, 1.0) * vertColor;
}

View File

@@ -0,0 +1,42 @@
/**
* Edge Filter
*
* Apply a custom shader to the filter() function to affect the geometry drawn to the screen.
*
* Press the mouse to turn the filter on and off.
*/
PShader edges;
boolean applyFilter = true;
void setup() {
size(640, 360, P3D);
edges = loadShader("edges.glsl");
noStroke();
}
void draw() {
background(0);
lights();
translate(width/2, height/2);
pushMatrix();
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
box(120);
popMatrix();
if (applyFilter == true) {
filter(edges);
}
// The sphere doesn't have the edge detection applied
// on it because it is drawn after filter() is called.
rotateY(frameCount * 0.02);
translate(150, 0);
sphere(40);
}
void mousePressed() {
applyFilter = !applyFilter;
}

View File

@@ -0,0 +1,48 @@
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
#define KERNEL_SIZE 9
// Edge detection kernel
// -1 -1 -1
// -1 +8 -1
// -1 -1 -1
float kernel[KERNEL_SIZE];
vec2 offset[KERNEL_SIZE];
void main(void) {
int i = 0;
vec4 sum = vec4(0.0);
offset[0] = vec2(-texcoordOffset.s, -texcoordOffset.t);
offset[1] = vec2(0.0, -texcoordOffset.t);
offset[2] = vec2(texcoordOffset.s, -texcoordOffset.t);
offset[3] = vec2(-texcoordOffset.s, 0.0);
offset[4] = vec2(0.0, 0.0);
offset[5] = vec2(texcoordOffset.s, 0.0);
offset[6] = vec2(-texcoordOffset.s, texcoordOffset.t);
offset[7] = vec2(0.0, texcoordOffset.t);
offset[8] = vec2(texcoordOffset.s, texcoordOffset.t);
kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0;
kernel[3] = -1.0; kernel[4] = 8.0; kernel[5] = -1.0;
kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0;
for(i = 0; i < KERNEL_SIZE; i++) {
vec4 tmp = texture2D(textureSampler, vertTexcoord.st + offset[i]);
sum += tmp * kernel[i];
}
gl_FragColor = vec4(sum.rgb, 1.0) * vertColor;
}

View File

@@ -0,0 +1,52 @@
/**
* Fish Eye
*
* This fish-eye shader is useful for dome projection
*/
PShader fisheye;
PGraphics canvas;
PImage img;
boolean useFishEye = true;
void setup() {
size(640, 640, P3D);
canvas = createGraphics(width, height, P3D);
fisheye = loadShader("FishEye.glsl");
fisheye.set("aperture", 180.0);
}
void draw() {
canvas.beginDraw();
canvas.background(0);
canvas.stroke(255, 0, 0);
for (int i = 0; i < width; i += 10) {
canvas.line(i, 0, i, height);
}
for (int i = 0; i < height; i += 10) {
canvas.line(0, i, width, i);
}
canvas.lights();
canvas.noStroke();
canvas.translate(mouseX, mouseY, 100);
canvas.rotateX(frameCount * 0.01);
canvas.rotateY(frameCount * 0.01);
canvas.box(100);
canvas.endDraw();
if (useFishEye == true) {
shader(fisheye);
}
image(canvas, 0, 0, width, height);
}
void mousePressed() {
if (useFishEye) {
useFishEye = false;
resetShader();
} else {
useFishEye = true;
}
}

View File

@@ -0,0 +1,57 @@
// Inspired by the "Angular Fisheye à la Bourke" sketch from
// Jonathan Cremieux, as shown in the OpenProcessing website:
// http://openprocessing.org/visuals/?visualID=12140
// Using the inverse transform of the angular fisheye as
// explained in Paul Bourke's website:
// http://paulbourke.net/miscellaneous/domefisheye/fisheye/
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
uniform mat4 texcoordMatrix;
varying vec4 vertColor;
varying vec4 vertTexcoord;
uniform float aperture;
const float PI = 3.1415926535;
void main(void) {
float apertureHalf = 0.5 * aperture * (PI / 180.0);
// This factor ajusts the coordinates in the case that
// the aperture angle is less than 180 degrees, in which
// case the area displayed is not the entire half-sphere.
float maxFactor = sin(apertureHalf);
// The st factor takes into account the situation when non-pot
// textures are not supported, so that the maximum texture
// coordinate to cover the entire image might not be 1.
vec2 stFactor = vec2(1.0 / abs(texcoordMatrix[0][0]), 1.0 / abs(texcoordMatrix[1][1]));
vec2 pos = (2.0 * vertTexcoord.st * stFactor - 1.0);
float l = length(pos);
if (l > 1.0) {
gl_FragColor = vec4(0, 0, 0, 1);
} else {
float x = maxFactor * pos.x;
float y = maxFactor * pos.y;
float n = length(vec2(x, y));
float z = sqrt(1.0 - n * n);
float r = atan(n, z) / PI;
float phi = atan(y, x);
float u = r * cos(phi) + 0.5;
float v = r * sin(phi) + 0.5;
gl_FragColor = texture2D(textureSampler, vec2(u, v) / stFactor) * vertColor;
}
}

View File

@@ -0,0 +1,72 @@
/**
* Glossy Fish Eye
*
* A fish-eye shader is used on the main surface and
* a glossy specular reflection shader is used on the
* offscreen canvas.
*/
PShader fisheye;
PShader glossy;
PGraphics canvas;
PImage img;
PShape ball;
boolean useFishEye = true;
void setup() {
size(640, 640, P3D);
canvas = createGraphics(width, height, P3D);
fisheye = loadShader("FishEye.glsl");
fisheye.set("aperture", 180.0);
glossy = loadShader("GlossyFrag.glsl", "GlossyVert.glsl");
glossy.set("AmbientColour", 0, 0, 0);
glossy.set("DiffuseColour", 0.9, 0.2, 0.2);
glossy.set("SpecularColour", 1.0, 1.0, 1.0);
glossy.set("AmbientIntensity", 1.0);
glossy.set("DiffuseIntensity", 1.0);
glossy.set("SpecularIntensity", 0.7);
glossy.set("Roughness", 0.7);
glossy.set("Sharpness", 0.0);
ball = createShape(SPHERE, 50);
ball.noStroke();
}
void draw() {
canvas.beginDraw();
canvas.shader(glossy);
canvas.noStroke();
canvas.background(0);
canvas.pushMatrix();
canvas.rotateY(frameCount * 0.01);
canvas.pointLight(204, 204, 204, 1000, 1000, 1000);
canvas.popMatrix();
for (float x = 0; x < canvas.width + 100; x += 100) {
for (float y = 0; y < canvas.height + 100; y += 100) {
for (float z = 0; z < 400; z += 100) {
canvas.pushMatrix();
canvas.translate(x, y, -z);
canvas.shape(ball);
canvas.popMatrix();
}
}
}
canvas.endDraw();
if (useFishEye == true) {
shader(fisheye);
}
image(canvas, 0, 0, width, height);
}
void mousePressed() {
if (useFishEye) {
useFishEye = false;
resetShader();
} else {
useFishEye = true;
}
}

View File

@@ -0,0 +1,57 @@
// Inspired by the "Angular Fisheye à la Bourke" sketch from
// Jonathan Cremieux, as shown in the OpenProcessing website:
// http://openprocessing.org/visuals/?visualID=12140
// Using the inverse transform of the angular fisheye as
// explained in Paul Bourke's website:
// http://paulbourke.net/miscellaneous/domefisheye/fisheye/
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
uniform mat4 texcoordMatrix;
varying vec4 vertColor;
varying vec4 vertTexcoord;
uniform float aperture;
const float PI = 3.1415926535;
void main(void) {
float apertureHalf = 0.5 * aperture * (PI / 180.0);
// This factor ajusts the coordinates in the case that
// the aperture angle is less than 180 degrees, in which
// case the area displayed is not the entire half-sphere.
float maxFactor = sin(apertureHalf);
// The st factor takes into account the situation when non-pot
// textures are not supported, so that the maximum texture
// coordinate to cover the entire image might not be 1.
vec2 stFactor = vec2(1.0 / abs(texcoordMatrix[0][0]), 1.0 / abs(texcoordMatrix[1][1]));
vec2 pos = (2.0 * vertTexcoord.st * stFactor - 1.0);
float l = length(pos);
if (l > 1.0) {
gl_FragColor = vec4(0, 0, 0, 1);
} else {
float x = maxFactor * pos.x;
float y = maxFactor * pos.y;
float n = length(vec2(x, y));
float z = sqrt(1.0 - n * n);
float r = atan(n, z) / PI;
float phi = atan(y, x);
float u = r * cos(phi) + 0.5;
float v = r * sin(phi) + 0.5;
gl_FragColor = texture2D(textureSampler, vec2(u, v) / stFactor) * vertColor;
}
}

View File

@@ -0,0 +1,45 @@
// Copyright (C) 2007 Dave Griffiths
// Copyright (C) 2007 Dave Griffiths
// Licence: GPLv2 (see COPYING)
// Fluxus Shader Library
// ---------------------
// Glossy Specular Reflection Shader
// A more controllable version of blinn shading,
// Useful for ceramic or fluids - from Advanced
// Renderman, thanks to Larry Gritz
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform vec3 AmbientColour;
uniform vec3 DiffuseColour;
uniform vec3 SpecularColour;
uniform float AmbientIntensity;
uniform float DiffuseIntensity;
uniform float SpecularIntensity;
uniform float Roughness;
uniform float Sharpness;
varying vec3 N;
varying vec3 P;
varying vec3 V;
varying vec3 L;
void main()
{
float w = 0.18*(1.0-Sharpness);
vec3 l = normalize(L);
vec3 n = normalize(N);
vec3 v = normalize(V);
vec3 h = normalize(l+v);
float diffuse = dot(l,n);
float specular = smoothstep(0.72-w,0.72+w,pow(max(0.0,dot(n,h)),1.0/Roughness));
gl_FragColor = vec4(AmbientColour*AmbientIntensity +
DiffuseColour*diffuse*DiffuseIntensity +
SpecularColour*specular*SpecularIntensity,1);
}

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2007 Dave Griffiths
// Licence: GPLv2 (see COPYING)
// Fluxus Shader Library
// ---------------------
// Glossy Specular Reflection Shader
// A more controllable version of blinn shading,
// Useful for ceramic or fluids - from Advanced
// Renderman, thanks to Larry Gritz
uniform mat4 modelviewMatrix;
uniform mat4 projmodelviewMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPosition[8];
attribute vec4 inVertex;
attribute vec3 inNormal;
varying vec3 N;
varying vec3 P;
varying vec3 V;
varying vec3 L;
void main() {
N = normalize(normalMatrix * inNormal);
P = inVertex.xyz;
V = -vec3(modelviewMatrix * inVertex);
L = vec3(modelviewMatrix * (lightPosition[0] - inVertex));
gl_Position = projmodelviewMatrix * inVertex;
}

View File

@@ -0,0 +1,34 @@
/**
* Image Mask
*
* Move the mouse to reveal the image through the dynamic mask.
*/
PShader maskShader;
PImage srcImage;
PGraphics maskImage;
void setup() {
size(640, 360, P2D);
srcImage = loadImage("leaves.jpg");
maskImage = createGraphics(srcImage.width, srcImage.height, P2D);
maskImage.noSmooth();
maskShader = loadShader("mask.glsl");
maskShader.set("maskSampler", maskImage);
background(0);
}
void draw() {
maskImage.beginDraw();
maskImage.background(0);
if (mouseX != 0 && mouseY != 0) {
maskImage.noStroke();
maskImage.fill(255, 0, 0);
maskImage.ellipse(mouseX, mouseY, 50, 50);
}
maskImage.endDraw();
shader(maskShader);
image(srcImage, 0, 0, width, height);
}

View File

@@ -0,0 +1,12 @@
uniform sampler2D textureSampler;
uniform sampler2D maskSampler;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
void main() {
vec4 texColor = texture2D(textureSampler, vertTexcoord.st).rgba;
vec4 maskColor = texture2D(maskSampler, vec2(vertTexcoord.s, 1.0 - vertTexcoord.t)).rgba;
gl_FragColor = mix(texColor, vec4(0, 0, 0, 0), 1.0 - maskColor.r);
}

View File

@@ -0,0 +1,106 @@
// Draws a triangle using low-level OpenGL calls.
import java.nio.*;
PGraphicsOpenGL pg;
PGL pgl;
PShader flatShader;
int vertLoc;
int colorLoc;
float[] vertices;
float[] colors;
FloatBuffer vertData;
FloatBuffer colorData;
void setup() {
size(640, 360, P3D);
pg = (PGraphicsOpenGL)g;
// Loads a shader to render geometry w/out
// textures and lights.
flatShader = loadShader("frag.glsl", "vert.glsl");
vertices = new float[12];
vertData = allocateDirectFloatBuffer(12);
colors = new float[12];
colorData = allocateDirectFloatBuffer(12);
}
void draw() {
background(0);
// The geometric transformations will be automatically passed
// to the shader.
rotate(frameCount * 0.01f, width, height, 0);
updateGeometry();
pgl = pg.beginPGL();
flatShader.bind();
vertLoc = pgl.getAttribLocation(flatShader.glProgram, "inVertex");
colorLoc = pgl.getAttribLocation(flatShader.glProgram, "inColor");
pgl.enableVertexAttribArray(vertLoc);
pgl.enableVertexAttribArray(colorLoc);
pgl.vertexAttribPointer(vertLoc, 4, PGL.FLOAT, false, 0, vertData);
pgl.vertexAttribPointer(colorLoc, 4, PGL.FLOAT, false, 0, colorData);
pgl.drawArrays(PGL.TRIANGLES, 0, 3);
pgl.disableVertexAttribArray(vertLoc);
pgl.disableVertexAttribArray(colorLoc);
flatShader.unbind();
pg.endPGL();
}
void updateGeometry() {
// Vertex 1
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = 0;
vertices[3] = 1;
colors[0] = 1;
colors[1] = 0;
colors[2] = 0;
colors[3] = 1;
// Corner 2
vertices[4] = width/2;
vertices[5] = height;
vertices[6] = 0;
vertices[7] = 1;
colors[4] = 0;
colors[5] = 1;
colors[6] = 0;
colors[7] = 1;
// Corner 3
vertices[8] = width;
vertices[9] = 0;
vertices[10] = 0;
vertices[11] = 1;
colors[8] = 0;
colors[9] = 0;
colors[10] = 1;
colors[11] = 1;
vertData.rewind();
vertData.put(vertices);
vertData.position(0);
colorData.rewind();
colorData.put(colors);
colorData.position(0);
}
FloatBuffer allocateDirectFloatBuffer(int n) {
return ByteBuffer.allocateDirect(n * Float.SIZE/8).order(ByteOrder.nativeOrder()).asFloatBuffer();
}

View File

@@ -0,0 +1,30 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011-12 Ben Fry and Casey Reas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec4 vertColor;
void main() {
gl_FragColor = vertColor;
}

View File

@@ -0,0 +1,32 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2011-12 Ben Fry and Casey Reas
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
uniform mat4 projmodelviewMatrix;
attribute vec4 inVertex;
attribute vec4 inColor;
varying vec4 vertColor;
void main() {
gl_Position = projmodelviewMatrix * inVertex;
vertColor = inColor;
}

View File

@@ -0,0 +1,68 @@
/**
* Separate Blur Shader
*
* This blur shader works by applying two successive passes, one horizontal
* and the other vertical.
*
* Press the mouse to switch between the custom and default shader.
*/
PShader blur;
PGraphics src;
PGraphics pass1, pass2;
void setup() {
size(640, 360, P2D);
blur = loadShader("blur.glsl");
blur.set("blurSize", 9);
blur.set("sigma", 5.0f);
src = createGraphics(width, height, P2D);
pass1 = createGraphics(width, height, P2D);
pass1.noSmooth();
pass2 = createGraphics(width, height, P2D);
pass2.noSmooth();
}
void draw() {
src.beginDraw();
src.background(0);
src.fill(255);
src.ellipse(width/2, height/2, 100, 100);
src.endDraw();
// Applying the blur shader along the vertical direction
blur.set("horizontalPass", 0);
pass1.beginDraw();
pass1.shader(blur);
pass1.image(src, 0, 0);
pass1.endDraw();
// Applying the blur shader along the horizontal direction
blur.set("horizontalPass", 1);
pass2.beginDraw();
pass2.shader(blur);
pass2.image(pass1, 0, 0);
pass2.endDraw();
image(pass2, 0, 0);
}
void keyPressed() {
if (key == '9') {
blur.set("blurSize", 9);
blur.set("sigma", 5.0);
} else if (key == '7') {
blur.set("blurSize", 7);
blur.set("sigma", 3.0);
} else if (key == '5') {
blur.set("blurSize", 5);
blur.set("sigma", 2.0);
} else if (key == '3') {
blur.set("blurSize", 5);
blur.set("sigma", 1.0);
}
}

View File

@@ -0,0 +1,57 @@
// Adapted from:
// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D textureSampler;
// The inverse of the texture dimensions along X and Y
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
uniform int blurSize;
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma; // The sigma value for the gaussian function: higher value means more blur
// A good value for 9x9 is around 3 to 5
// A good value for 7x7 is around 2.5 to 4
// A good value for 5x5 is around 2 to 3.5
// ... play around with this based on what you need :)
const float pi = 3.14159265;
void main() {
float numBlurPixelsPerSide = float(blurSize / 2);
vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
vec3 incrementalGaussian;
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
float coefficientSum = 0.0;
// Take the central sample first...
avgValue += texture2D(textureSampler, vertTexcoord.st) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
// Go through the remaining 8 vertical samples (4 on each side of the center)
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
avgValue += texture2D(textureSampler, vertTexcoord.st - i * texcoordOffset *
blurMultiplyVec) * incrementalGaussian.x;
avgValue += texture2D(textureSampler, vertTexcoord.st + i * texcoordOffset *
blurMultiplyVec) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
gl_FragColor = avgValue / coefficientSum;
}

View File

@@ -0,0 +1,43 @@
/**
* Toon Shading.
*
* Example showing the use of a custom lighting shader in order
* to apply a "toon" effect on the scene. Based on the glsl tutorial
* from lighthouse 3D:
* http://www.lighthouse3d.com/tutorials/glsl-tutorial/toon-shader-version-ii/
*/
PShader toon;
boolean shaderEnabled = true;
void setup() {
size(640, 360, P3D);
noStroke();
fill(204);
toon = loadShader("ToonFrag.glsl", "ToonVert.glsl");
}
void draw() {
if (shaderEnabled == true) {
shader(toon);
}
noStroke();
background(0);
float dirY = (mouseY / float(height) - 0.5) * 2;
float dirX = (mouseX / float(width) - 0.5) * 2;
directionalLight(204, 204, 204, -dirX, -dirY, -1);
translate(width/2, height/2);
sphere(120);
}
void mousePressed() {
if (shaderEnabled) {
shaderEnabled = false;
resetShader();
}
else {
shaderEnabled = true;
}
}

View File

@@ -0,0 +1,20 @@
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
float intensity;
vec4 color;
intensity = max(0.0, dot(vertLightDir, vertNormal));
if (intensity > 0.95) {
color = vec4(1.0, 0.5, 0.5, 1.0);
} else if (intensity > 0.5) {
color = vec4(0.6, 0.3, 0.3, 1.0);
} else if (intensity > 0.25) {
color = vec4(0.4, 0.2, 0.2, 1.0);
} else {
color = vec4(0.2, 0.1, 0.1, 1.0);
}
gl_FragColor = color;
}

View File

@@ -0,0 +1,29 @@
// Toon shader using per-pixel lighting. Based on the glsl
// tutorial from lighthouse 3D:
// http://www.lighthouse3d.com/tutorials/glsl-tutorial/toon-shader-version-ii/
uniform mat4 modelviewMatrix;
uniform mat4 projmodelviewMatrix;
uniform mat3 normalMatrix;
uniform vec3 lightNormal[8];
attribute vec4 inVertex;
attribute vec3 inNormal;
varying vec3 vertNormal;
varying vec3 vertLightDir;
void main() {
// Vertex in clip coordinates
gl_Position = projmodelviewMatrix * inVertex;
// Normal vector in eye coordinates is passed
// to the fragment shader
vertNormal = normalize(normalMatrix * inNormal);
// Assuming that there is only one directional light.
// Its normal vector is passed to the fragment shader
// in order to perform per-pixel lighting calculation.
vertLightDir = -lightNormal[0];
}