Created
June 9, 2014 09:15
-
-
Save AdmiralPotato/c5572e6d3aebdf17a22d 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
//configurable variables | |
boolean | |
exportMode = true; //set to true when exporting, false when designing | |
String | |
folderPrefix = "b"; | |
int | |
fps = 24, | |
outputScale = 2, //set to 2 or 4 when exporting, 1 when designing | |
windowSize = 480 * outputScale, | |
numFrames = 48, | |
samplesPerFrame = 64; //set to 64 or 128 when exporting, 4 or 8 when designing | |
float | |
motionBlurFactor = 1.0; | |
//you should probably leave these variables alone | |
int | |
currentFrame = 0, | |
preserveAlpha = 0xff000000; | |
int[][] | |
motionBlurBuffer; | |
float | |
time = 0, | |
half = windowSize / 2, | |
pi = PI, | |
tau = pi * 2.0, | |
deg = pi / 180.0; | |
int | |
numStaticDots = 18, | |
numOrbitingDots = 3; | |
float | |
lumBling = 1.0, | |
lumLine = 1, | |
staticDotRotaryOffset = tau / (float) numStaticDots, | |
orbitingDotRotaryOffset = tau / (float) numOrbitingDots; | |
StaticDot[] staticDotList = new StaticDot[numStaticDots]; | |
OrbitingDot[] orbitingDotList = new OrbitingDot[numOrbitingDots]; | |
float range(float startPoint, float stopPoint, float value){ | |
return min(1, max(0, map(value, startPoint, stopPoint, 0.0, 1.0))); | |
} | |
//reference: https://github.com/sole/tween.js/blob/master/src/Tween.js | |
float sinusoidalInOut(float k){ | |
return 0.5 * ( 1.0 - cos( pi * k ) ); | |
} | |
float cubicIn(float k){ | |
return k * k * k; | |
} | |
float cubicOut(float k){ | |
return --k * k * k + 1; | |
} | |
float cubicInOut(float k){ | |
if ( ( k *= 2.0 ) < 1.0 ) return 0.5 * k * k * k; | |
return 0.5 * ( ( k -= 2.0 ) * k * k + 2.0 ); | |
} | |
class OrbitingDot{ | |
int index; | |
float | |
distanceFromCenter = 120, | |
maxLineDistance = 200, | |
minLineDistance = 50, | |
maxRadiusDistance = 100, | |
minRadiusDistance = 30, | |
outerRadius = 15, | |
rotaryOffset, | |
x, y, | |
innerRadius; | |
OrbitingDot(int id){ | |
index = id; | |
} | |
void update(){ | |
int i; | |
float | |
distance, | |
fractionalOpacity, | |
fractionalRadius; | |
StaticDot staticDot; | |
rotaryOffset = tau / 3 * time + ((float)index * orbitingDotRotaryOffset); | |
x = cos(rotaryOffset) * distanceFromCenter; | |
y = sin(rotaryOffset) * distanceFromCenter; | |
for (i = 0; i < staticDotList.length; i++) { | |
staticDot = staticDotList[i]; | |
distance = dist(x, y, staticDot.x, staticDot.y); | |
fractionalOpacity = cubicOut(range(maxLineDistance, minLineDistance, distance)); | |
fractionalRadius = cubicIn(range(maxRadiusDistance, minRadiusDistance, distance)); | |
noFill(); | |
stroke(lumLine, fractionalOpacity); | |
line(x, y, staticDot.x, staticDot.y); | |
staticDot.innerRadius += fractionalRadius * staticDot.outerRadius; | |
} | |
} | |
void draw(){ | |
pushMatrix(); | |
translate(0,0,1); | |
stroke(lumBling); | |
fill(0, 1, lumBling); | |
ellipse(x, y, outerRadius, outerRadius); | |
popMatrix(); | |
} | |
}; | |
class StaticDot{ | |
int index; | |
float | |
distanceFromCenter = 160, | |
outerRadius = 25, | |
innerRadiusMin = 2, | |
rotaryOffset, | |
x, y, | |
innerRadius, | |
saturation; | |
StaticDot(int id){ | |
index = id; | |
rotaryOffset = (float)index * staticDotRotaryOffset; | |
x = cos(rotaryOffset) * distanceFromCenter; | |
y = sin(rotaryOffset) * distanceFromCenter; | |
innerRadius = innerRadiusMin; | |
saturation = 0.5; | |
} | |
void update(){ | |
innerRadius = innerRadiusMin; | |
} | |
void draw(){ | |
pushMatrix(); | |
translate(0,0,1); | |
noStroke(); | |
//cut an alpha 1.0 hole out of existing image | |
fill(1, -1); | |
ellipse(x, y, outerRadius, outerRadius); | |
translate(0,0,1); | |
noFill(); | |
stroke(lumLine); | |
ellipse(x, y, outerRadius, outerRadius); | |
noStroke(); | |
fill(lumBling); | |
ellipse(x, y, innerRadius, innerRadius); | |
popMatrix(); | |
} | |
}; | |
float | |
staticEllipseSize = 160, | |
staticEllipseSpread = 5; | |
void sample(){ | |
int i; | |
OrbitingDot orbitingDot; | |
StaticDot staticDot; | |
colorMode(HSB, 1.0); | |
clear(); | |
//means that output matte is white instead of black. | |
//background(0,0,1,-1); | |
strokeWeight(2); | |
ellipseMode(RADIUS); | |
noFill(); | |
stroke(lumLine); | |
//ellipse(0, 0, staticEllipseSize, staticEllipseSize); | |
ellipse(0, 0, staticEllipseSize - staticEllipseSpread, staticEllipseSize - staticEllipseSpread); | |
ellipse(0, 0, staticEllipseSize + staticEllipseSpread, staticEllipseSize + staticEllipseSpread); | |
ellipseMode(CENTER); | |
for (i = 0; i < orbitingDotList.length; i++) { | |
orbitingDot = orbitingDotList[i]; | |
orbitingDot.update(); | |
orbitingDot.draw(); | |
} | |
for (i = 0; i < staticDotList.length; i++) { | |
staticDot = staticDotList[i]; | |
staticDot.draw(); | |
staticDot.update(); | |
} | |
} | |
void setup() { | |
int i; | |
size(windowSize, windowSize, P3D); | |
ortho(); | |
frameRate(fps); | |
smooth(8); | |
motionBlurBuffer = new int[width * height][4]; | |
for (i = 0; i < numOrbitingDots; i++) { | |
orbitingDotList[i] = new OrbitingDot(i); | |
} | |
for (i = 0; i < numStaticDots; i++) { | |
staticDotList[i] = new StaticDot(i); | |
} | |
} | |
void draw(){ | |
pushMatrix(); | |
translate(half, half); | |
scale(outputScale); | |
multiSample(); | |
popMatrix(); | |
if(exportMode){ | |
saveFrame(folderPrefix + "-" + numFrames + "/####.png"); | |
} | |
currentFrame++; | |
if(exportMode && currentFrame >= numFrames){ | |
exit(); | |
} | |
time = (float) currentFrame / numFrames; | |
} | |
void multiSample(){ | |
int | |
pixelIndex, | |
channelIndex, | |
sampleIndex; | |
if(samplesPerFrame < 2){ | |
sample(); | |
} | |
else { | |
//set the motionBlurBuffer back to empty | |
for (pixelIndex = 0; pixelIndex < width * height; pixelIndex++){ | |
for (channelIndex = 0; channelIndex < 4; channelIndex++){ | |
motionBlurBuffer[pixelIndex][channelIndex] = 0; | |
} | |
} | |
for (sampleIndex = 0; sampleIndex < samplesPerFrame; sampleIndex++) { | |
time = map( | |
currentFrame + ((sampleIndex * motionBlurFactor) / samplesPerFrame), // value | |
0, //start1 | |
numFrames, //stop1 | |
0, //start2 | |
1 //stop2 | |
); | |
sample(); | |
loadPixels(); | |
for (int i=0; i<pixels.length; i++) { | |
motionBlurBuffer[i][0] += pixels[i] >> 24 & 0xff; //alpha | |
motionBlurBuffer[i][1] += pixels[i] >> 16 & 0xff; //red | |
motionBlurBuffer[i][2] += pixels[i] >> 8 & 0xff; //green | |
motionBlurBuffer[i][3] += pixels[i] & 0xff; //blue | |
} | |
} | |
loadPixels(); | |
for(pixelIndex = 0; pixelIndex < pixels.length; pixelIndex++){ | |
pixels[pixelIndex] = | |
(motionBlurBuffer[pixelIndex][0]/samplesPerFrame) << 24 | //alpha | |
(motionBlurBuffer[pixelIndex][1]/samplesPerFrame) << 16 | //red | |
(motionBlurBuffer[pixelIndex][2]/samplesPerFrame) << 8 | //green | |
(motionBlurBuffer[pixelIndex][3]/samplesPerFrame); //blue | |
//invert and preserveAlpha | |
//preserveAlpha = pixels[pixelIndex] >> 24 & 0xff; | |
//pixels[pixelIndex] = (~pixels[pixelIndex]) & 0x00ffffff | (preserveAlpha << 24); | |
} | |
updatePixels(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment