Skip to content

Commit 232dd87

Browse files
committed
at last voronoi distance
1 parent d27dbb0 commit 232dd87

File tree

10 files changed

+842
-58
lines changed

10 files changed

+842
-58
lines changed

contributed/noise_add.rb

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
attr_reader :img
4+
5+
def settings
6+
size(1280, 640, P2D)
7+
end
8+
9+
def setup
10+
sketch_title 'Noise Add'
11+
blend_mode(ADD)
12+
background(0)
13+
puts('Image takes time to develop be patient...')
14+
end
15+
16+
def draw
17+
sc = 0.01 / (1 + frameCount / 30)
18+
img = create_image(width, height, RGB)
19+
img.load_pixels
20+
grid(width, height) do |x, y|
21+
nse = noise(x * sc, y * sc, frame_count * 0.02)
22+
img.pixels[x + y * width] = nse > 0.6 ? color(4, 2, 1) : color(0)
23+
end
24+
img.update_pixels
25+
image(img, 0, 0)
26+
end
27+
28+
def key_pressed
29+
return unless key == 's'
30+
31+
save_frame
32+
end
+17-35
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,39 @@
1-
#
2-
# Mirror
1+
# Mirror 2
32
# by Daniel Shiffman.
43
#
5-
# Each pixel from the video source is drawn as a rectangle with rotation
6-
# based on brightness.
7-
4+
# Each pixel from the video source is drawn as a rectangle with size based
5+
# on brightness.
86
load_library :video
9-
attr_reader :video, :cols, :rows
7+
java_import 'processing.video.Capture'
8+
attr_reader :video
109
# Size of each cell in the grid
11-
CELL_SIZE = 40
12-
java_alias :color_float, :color, [Java::float, Java::float, Java::float, Java::float]
10+
CELL_SIZE = 15
11+
OFFSET = CELL_SIZE / 2.0
1312

1413
def setup
1514
sketch_title 'mirror'
16-
frame_rate(30)
17-
@cols = width / CELL_SIZE
18-
@rows = height / CELL_SIZE
1915
colorMode(RGB, 255, 255, 255, 100)
20-
# This the default video input, try test_capture to find name of your Camera
21-
@video = Java::ProcessingVideo::Capture.new(self, 960, 720, "UVC Camera (046d:0825)")
22-
# Start capturing the images from the camera
16+
# Try test_capture to find the name of your Camera
17+
@video = Capture.new(self, width, height, 'UVC Camera (046d:0825)')
2318
video.start
24-
background(0)
2519
end
2620

2721
def draw
2822
return unless video.available # ruby guard clause
2923

24+
background(0, 0, 255)
3025
video.read
31-
video.loadPixels
32-
grid(width, height, cols, rows) do |x, y|
33-
loc = (video.width - x - 1) + y * video.width # Reversing x to mirror the image
34-
col = color_float(
35-
red(video.pixels[loc]),
36-
green(video.pixels[loc]),
37-
blue(video.pixels[loc]),
38-
75 # alpha
39-
)
40-
# Code for drawing a single rect
41-
# Using translate in order for rotation to work properly
42-
push_matrix
43-
translate(x + CELL_SIZE / 2, y + CELL_SIZE / 2)
44-
# Rotation formula based on brightness
45-
rotate((2 * PI * brightness(col) / 255.0))
26+
video.load_pixels
27+
grid(width, height, CELL_SIZE, CELL_SIZE) do |x, y|
28+
loc = (width - x - 1 + y * width) # Reversing x to mirror the image
29+
sz = brightness(video.pixels[loc]) / 255 * CELL_SIZE
4630
rect_mode(CENTER)
47-
fill(col)
31+
fill(255)
4832
no_stroke
49-
# Rects are larger than the cell for some overlap
50-
rect(0, 0, CELL_SIZE + 6, CELL_SIZE + 6)
51-
pop_matrix
33+
rect(x + OFFSET, y + OFFSET, sz, sz)
5234
end
5335
end
5436

