Last active
July 10, 2020 10:56
-
-
Save heisters/22b2e2a95e6ad8cd74b9 to your computer and use it in GitHub Desktop.
Cinder blur filter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uniform float u_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 :) | |
// The size of the blur | |
uniform float u_blurSize; | |
uniform sampler2D u_tex; // Texture that will be blurred by this shader | |
// The direction of the blur. vec2(1.0, 0.0) for horizontal, vec2(0.0, 1.0) for | |
// vertical | |
uniform vec2 u_direction; | |
// The inverse of the texture dimensions along X and Y | |
uniform vec2 u_texcoordOffset; | |
const float PI = 3.14159265; | |
void main() | |
{ | |
vec2 blurMult = u_texcoordOffset * u_direction; | |
float blurSizePerSide = (u_blurSize - 1.0) * 0.5; | |
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889) | |
vec3 incrementalGaussian; | |
incrementalGaussian.x = 1.0 / (sqrt(2.0 * PI) * u_sigma); | |
incrementalGaussian.y = exp(-0.5 / (u_sigma * u_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(u_tex, gl_TexCoord[0].xy) * 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 <= blurSizePerSide; i++) { | |
avgValue += texture2D(u_tex, gl_TexCoord[0].xy - i * blurMult) * incrementalGaussian.x; | |
avgValue += texture2D(u_tex, gl_TexCoord[0].xy + i * blurMult) * incrementalGaussian.x; | |
coefficientSum += 2.0 * incrementalGaussian.x; | |
incrementalGaussian.xy *= incrementalGaussian.yz; | |
} | |
gl_FragColor = avgValue / coefficientSum; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void main() { | |
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; | |
gl_TexCoord[0] = gl_MultiTexCoord0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "BlurFilter.h" | |
#include "Resources.h" | |
using namespace std; | |
using namespace ci; | |
BlurFilter::BlurFilter( int w, int h ) : | |
mFboA( w, h ), | |
mFboB( w, h ) | |
{ | |
mBlurShader = gl::GlslProg::create( app::loadResource( RES_BLUR_VERT_SHADER), app::loadResource( RES_BLUR_FRAG_SHADER ) ); | |
} | |
void BlurFilter::drawTexIntoFBO( gl::Fbo &fbo, const gl::Texture &tex, float sigma, float size, const Vec2f &direction ) | |
{ | |
Vec2f texcoordOffset = Vec2f(1.f, 1.f) / (Vec2f)tex.getSize(); | |
fbo.bindFramebuffer(); | |
mBlurShader->bind(); | |
mBlurShader->uniform("u_sigma", sigma); | |
mBlurShader->uniform("u_blurSize", size); | |
mBlurShader->uniform("u_direction", direction); | |
mBlurShader->uniform("u_texcoordOffset", texcoordOffset); | |
gl::clear( Color::black() ); | |
gl::setViewport( fbo.getBounds() ); | |
gl::pushMatrices(); | |
gl::setMatricesWindow( fbo.getSize(), false ); | |
gl::draw( tex, fbo.getBounds() ); | |
gl::popMatrices(); | |
mBlurShader->unbind(); | |
mFboA.unbindFramebuffer(); | |
} | |
ci::gl::Texture | |
BlurFilter::blur( const ci::gl::Texture &tex, float sigma, float size ) | |
{ | |
auto oldvp = gl::getViewport(); | |
drawTexIntoFBO( mFboA, tex, sigma, size, Vec2f(0.f, 1.f) ); | |
drawTexIntoFBO( mFboB, mFboA.getTexture(), sigma, size, Vec2f(1.f, 0.f) ); | |
gl::setViewport( oldvp ); | |
return mFboB.getTexture(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "cinder/gl/GlSlProg.h" | |
#include "cinder/gl/Fbo.h" | |
class BlurFilter | |
{ | |
public: | |
BlurFilter( int w, int h ); | |
ci::gl::Texture blur( const ci::gl::Texture &tex, float sigma, float size ); | |
private: | |
void drawTexIntoFBO( ci::gl::Fbo &fbo, const ci::gl::Texture &tex, float sigma, float size, const ci::Vec2f &direction ); | |
ci::gl::GlslProgRef mBlurShader; | |
ci::gl::Fbo mFboA, mFboB; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment