Created
December 10, 2021 19:12
-
-
Save Bleuje/a09b0acdf8dc0f6caeaf850216a9700d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Processing code by Etienne JACOB | |
// motion blur template by beesandbombs | |
int[][] result; | |
float t, c; | |
float ease(float p) { | |
return 3*p*p - 2*p*p*p; | |
} | |
float ease(float p, float g) { | |
if (p < 0.5) | |
return 0.5 * pow(2*p, g); | |
else | |
return 1 - 0.5 * pow(2*(1 - p), g); | |
} | |
float softplus(float q,float p){ | |
float qq = q+p; | |
if(qq<=0){ | |
return 0; | |
} | |
if(qq>=2*p){ | |
return qq-p; | |
} | |
return 1/(4*p)*qq*qq; | |
} | |
float mn = .5*sqrt(3), ia = atan(sqrt(.5)); | |
void push() { | |
pushMatrix(); | |
pushStyle(); | |
} | |
void pop() { | |
popStyle(); | |
popMatrix(); | |
} | |
void draw() { | |
if (!recording) { | |
t = (mouseX*1.3/width)%1; | |
//t = map(mouseX,0,width,0.95,1.05)%1; | |
c = mouseY*1.0/height; | |
if (mousePressed) | |
println(c); | |
draw_(); | |
} else { | |
for (int i=0; i<width*height; i++) | |
for (int a=0; a<3; a++) | |
result[i][a] = 0; | |
c = 0; | |
for (int sa=0; sa<samplesPerFrame; sa++) { | |
t = map(frameCount-1 + sa*shutterAngle/samplesPerFrame, 0, numFrames, 0, 1); | |
draw_(); | |
loadPixels(); | |
for (int i=0; i<pixels.length; i++) { | |
result[i][0] += pixels[i] >> 16 & 0xff; | |
result[i][1] += pixels[i] >> 8 & 0xff; | |
result[i][2] += pixels[i] & 0xff; | |
} | |
} | |
loadPixels(); | |
for (int i=0; i<pixels.length; i++) | |
pixels[i] = 0xff << 24 | | |
int(result[i][0]*1.0/samplesPerFrame) << 16 | | |
int(result[i][1]*1.0/samplesPerFrame) << 8 | | |
int(result[i][2]*1.0/samplesPerFrame); | |
updatePixels(); | |
if (frameCount<=numFrames) | |
{ | |
saveFrame("fr###.gif"); | |
println(frameCount,"/",numFrames); | |
} | |
if (frameCount==numFrames) | |
stop(); | |
} | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
int samplesPerFrame = 6; | |
int numFrames = 300; | |
float shutterAngle = 1.7; | |
boolean recording = true; | |
int n = 32; | |
class IntegerPair | |
{ | |
int x,y; | |
IntegerPair(int x_,int y_) | |
{ | |
x = x_; | |
y = y_; | |
} | |
} | |
// Hilbert curve algo from wikipedia | |
//convert d to (x,y) | |
IntegerPair d2xy(int n, int d) { | |
if(d<0) return new IntegerPair(0,d); | |
if(d>=n*n) return new IntegerPair(n-1,-(d-n*n)-1); | |
int rx, ry, s, t=d; | |
int x,y; | |
x = 0; | |
y = 0; | |
for (s=1; s<n; s*=2) { | |
rx = 1 & (t/2); | |
ry = 1 & (t ^ rx); | |
IntegerPair res = rot(s, new IntegerPair(x,y), rx, ry); | |
x = res.x; | |
y = res.y; | |
x += s * rx; | |
y += s * ry; | |
t /= 4; | |
} | |
return new IntegerPair(x,y); | |
} | |
//rotate/flip a quadrant appropriately | |
IntegerPair rot(int n, IntegerPair input, int rx, int ry) { | |
int x = input.x; | |
int y = input.y; | |
if (ry == 0) { | |
if (rx == 1) { | |
x = n-1 - x; | |
y = n-1 - y; | |
} | |
//Swap x and y | |
int t = x; | |
x = y; | |
y = t; | |
} | |
return new IntegerPair(x,y); | |
} | |
PVector perEase(float param) | |
{ | |
float frac = param-floor(param); | |
float speed = 2.8; | |
float cs = constrain(speed*frac,0,1); | |
float res = floor(param)+ease(cs,2.8); | |
float res2 = sin(PI*cs); | |
return new PVector(res,res2); | |
} | |
PVector pixelpos(int ix,int iy) | |
{ | |
float w = 130; | |
float x = map(ix,0,n-1,w,width-w)-width/2; | |
float y = map(iy,0,n-1,w,height-w)-height/2; | |
return new PVector(x,y); | |
} | |
PVector position(float p) | |
{ | |
int ind1 = floor(p); | |
int ind2 = ind1+1; | |
IntegerPair ipos1 = d2xy(n,ind1); | |
IntegerPair ipos2 = d2xy(n,ind2); | |
PVector v1 = pixelpos(ipos1.x,ipos1.y); | |
PVector v2 = pixelpos(ipos2.x,ipos2.y); | |
PVector res = v1.copy().lerp(v2,p-ind1); | |
return res; | |
} | |
PVector position2(float q,float offset) | |
{ | |
float p = map(q,0,1,0,n*n); | |
return position(p+offset); | |
} | |
float easeOutElastic(float x) | |
{ | |
float c4 = (2*PI)/3; | |
if(x<=0) return 0; | |
if(x>=1) return 1; | |
return pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1; | |
} | |
void showDots(float tt,float offset) | |
{ | |
int K = n*n/4; | |
for(int i=-10;i<K+10;i++) | |
{ | |
float p = (i+tt)/K; | |
float delay = 7*(1-p); | |
PVector movement = perEase(tt-delay); | |
float q = (i + movement.x)/K; | |
float intensity = pow(movement.y,5.0); | |
PVector pos = position2(q,offset); | |
float sz = 10; | |
intensity = easeOutElastic(intensity); | |
push(); | |
translate(pos.x,pos.y); | |
stroke(255); | |
strokeWeight(1.0); | |
fill(0); | |
ellipse(0,0,sz-5*intensity,sz-5*intensity); | |
strokeWeight(1.5+(sz-5)*intensity); | |
if(offset==0)point(0,0); | |
pop(); | |
} | |
} | |
void setup(){ | |
size(600,600,P3D); | |
result = new int[width*height][3]; | |
} | |
void draw_(){ | |
background(0); | |
push(); | |
translate(width/2,height/2); | |
scale(1.3); | |
translate(0,0,-1); | |
stroke(180); | |
strokeWeight(0.8); | |
noFill(); | |
beginShape(); | |
for(int i=-10;i<n*n+10;i++) | |
{ | |
IntegerPair ipos = d2xy(n,i); | |
PVector pos = pixelpos(ipos.x,ipos.y); | |
vertex(pos.x,pos.y); | |
} | |
endShape(); | |
translate(0,0,1); | |
showDots(t,0); | |
showDots(t+8.0/(n*n),2); | |
pop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment