Skip to content

Commit 56b1920

Browse files
author
monkstone
committed
add metaballs example
1 parent 727d9da commit 56b1920

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Adapted from:
2+
// <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>
3+
4+
#ifdef GL_ES
5+
precision mediump float;
6+
precision mediump int;
7+
#endif
8+
9+
#define PROCESSING_TEXTURE_SHADER
10+
11+
uniform sampler2D texture;
12+
13+
// The inverse of the texture dimensions along X and Y
14+
uniform vec2 texOffset;
15+
16+
varying vec4 vertColor;
17+
varying vec4 vertTexCoord;
18+
19+
uniform int kernelSize;
20+
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
21+
uniform float strength; // The strength value for the gaussian function: higher value means more blur
22+
// A good value for 9x9 is around 3 to 5
23+
// A good value for 7x7 is around 2.5 to 4
24+
// A good value for 5x5 is around 2 to 3.5
25+
// ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
26+
27+
const float pi = 3.14159265;
28+
29+
void main() {
30+
float numBlurPixelsPerSide = float(kernelSize / 2);
31+
32+
vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
33+
34+
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
35+
vec3 incrementalGaussian;
36+
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * strength);
37+
incrementalGaussian.y = exp(-0.5 / (strength * strength));
38+
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
39+
40+
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
41+
float coefficientSum = 0.0;
42+
43+
// Take the central sample first...
44+
avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
45+
coefficientSum += incrementalGaussian.x;
46+
incrementalGaussian.xy *= incrementalGaussian.yz;
47+
48+
// Go through the remaining 8 vertical samples (4 on each side of the center)
49+
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
50+
avgValue += texture2D(texture, vertTexCoord.st - i * texOffset *
51+
blurMultiplyVec) * incrementalGaussian.x;
52+
avgValue += texture2D(texture, vertTexCoord.st + i * texOffset *
53+
blurMultiplyVec) * incrementalGaussian.x;
54+
coefficientSum += 2.0 * incrementalGaussian.x;
55+
incrementalGaussian.xy *= incrementalGaussian.yz;
56+
}
57+
58+
gl_FragColor = avgValue / coefficientSum;
59+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifdef GL_ES
2+
precision mediump float;
3+
precision mediump int;
4+
#endif
5+
6+
#define PROCESSING_TEXTURE_SHADER
7+
8+
uniform sampler2D texture;
9+
varying vec4 vertTexCoord;
10+
11+
uniform float threshold;
12+
uniform float antialiasing;
13+
14+
void main(void) {
15+
16+
vec2 coord = vertTexCoord.st;
17+
18+
// Get the color of the pixel at our fragment's coordinates
19+
vec4 pixel = texture2D( texture, coord );
20+
21+
gl_FragColor = vec4(smoothstep(threshold - antialiasing, threshold + antialiasing, pixel.r));
22+
}

image_filtering/metaballs.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
# Note: this filter is meant to be used on black & white images
3+
4+
# The 2D metaball filter is a combination of blur and threshold
5+
attr_reader :gaussian_blur, :threshold
6+
7+
def setup
8+
size(500, 500, P2D)
9+
# Load and configure the filters
10+
@gaussian_blur = load_shader('gaussianBlur.glsl')
11+
gaussian_blur.set('kernelSize', 32) # How big is the sampling kernel?
12+
gaussian_blur.set('strength', 7.0) # How strong is the blur?
13+
@threshold = load_shader('threshold.glsl')
14+
threshold.set('threshold', 0.5)
15+
threshold.set('antialiasing', 0.05) # values between 0.00 and 0.10 work best
16+
end
17+
18+
def draw
19+
background(255)
20+
# Draw some moving circles
21+
translate(width / 2,height / 2)
22+
no_stroke
23+
fill(0)
24+
ellipse(0, 0, 100, 100)
25+
x = map1d(sin(frame_count * 0.01), (-1.0..1.0), (-120.0..120.0))
26+
ellipse(x, 0, 100, 100)
27+
ellipse(-x, 0, 100, 100)
28+
y = map1d(sin(frame_count * 0.01), (-1.0..1.0), (-120.0..120.0))
29+
ellipse(0, y, 100, 100)
30+
ellipse(0, -y, 100, 100)
31+
# Vertical blur pass
32+
gaussian_blur.set('horizontalPass', 0)
33+
filter(gaussian_blur)
34+
# Horizontal blur pass
35+
gaussian_blur.set('horizontalPass', 1)
36+
filter(gaussian_blur)
37+
filter(threshold)
38+
end
39+

0 commit comments

Comments
 (0)