Skip to content

Commit 9a2a026

Browse files
committed
droste capture
1 parent ad1b0cb commit 9a2a026

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// This implementation is based on GLSL code by ArKano22:
2+
// http://www.gamedev.net/topic/590070-glsl-droste/
3+
uniform float globalTime;
4+
uniform sampler2D texture; // iChannel0 in Shadertoy
5+
uniform vec2 sketchSize; // iResolution in Shadertoy
6+
uniform int mode;
7+
8+
const float TWO_PI = 3.141592*2.0;
9+
//ADJUSTABLE PARAMETERS:
10+
const float Branches = 1.0;
11+
const float scale = 0.4;
12+
const float off = 0.6;
13+
//Complex Math:
14+
vec2 complexExp(in vec2 z){
15+
return vec2(exp(z.x)*cos(z.y),exp(z.x)*sin(z.y));
16+
}
17+
vec2 complexLog(in vec2 z){
18+
return vec2(log(length(z)), atan(z.y, z.x));
19+
}
20+
vec2 complexMult(in vec2 a,in vec2 b){
21+
return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
22+
}
23+
float complexMag(in vec2 z){
24+
return float(pow(length(z), 2.0));
25+
}
26+
vec2 complexReciprocal(in vec2 z){
27+
return vec2(z.x / complexMag(z), -z.y / complexMag(z));
28+
}
29+
vec2 complexDiv(in vec2 a,in vec2 b){
30+
return complexMult(a, complexReciprocal(b));
31+
}
32+
vec2 complexPower(in vec2 a, in vec2 b){
33+
return complexExp( complexMult(b,complexLog(a)) );
34+
}
35+
//Misc Functions:
36+
float nearestPower(in float a, in float base){
37+
return pow(base, ceil( log(abs(a))/log(base) )-1.0 );
38+
}
39+
float map(float value, float istart, float istop, float ostart, float ostop) {
40+
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
41+
}
42+
43+
void main( void ){
44+
45+
//SHIFT AND SCALE COORDINATES
46+
vec2 uv=gl_FragCoord.xy/sketchSize.xy - off;
47+
48+
//ESCHER GRID TRANSFORM:
49+
float factor = pow(1.0/scale,Branches);
50+
uv= complexPower(uv, complexDiv(vec2( log(factor) ,TWO_PI), vec2(0.0,TWO_PI) ) );
51+
52+
//RECTANGULAR DROSTE EFFECT:
53+
float FT = fract(globalTime);
54+
FT = log(FT+1.)/log(2.);
55+
uv *= 1.0+FT*(scale-1.0);
56+
57+
float npower = max(nearestPower(uv.x,scale),nearestPower(uv.y,scale));
58+
uv.x = map(uv.x,-npower,npower,-1.0,1.0);
59+
uv.y = map(uv.y,-npower,npower,-1.0,1.0);
60+
61+
//UNDO SHIFT AND SCALE:
62+
gl_FragColor = texture(texture,uv*off+vec2(off));
63+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
load_library :glvideo
2+
include_package 'gohai.glvideo'
3+
attr_reader :cam, :my_filter, :origin
4+
5+
def settings
6+
size(1280, 960, P2D)
7+
end
8+
9+
def setup
10+
sketch_title 'Droste'
11+
@origin = Time.now
12+
@my_filter = load_shader(data_path('droste.glsl'))
13+
my_filter.set('sketchSize', width.to_f, height.to_f)
14+
start_capture
15+
end
16+
17+
def time
18+
(Time.now - origin) * 0.5
19+
end
20+
21+
def start_capture
22+
@cam = GLCapture.new(self)
23+
cam.start
24+
end
25+
26+
def draw
27+
background 0
28+
cam.read if cam.available
29+
image(cam, 0, 0, width, height)
30+
my_filter.set('globalTime', time)
31+
return if mouse_pressed?
32+
filter(my_filter)
33+
end

0 commit comments

Comments
 (0)