Skip to content

Instantly share code, notes, and snippets.

@chasemarangu
Last active December 10, 2019 09:32
Show Gist options
  • Save chasemarangu/6a3a20a69caea821bf4fad1238a68de6 to your computer and use it in GitHub Desktop.
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
/**
* 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