|
| 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 | +} |
0 commit comments