Skip to content

Instantly share code, notes, and snippets.

@KrabCode
Created September 24, 2020 18:26
Show Gist options
  • Save KrabCode/365d622e1dca7c7a3ba9077652985457 to your computer and use it in GitHub Desktop.
Save KrabCode/365d622e1dca7c7a3ba9077652985457 to your computer and use it in GitHub Desktop.
adjustable blur shader
// From the PostFX library for Processing, put this file into the data folder in the sketch folder
// Adapted from:
// <a href="http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html" target="_blank" rel="nofollow">http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html</a>
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_TEXTURE_SHADER
uniform sampler2D texture;
uniform float blurX;
uniform float blurY;
uniform float blurW;
uniform float blurH;
// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;
uniform vec2 resolution;
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 <span class="Emoticon Emoticon1"><span>:)</span></span>
const float pi = 3.14159265;
vec4 blur(){
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(texture, 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(texture, vertTexCoord.st - i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
avgValue += texture2D(texture, vertTexCoord.st + i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
return avgValue / coefficientSum;
}
vec4 original(){
return texture2D(texture, gl_FragCoord.xy / resolution.xy);
}
bool pointRect(float px, float py, float rx, float ry, float rw, float rh) {
// is the point inside the rectangle's bounds?
if (px >= rx && // right of the left edge AND
px <= rx + rw && // left of the right edge AND
py >= ry && // below the top AND
py <= ry + rh) { // above the bottom
return true;
}
return false;
}
void main() {
bool isInsideRectangle = pointRect(gl_FragCoord.x, resolution.y - gl_FragCoord.y, blurX, blurY, blurW, blurH);
if(isInsideRectangle){
gl_FragColor = blur();
}else{
gl_FragColor = original();
}
}
PImage image;
PShader blur;
PGraphics pg;
void setup(){
size(800,800,P2D);
pg = createGraphics(width, height,P2D);
blur = loadShader("blur.glsl");
image = loadImage("https://picsum.photos/800/800.jpg");
}
void draw(){
pg.beginDraw();
pg.background(image);
blurPass(pg);
pg.endDraw();
image(pg, 0, 0, width, height);
surface.setTitle("fps: " + frameRate);
}
void blurPass(PGraphics pg){
blur.set("blurX", 200f);
blur.set("blurY", 200f);
blur.set("blurW", 400f);
blur.set("blurH", 400f);
blur.set("blurSize", 7);
blur.set("texOffset", 0f, 0f);
blur.set("sigma", 3f);
blur.set("horizontalPass", 0);
pg.filter(blur);
blur.set("horizontalPass", 1);
pg.filter(blur);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment