diff --git a/java/examples/Topics/Shaders/BadPrint/BadPrint.pde b/java/examples/Topics/Shaders/BadPrint/BadPrint.pde new file mode 100644 index 000000000..ee8278ec8 --- /dev/null +++ b/java/examples/Topics/Shaders/BadPrint/BadPrint.pde @@ -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); +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/BadPrint/data/BadPrintFrag.glsl b/java/examples/Topics/Shaders/BadPrint/data/BadPrintFrag.glsl new file mode 100644 index 000000000..062cf02b7 --- /dev/null +++ b/java/examples/Topics/Shaders/BadPrint/data/BadPrintFrag.glsl @@ -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); +} diff --git a/java/examples/Topics/Shaders/BadPrint/data/BadPrintVert.glsl b/java/examples/Topics/Shaders/BadPrint/data/BadPrintVert.glsl new file mode 100644 index 000000000..cc7662c5b --- /dev/null +++ b/java/examples/Topics/Shaders/BadPrint/data/BadPrintVert.glsl @@ -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; +} diff --git a/java/examples/Topics/Shaders/BlurFilter/BlurFilter.pde b/java/examples/Topics/Shaders/BlurFilter/BlurFilter.pde new file mode 100644 index 000000000..ce6c268f3 --- /dev/null +++ b/java/examples/Topics/Shaders/BlurFilter/BlurFilter.pde @@ -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); +} + + + diff --git a/java/examples/Topics/Shaders/BlurFilter/data/blur.glsl b/java/examples/Topics/Shaders/BlurFilter/data/blur.glsl new file mode 100644 index 000000000..b11a04d64 --- /dev/null +++ b/java/examples/Topics/Shaders/BlurFilter/data/blur.glsl @@ -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; +} diff --git a/java/examples/Topics/Shaders/EdgeDetect/EdgeDetect.pde b/java/examples/Topics/Shaders/EdgeDetect/EdgeDetect.pde new file mode 100644 index 000000000..db617514a --- /dev/null +++ b/java/examples/Topics/Shaders/EdgeDetect/EdgeDetect.pde @@ -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(); + } +} diff --git a/java/examples/Topics/Shaders/EdgeDetect/data/edges.glsl b/java/examples/Topics/Shaders/EdgeDetect/data/edges.glsl new file mode 100644 index 000000000..b032743d0 --- /dev/null +++ b/java/examples/Topics/Shaders/EdgeDetect/data/edges.glsl @@ -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; +} diff --git a/java/examples/Topics/Shaders/EdgeFilter/EdgeFilter.pde b/java/examples/Topics/Shaders/EdgeFilter/EdgeFilter.pde new file mode 100644 index 000000000..845a9fbcc --- /dev/null +++ b/java/examples/Topics/Shaders/EdgeFilter/EdgeFilter.pde @@ -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; +} diff --git a/java/examples/Topics/Shaders/EdgeFilter/data/edges.glsl b/java/examples/Topics/Shaders/EdgeFilter/data/edges.glsl new file mode 100644 index 000000000..b032743d0 --- /dev/null +++ b/java/examples/Topics/Shaders/EdgeFilter/data/edges.glsl @@ -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; +} diff --git a/java/examples/Topics/Shaders/FishEye/FishEye.pde b/java/examples/Topics/Shaders/FishEye/FishEye.pde new file mode 100644 index 000000000..4042c30b1 --- /dev/null +++ b/java/examples/Topics/Shaders/FishEye/FishEye.pde @@ -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; + } +} diff --git a/java/examples/Topics/Shaders/FishEye/data/FishEye.glsl b/java/examples/Topics/Shaders/FishEye/data/FishEye.glsl new file mode 100644 index 000000000..65d005e0a --- /dev/null +++ b/java/examples/Topics/Shaders/FishEye/data/FishEye.glsl @@ -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; + } +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/GlossyFishEye/GlossyFishEye.pde b/java/examples/Topics/Shaders/GlossyFishEye/GlossyFishEye.pde new file mode 100644 index 000000000..09c7dff45 --- /dev/null +++ b/java/examples/Topics/Shaders/GlossyFishEye/GlossyFishEye.pde @@ -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; + } +} diff --git a/java/examples/Topics/Shaders/GlossyFishEye/data/FishEye.glsl b/java/examples/Topics/Shaders/GlossyFishEye/data/FishEye.glsl new file mode 100644 index 000000000..65d005e0a --- /dev/null +++ b/java/examples/Topics/Shaders/GlossyFishEye/data/FishEye.glsl @@ -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; + } +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyFrag.glsl b/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyFrag.glsl new file mode 100644 index 000000000..4f96b6f6d --- /dev/null +++ b/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyFrag.glsl @@ -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); +} diff --git a/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyVert.glsl b/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyVert.glsl new file mode 100644 index 000000000..fa0c29590 --- /dev/null +++ b/java/examples/Topics/Shaders/GlossyFishEye/data/GlossyVert.glsl @@ -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; +} + diff --git a/java/examples/Topics/Shaders/ImageMask/ImageMask.pde b/java/examples/Topics/Shaders/ImageMask/ImageMask.pde new file mode 100644 index 000000000..a9630609f --- /dev/null +++ b/java/examples/Topics/Shaders/ImageMask/ImageMask.pde @@ -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); +} + diff --git a/java/examples/Topics/Shaders/ImageMask/data/mask.glsl b/java/examples/Topics/Shaders/ImageMask/data/mask.glsl new file mode 100644 index 000000000..e4d0dbb26 --- /dev/null +++ b/java/examples/Topics/Shaders/ImageMask/data/mask.glsl @@ -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); +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/LowLevelGL/LowLevelGL.pde b/java/examples/Topics/Shaders/LowLevelGL/LowLevelGL.pde new file mode 100644 index 000000000..1d6d73c33 --- /dev/null +++ b/java/examples/Topics/Shaders/LowLevelGL/LowLevelGL.pde @@ -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(); +} diff --git a/java/examples/Topics/Shaders/LowLevelGL/data/frag.glsl b/java/examples/Topics/Shaders/LowLevelGL/data/frag.glsl new file mode 100644 index 000000000..16742d2bd --- /dev/null +++ b/java/examples/Topics/Shaders/LowLevelGL/data/frag.glsl @@ -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; +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/LowLevelGL/data/vert.glsl b/java/examples/Topics/Shaders/LowLevelGL/data/vert.glsl new file mode 100644 index 000000000..95c266a76 --- /dev/null +++ b/java/examples/Topics/Shaders/LowLevelGL/data/vert.glsl @@ -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; +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/SepBlur/SepBlur.pde b/java/examples/Topics/Shaders/SepBlur/SepBlur.pde new file mode 100644 index 000000000..e9e61a19b --- /dev/null +++ b/java/examples/Topics/Shaders/SepBlur/SepBlur.pde @@ -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); + } +} diff --git a/java/examples/Topics/Shaders/SepBlur/data/blur.glsl b/java/examples/Topics/Shaders/SepBlur/data/blur.glsl new file mode 100644 index 000000000..bba029e7f --- /dev/null +++ b/java/examples/Topics/Shaders/SepBlur/data/blur.glsl @@ -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; +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/ToonShading/ToonShading.pde b/java/examples/Topics/Shaders/ToonShading/ToonShading.pde new file mode 100644 index 000000000..644a74c95 --- /dev/null +++ b/java/examples/Topics/Shaders/ToonShading/ToonShading.pde @@ -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; + } +} + diff --git a/java/examples/Topics/Shaders/ToonShading/data/ToonFrag.glsl b/java/examples/Topics/Shaders/ToonShading/data/ToonFrag.glsl new file mode 100644 index 000000000..bb1c72971 --- /dev/null +++ b/java/examples/Topics/Shaders/ToonShading/data/ToonFrag.glsl @@ -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; +} \ No newline at end of file diff --git a/java/examples/Topics/Shaders/ToonShading/data/ToonVert.glsl b/java/examples/Topics/Shaders/ToonShading/data/ToonVert.glsl new file mode 100644 index 000000000..f314485aa --- /dev/null +++ b/java/examples/Topics/Shaders/ToonShading/data/ToonVert.glsl @@ -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]; +} \ No newline at end of file