5537
def settings
56-
size(960, 720)
38+
size(960, 544)
5739
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//jscottpilgrim
2+
//greyscale julia by distance estimator
3+
//distance estimation info: http://www.iquilezles.org/www/articles/distancefractals/distancefractals.htm
4+
5+
//fragment shader
6+
7+
#ifdef GL_ES
8+
precision highp float;
9+
precision mediump int;
10+
#endif
11+
12+
uniform vec2 resolution;
13+
14+
uniform vec2 center;
15+
uniform float zoom;
16+
17+
uniform vec2 juliaParam;
18+
19+
const int maxIterations = 250;
20+
21+
//double precision not natively supported in webgl/gl_es
22+
//emulated double precision from: https://gist.github.com/LMLB/4242936fe79fb9de803c20d1196db8f3
23+
//performance drops dramatically from single precision. drop number of iterations to balance performance and max zoom. maybe ~300
24+
25+
float times_frc(float a, float b) {
26+
return mix(0.0, a * b, b != 0.0 ? 1.0 : 0.0);
27+
}
28+
float plus_frc(float a, float b) {
29+
return mix(a, a + b, b != 0.0 ? 1.0 : 0.0);
30+
}
31+
float minus_frc(float a, float b) {
32+
return mix(a, a - b, b != 0.0 ? 1.0 : 0.0);
33+
}
34+
// Double emulation based on GLSL Mandelbrot Shader by Henry Thasler (www.thasler.org/blog)
35+
//
36+
// Emulation based on Fortran-90 double-single package. See http://crd.lbl.gov/~dhbailey/mpdist/
37+
// Addition: res = ds_add(a, b) => res = a + b
38+
vec2 add (vec2 dsa, vec2 dsb) {
39+
vec2 dsc;
40+
float t1, t2, e;
41+
t1 = plus_frc(dsa.x, dsb.x);
42+
e = minus_frc(t1, dsa.x);
43+
t2 = plus_frc(plus_frc(plus_frc(minus_frc(dsb.x, e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y);
44+
dsc.x = plus_frc(t1, t2);
45+
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
46+
return dsc;
47+
}
48+
// Subtract: res = ds_sub(a, b) => res = a - b
49+
vec2 sub (vec2 dsa, vec2 dsb) {
50+
vec2 dsc;
51+
float e, t1, t2;
52+
t1 = minus_frc(dsa.x, dsb.x);
53+
e = minus_frc(t1, dsa.x);
54+
t2 = minus_frc(plus_frc(plus_frc(minus_frc(minus_frc(0.0, dsb.x), e), minus_frc(dsa.x, minus_frc(t1, e))), dsa.y), dsb.y);
55+
dsc.x = plus_frc(t1, t2);
56+
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
57+
return dsc;
58+
}
59+
// Compare: res = -1 if a < b
60+
// = 0 if a == b
61+
// = 1 if a > b
62+
float cmp(vec2 dsa, vec2 dsb) {
63+
if (dsa.x < dsb.x) {
64+
return -1.;
65+
}
66+
if (dsa.x > dsb.x) {
67+
return 1.;
68+
}
69+
if (dsa.y < dsb.y) {
70+
return -1.;
71+
}
72+
if (dsa.y > dsb.y) {
73+
return 1.;
74+
}
75+
return 0.;
76+
}
77+
// Multiply: res = ds_mul(a, b) => res = a * b
78+
vec2 mul (vec2 dsa, vec2 dsb) {
79+
vec2 dsc;
80+
float c11, c21, c2, e, t1, t2;
81+
float a1, a2, b1, b2, cona, conb, split = 8193.;
82+
cona = times_frc(dsa.x, split);
83+
conb = times_frc(dsb.x, split);
84+
a1 = minus_frc(cona, minus_frc(cona, dsa.x));
85+
b1 = minus_frc(conb, minus_frc(conb, dsb.x));
86+
a2 = minus_frc(dsa.x, a1);
87+
b2 = minus_frc(dsb.x, b1);
88+
c11 = times_frc(dsa.x, dsb.x);
89+
c21 = plus_frc(times_frc(a2, b2), plus_frc(times_frc(a2, b1), plus_frc(times_frc(a1, b2), minus_frc(times_frc(a1, b1), c11))));
90+
c2 = plus_frc(times_frc(dsa.x, dsb.y), times_frc(dsa.y, dsb.x));
91+
t1 = plus_frc(c11, c2);
92+
e = minus_frc(t1, c11);
93+
t2 = plus_frc(plus_frc(times_frc(dsa.y, dsb.y), plus_frc(minus_frc(c2, e), minus_frc(c11, minus_frc(t1, e)))), c21);
94+
dsc.x = plus_frc(t1, t2);
95+
dsc.y = minus_frc(t2, minus_frc(dsc.x, t1));
96+
return dsc;
97+
}
98+
// create double-single number from float
99+
vec2 set(float a) {
100+
return vec2(a, 0.0);
101+
}
102+
float rand(vec2 co) {
103+
// implementation found at: lumina.sourceforge.net/Tutorials/Noise.html
104+
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
105+
}
106+
vec2 complexMul(vec2 a, vec2 b) {
107+
return vec2(a.x*b.x - a.y*b.y,a.x*b.y + a.y * b.x);
108+
}
109+
// double complex multiplication
110+
vec4 dcMul(vec4 a, vec4 b) {
111+
return vec4(sub(mul(a.xy,b.xy),mul(a.zw,b.zw)),add(mul(a.xy,b.zw),mul(a.zw,b.xy)));
112+
}
113+
// double complex addition
114+
vec4 dcAdd(vec4 a, vec4 b) {
115+
return vec4(add(a.xy,b.xy),add(a.zw,b.zw));
116+
}
117+
// Length of double complex
118+
vec2 dcLength(vec4 a) {
119+
return add(mul(a.xy,a.xy),mul(a.zw,a.zw));
120+
}
121+
// create double-complex from complex float
122+
vec4 dcSet(vec2 a) {
123+
return vec4(a.x,0.,a.y,0.);
124+
}
125+
//create double-complex from complex double
126+
vec4 dcSet(vec2 a, vec2 ad) {
127+
return vec4(a.x, ad.x,a.y,ad.y);
128+
}
129+
// Multiply double-complex with double
130+
vec4 dcMul(vec4 a, vec2 b) {
131+
return vec4(mul(a.xy,b),mul(a.wz,b));
132+
}
133+
134+
135+
void main()
136+
{
137+
vec4 uv = dcSet( gl_FragCoord.xy - resolution.xy * 0.5 );
138+
vec4 dcCenter = dcSet( center );
139+
140+
vec4 c = dcSet( juliaParam );
141+
vec4 z = dcAdd( dcMul( uv, set( zoom ) ), dcCenter );
142+
vec4 dz = dcSet( vec2( 1.0, 0.0 ) );
143+
bool escape = false;
144+
145+
float dotZZ = 0.0;
146+
147+
for ( int i = 0 ; i < maxIterations; i++ ) {
148+
//z' = 2 * z * z'
149+
//dz = 2.0 * vec2( z.x * dz.x - z.y * dz.y, z.x * dz.y + z.y * dz.x );
150+
dz = dcMul( dcMul( z, dz ), set( 2.0 ) );
151+
152+
//mandelbrot function on z
153+
//z = c + complexSquare( z );
154+
z = dcAdd( c, dcMul( z, z ) );
155+
156+
//escape radius 32^2
157+
//if ( dot( z, z ) > 1024.0 )
158+
//lowered to compensate for emulated double computation speed
159+
dotZZ = z.x * z.x + z.z * z.z; // extract high part
160+
if( dotZZ > 400.0 )
161+
{
162+
escape = true;
163+
break;
164+
}
165+
}
166+
167+
vec3 color = vec3( 1.0 );
168+
169+
if ( escape )
170+
{
171+
//distance
172+
//d(c) = (|z|*log|z|)/|z'|
173+
174+
float dotDZDZ = dz.x * dz.x + dz.z * dz.z; // extract high part
175+
176+
float d = sqrt( dotZZ );
177+
d *= log( d );
178+
d /= sqrt( dotDZDZ );
179+
180+
d = clamp( pow( 4.0 * d, 0.1 ), 0.0, 1.0 );
181+
182+
color = vec3( d );
183+
}
184+
else
185+
{
186+
//set inside points to inside color
187+
color = vec3( 0.0 );
188+
}
189+
190+
gl_FragColor = vec4( color, 1.0 );
191+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//jscottpilgrim
2+
//greyscale julia by distance estimator
3+
//distance estimation info: http://www.iquilezles.org/www/articles/distancefractals/distancefractals.htm
4+
5+
//fragment shader
6+
7+
#ifdef GL_ES
8+
precision mediump float;
9+
precision mediump int;
10+
#endif
11+
12+
uniform vec2 resolution;
13+
14+
uniform vec2 center;
15+
uniform float zoom;
16+
17+
uniform vec2 juliaParam;
18+
19+
const int maxIterations = 1000;
20+
21+
vec2 complexSquare( vec2 v ) {
22+
return vec2(
23+
v.x * v.x - v.y * v.y,
24+
v.x * v.y * 2.0
25+
);
26+
}
27+
28+
29+
void main()
30+
{
31+
vec2 uv = gl_FragCoord.xy - resolution.xy * 0.5;
32+
33+
bool escape = false;
34+
vec2 c = juliaParam;
35+
vec2 z = uv * zoom + center;
36+
vec2 dz = vec2( 1.0, 0.0 );
37+
38+
for ( int i = 0 ; i < maxIterations; i++ ) {
39+
//z' = 2 * z * z'
40+
dz = 2.0 * vec2( z.x * dz.x - z.y * dz.y, z.x * dz.y + z.y * dz.x );
41+
42+
//mandelbrot function on z
43+
z = c + complexSquare( z );
44+
45+
//higher escape radius for detail, 32^2
46+
if ( dot( z, z ) > 1024.0 )
47+
{
48+
escape = true;
49+
break;
50+
}
51+
}
52+
53+
vec3 color = vec3( 1.0 );
54+
55+
if ( escape )
56+
{
57+
//distance
58+
//d(c) = (|z|*log|z|)/|z'|
59+
60+
//idk why inigo uses this formula. optimization of distance estimation?
61+
//float d = 0.5*sqrt(dot(z,z)/dot(dz,dz))*log(dot(z,z));
62+
63+
float d = sqrt( dot( z, z ) );
64+
d *= log( sqrt( dot( z, z ) ) );
65+
d /= sqrt( dot( dz, dz ) );
66+
67+
d = clamp( pow( 4.0 * d, 0.1 ), 0.0, 1.0 );
68+
69+
color = vec3( d );
70+
}
71+
else
72+
{
73+
//set inside points to inside color
74+
color = vec3( 0.0 );
75+
}
76+
77+
gl_FragColor = vec4( color, 1.0 );
78+
}

0 commit comments

Comments
 (0)