Skip to content

Instantly share code, notes, and snippets.

@gre
Created September 4, 2015 12:22
Show Gist options
  • Save gre/1c04aed31742be2d0ad6 to your computer and use it in GitHub Desktop.
Save gre/1c04aed31742be2d0ad6 to your computer and use it in GitHub Desktop.
Multi-pass blur implementation in gl-shader(-native)
const React = require("react-native");
const GL = require("gl-react-native");
const {
PropTypes
} = React;
const Blur1D = require("./Blur1D");
const NORM = Math.sqrt(2)/2;
function directionForPass (p, factor, total) {
const f = factor * p / total;
switch (p%4) {
case 0: return [f,0];
case 1: return [0,f];
case 2: return [f*NORM,f*NORM];
case 3: return [f*NORM,-f*NORM];
}
return p%2 ? [f,0] : [0,f];
}
/** Usages:
- Small blur:
<Blur factor={0.5} passes={2} width={w} height={h}>{url}</Blur>
- Medium blur:
<Blur factor={2} passes={4} width={w} height={h}>{url}</Blur>
- Powerful blur:
<Blur factor={20} passes={6} width={w} height={h}>{url}</Blur>
*/
class Blur extends GL.Component {
render () {
const { width, height, factor, children, passes } = this.props;
const rec = p => p <= 0 ? children :
<Blur1D width={width} height={height} direction={directionForPass(p, factor, passes)}>
{rec(p-1)}
</Blur1D>;
return rec(passes);
}
}
Blur.defaultProps = {
passes: 2
};
Blur.propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
factor: PropTypes.number.isRequired,
children: PropTypes.any.isRequired,
passes: PropTypes.number
};
module.exports = Blur;
const React = require("react-native");
const GL = require("gl-react-native");
const {
PropTypes
} = React;
const shaders = GL.Shaders.create({
blur1D: {
frag: `
precision highp float;
varying vec2 uv;
uniform sampler2D t;
uniform vec2 resolution;
uniform vec2 direction;
// Credits: https://github.com/Jam3/glsl-fast-gaussian-blur
vec4 blur9 (sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.3846153846) * direction;
vec2 off2 = vec2(3.2307692308) * direction;
color += texture2D(image, uv) * 0.2270270270;
color += texture2D(image, uv + (off1 / resolution)) * 0.3162162162;
color += texture2D(image, uv - (off1 / resolution)) * 0.3162162162;
color += texture2D(image, uv + (off2 / resolution)) * 0.0702702703;
color += texture2D(image, uv - (off2 / resolution)) * 0.0702702703;
return color;
}
void main () {
gl_FragColor = blur9(t, uv, resolution, direction);
}
`
}
});
class Blur1D extends GL.Component {
render () {
const { width, height, direction, children } = this.props;
return <GL.View
shader={shaders.blur1D}
width={width}
height={height}
uniforms={{
direction,
resolution: [ width, height ]
}}>
<GL.Target uniform="t">{children}</GL.Target>
</GL.View>;
}
}
Blur1D.propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
direction: PropTypes.array.isRequired,
children: PropTypes.any.isRequired
};
module.exports = Blur1D;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment