Last active
December 10, 2019 09:32
-
-
Save chasemarangu/6a3a20a69caea821bf4fad1238a68de6 to your computer and use it in GitHub Desktop.
2.5D animation of some shiny blue material https://twitter.com/c010011012/status/1204332564271337472
This file contains hidden or 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
/** | |
* Glittery Hills | |
* C010011012 (@cmarangu) 2019 12/8 | |
* Looped animation inspired by Eteinne Jacob | |
* works in Processing.org (download) | |
**/ | |
float arg; | |
float altarg; | |
// 3D projection | |
float[] xy (float x, float y, float z) { | |
return new float[]{ | |
x/(1+z/1.0)*255*1.7+255, | |
-y/(1+z/1.0)*255*2.3+255 | |
}; | |
} | |
// y-repeating white noise | |
float wnoise (float mx, float my) { | |
// see the %= 3? that means every 3 y will be te same value | |
// for the same value in x. useful for loop animation ;) | |
my %= 3; | |
my += 6; | |
return ((100*1e4+mx*mx*13+mx*7+my*6+my*mx*3+my*my*5)%100)/100; | |
} | |
// y-repeating gradient noise from y-repeating white noise | |
float gnoise (float x, float y) { | |
float mx = (100+x)%1; | |
float my = (100+y)%1; | |
mx = 3*mx*mx-2*mx*mx*mx; | |
my = 3*my*my-2*my*my*my; | |
x = floor(x); | |
y = floor(y); | |
return lerp( | |
lerp(wnoise(x, y), wnoise(x+1, y), mx), | |
lerp(wnoise(x, y+1), wnoise(x+1, y+1), mx), | |
my | |
); | |
} | |
// y-repeating fractal noise from y-repeating gradient noise | |
float fnoise (float x, float y) { | |
float amp = 0.5; | |
float fre = 1; | |
float wav = 0; | |
x += 60; | |
y += 200; | |
for (int i=0; i<3; ++i) { | |
wav += amp*gnoise(x*fre, y*fre); | |
fre *= 2; | |
amp /= 2; | |
} | |
return wav; | |
} | |
// height map | |
float h (float x, float z) { | |
//return sin(z*PI+arg*TWO_PI)* | |
// sin(x+z)*0.2+ | |
// -1+ | |
// x*x/16+ | |
// 0*((z > 7) ? -pow(z-7, 2) : 0); | |
return -3.3+fnoise(x/3+z/4, z/2+arg*3)*2+pow(1.3, z-6)+ | |
0;//((z>40)?pow(z-40, 1.5):0); | |
} | |
PVector sund; | |
PVector surfn; | |
PVector leg12; | |
PVector leg23; | |
PVector refl; | |
// stuff | |
// rasterizes a triangle in 3D coordinates, lit according to view direction | |
// as well as its own reflection direction and the sun direction | |
void tri (PVector pt1, PVector pt2, PVector pt3, PVector vd) { | |
sund = PVector.sub(pt1, new PVector(-1, -16, 7)); | |
sund.normalize(); | |
float[] pt1xy = xy(pt1.x, pt1.y, pt1.z); | |
float[] pt2xy = xy(pt2.x, pt2.y, pt2.z); | |
float[] pt3xy = xy(pt3.x, pt3.y, pt3.z); | |
strokeWeight(1/(1+pt1.z)); | |
leg12 = PVector.sub(pt1, pt2); | |
leg23 = PVector.sub(pt2, pt3); | |
// surfn PVector.cross(leg12, leg13); | |
surfn = leg12.cross(leg23); | |
surfn.normalize(); | |
float lit = PVector.dot(surfn, sund); | |
// specular highlighting --and also diffuse light | |
// I am using the phong model on 2D ;P I am testing | |
// combining effects from raymarching | |
// with my previous skills lol it worked tho | |
refl = PVector.sub(vd, surfn.mult(2*PVector.dot(surfn, vd)) ); | |
refl.normalize(); | |
float spec = constrain( | |
PVector.dot( | |
refl, | |
sund | |
), | |
0, | |
1 | |
); | |
spec = 0.6*pow(spec, 5)+0.4*pow(spec, 70); | |
color col = lerpColor(color(0, 0, 110), color(0, 0, 200), lit ); | |
float r = red(col); | |
float g = green(col); | |
float b = blue(col); | |
r += spec*255; | |
g += spec*255; | |
b += spec*255; | |
col = color(r, g, b); | |
fill(col); | |
triangle( | |
pt1xy[0], pt1xy[1], | |
pt2xy[0], pt2xy[1], | |
pt3xy[0], pt3xy[1] | |
); | |
} | |
// general loop animation code | |
float FRAMES = 30; | |
float C = 0; | |
PImage[] imgs = new PImage[int(FRAMES)]; | |
float zChunks = 5; | |
float zSECTOR = zChunks*20; | |
float zSectorTWO = zSECTOR; | |
void setup () { | |
size(510, 510); | |
sund = new PVector(-0.7, 1, -0.5); | |
sund.normalize(); | |
} | |
// below is the code that helps draw the main object | |
// using the lit triangle drawer function | |
float iw = 5; | |
float lx, lz; | |
float oz=0, ox=0, oy=0; | |
PVector pta, ptb, ptc, ptd, viewd; | |
boolean firstx, firstz; | |
void drawiz (float ix, boolean revers) { | |
lx = ix/iw; | |
firstz = true; | |
for (float iz=zSECTOR+zChunks; iz>=zSECTOR; --iz) { | |
lx = (ix+arg*0)/iw; | |
lz = (iz-arg*1)/iw; | |
float[] pt = xy(lx, h(lx, lz), lz); | |
if (pt[0] > -40 && pt[0] < width+100 && pt[1] < height+100 && lz >= 0) { | |
if (!firstx && !firstz) { | |
if (revers) { | |
pta = new PVector(lx, h(lx, lz), lz); | |
ptb = new PVector(ox, h(ox, lz), lz); | |
ptc = new PVector(lx, h(lx, oz), oz); | |
ptd = new PVector(ox, h(ox, oz), oz); | |
} | |
else { | |
pta = new PVector(ox, h(ox, lz), lz); | |
ptb = new PVector(lx, h(lx, lz), lz); | |
ptc = new PVector(ox, h(ox, oz), oz); | |
ptd = new PVector(lx, h(lx, oz), oz); | |
} | |
viewd = new PVector(lx/2+ox/2, h(lx/2+ox/2, lz/2+oz/2), lz/2+oz/2); | |
viewd.normalize(); | |
// stroke(70, 170, 255); | |
stroke(0, 255, 255); | |
tri(pta, ptb, ptc, viewd); | |
tri(ptb, ptd, ptc, viewd); | |
} | |
float[] pt2 = xy(ox, h(ox, oz), oz); | |
strokeWeight(max(15/(1+lz), 2)); | |
stroke(100, 230, 255); | |
point(pt2[0], pt2[1]); | |
point(pt[0], pt[1]); | |
} | |
firstz = false; | |
oz = lz; | |
oy = h(lx, lz); | |
} | |
firstx = false; | |
ox = lx; | |
} | |
void draw () { | |
if (C <= FRAMES) { | |
arg = (C%FRAMES)/FRAMES; | |
if (zSECTOR == zSectorTWO) { | |
background(0, 0, 155); | |
noStroke(); | |
for (float gy=255; gy<510; gy+=3) { | |
fill(lerpColor(color(0, 0, 155), color(0, 255, 255), (gy-255)/255) ); | |
rect(0, gy, 510, 3); | |
} | |
} | |
firstx = true; | |
for (float ix=-iw*16; ix<=0; ++ix) { | |
drawiz(ix, true); | |
} | |
for (float ix=iw*16; ix>=0; --ix) { | |
drawiz(ix, false); | |
} | |
zSECTOR -= zChunks; | |
if (zSECTOR <= 0) { | |
zSECTOR = zSectorTWO; | |
imgs[int(C%FRAMES)] = get(0, 0, width, height); | |
// saveFrame("c#######.gif"); | |
C++; | |
} | |
} | |
else { | |
// preview mode | |
image(imgs[int(C%FRAMES)], 0, 0); | |
C++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment