Have been trying to figure out how to rectify Escher's prententoonstelling for a while now. With some nice happy accidents along the way
Log in to post a comment.
#version 300 es precision highp float; uniform float iTime; uniform vec2 iResolution; out vec4 fragColor; #define PI 3.14159265359 #define gamma 22.5836845297 uniform float Inverse; // value = 0.0, min=0.0, max=1.0 step=1.0 (No, Yes) uniform float Animate; // value = 0.0, min=0.0, max=1.0 step=1.0 (No, Yes) uniform float DeformationScale; // value=1.0, min=0.0, max=1.0, step=0.01 uniform float Droste; // value=22.58368, min=1.0, max=256.0, step=0.00001 float deformationScale; float d16 = 1./16.; float td16 = 2./16.; // Complex operators from Roy Wiggins vec2 cMul(vec2 a, vec2 b) { return vec2( a.x*b.x - a.y*b.y,a.x*b.y + a.y * b.x); } vec2 cInverse(vec2 a) { return vec2(a.x,-a.y)/dot(a,a); } vec2 cDiv(vec2 a, vec2 b) { return cMul( a,cInverse(b)); } vec2 cExp(in vec2 z){ return vec2(exp(z.x)*cos(z.y),exp(z.x)*sin(z.y)); } vec2 cLog(vec2 a) { float b = atan(a.y,a.x); // 0.4 adjustment rotation return vec2(log(length(a)),b + 0.4*deformationScale/256.); } vec2 escher(vec2 z) { z = cLog(z); if(Animate>0.0){ z.y -= iTime/2.; } // Multiply by inverse of h formula paper vec2 denom = cDiv(vec2(log(deformationScale), 2.0*PI), vec2(0,2.0*PI)); z = cMul(denom, z); //z.x = mod(z.x-iTime,log(256.)); z = cExp(z); return z; } // From Reinder's prentententoonstellingd16, td16, d16 vec3 droste(vec2 z ) { float t = Droste; float changed = 0.0; for( int i=0; i<3; i++ ) { if(any(greaterThan(abs(z),vec2(1.)))) { z *= (1./t); changed = 1.0; } if(all(lessThan(abs(z),vec2(1./t)))) { z *= t; changed = 1.0; } } return vec3(z, changed); } vec2 escher_inverse(vec2 z) { z = cLog(z); if(Animate>0.0){ z.y -= iTime/2.; } vec2 denom = cDiv(vec2(log(deformationScale), 2.0*PI), vec2(0,2.0*PI)); z = cDiv(z, denom); //z.x = mod(z.x,log(256.)); z = cExp(z); return z; } void main() { deformationScale = pow(DeformationScale, 2.) * 255. + 1.; float[] gaussian = float[] (d16, td16, d16, td16, 4./16., td16, d16, td16, d16); vec3 col = vec3(0.); for (int x=-1; x<=1; x++) { for (int y=-1; y<=1; y++) { vec2 z = (2. * gl_FragCoord.xy + vec2(x, y) - iResolution) / iResolution.y; //z = escher(z); if(Inverse>0.0){ z = escher_inverse(z); } else{ z = escher(z); } vec3 dro; dro = droste(z); if(dro.z>0.0){ col *= vec3(1.0,0.0,0.0); } z = vec2(dro.x, dro.y); z = .5 + .5*z; //mod(z,1.0); z = sin(z*20.0)*10.; col += gaussian[(x+1)*3 + (y+1)]*vec3(z.x*z.y)*0.12; } } fragColor = vec4( col, 1.0); }