Skip to content

Instantly share code, notes, and snippets.

@felipetavares
Last active October 20, 2019 01:04
Show Gist options
  • Save felipetavares/249051d0aa7572d31fc43b5f41f0f357 to your computer and use it in GitHub Desktop.
Save felipetavares/249051d0aa7572d31fc43b5f41f0f357 to your computer and use it in GitHub Desktop.
Tetrahedron fractals with raymarching. Camera & ambient occlusion. View with https://github.com/Gargaj/Bonzomatic
#version 450 core
uniform float fGlobalTime; // in seconds
uniform vec2 v2Resolution; // viewport resolution (in pixels)
uniform sampler1D texFFT; // towards 0.0 is bass / lower freq, towards 1.0 is higher / treble freq
uniform sampler1D texFFTSmoothed; // this one has longer falloff and less harsh transients
uniform sampler1D texFFTIntegrated; // this is continually increasing
layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything
#define steps 16
#define iters 8
mat2 rot(float a) {
return mat2(
cos(a), -sin(a),
sin(a), cos(a)
);
}
float sphere(vec3 p, vec3 o, float r) {
return length(p-o) - r;
}
float tetrahedron(vec3 p, vec3 o) {
vec3 v[4] = {
vec3(1, 1, 1),
vec3(-1, -1, 1),
vec3(-1, 1, -1),
vec3(1, -1, -1),
};
int c;
float d;
p.xy *= rot(fGlobalTime*0.1+sin(length(o)));
p.xz *= rot(fGlobalTime*0.1+cos(length(o)));
for (int i=0;i<iters;i++) {
c = 0;
d = length(p-v[c]);
for (int j=0;j<4;j++) {
float tmp = length(p-v[j]);
if (tmp < d) {
d = tmp;
c = j;
}
}
p = 2.0*p-v[c];
}
return length(p)*pow(2.0, -iters);
}
float estimator(vec3 p) {
vec3 modp = mod(p, 4) - 2;
//return sphere(p, vec3(0), 1);
return tetrahedron(modp, p);
}
#define eps 0.5
vec3 normal(vec3 p) {
vec3 x = vec3(eps, 0, 0);
vec3 y = vec3(0, eps, 0);
vec3 z = vec3(0, 0, eps);
return normalize(vec3(
estimator(p+x)-estimator(p-x),
estimator(p+y)-estimator(p-y),
estimator(p+z)-estimator(p-z)
));
}
vec4 marcher(vec3 o, vec3 d) {
vec3 p = o;
int step;
float distance;
for (step=0;step<steps;step++) {
distance = estimator(p);
p += d*distance;
if (distance < 0.01) break;
}
float ao = float(step)/float(steps);
float base = 1.0-ao+distance*0.1;
vec3 n = vec3(1)+normal(p)*0.8;
return vec4(
sin(base*n.x),
sin(base*n.y),
sin(base*n.z),
1.0
);
}
void main(void) {
float speed = 8;
float dist = speed/4*-fGlobalTime;
vec3 screen = gl_FragCoord.xyz/v2Resolution.x+vec3(-0.5, -0.5*3.0/4.0, -3+dist);
vec3 eye = vec3(0, 0, -4+dist);
vec3 dir = screen-eye;
dir.xy *= rot(fGlobalTime*0.2);
dir.yz *= rot(sin(fGlobalTime));
out_color = marcher(eye, dir);
}
@felipetavares
Copy link
Author

This is what it looks like:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment