0.00
60.0 fps

March of the Gaskets

Playing around with ray marching

Log in to post a comment.

#version 300 es
precision highp float;

uniform float iTime;
uniform vec2  iResolution;

out vec4 fragColor;

// Credit to Bigwings for the framework and Hvidtfeldts for the fractal code


#define MAX_STEPS 130
#define MAX_DIST 1000.
#define SURF_DIST .001


float sdPlane(vec3 p) {
	return p.y + 1.0;
}

float repeat(float d, float domain)
{
    return mod(d, domain)-domain/2.0;
}

float sdSierpinski(vec3 z, vec3 offset)
{
    z.x = repeat(z.x, 4.);
    z.z = repeat(z.z, 4.);
     //int iterations = int((sin(iTime)+1.0)*8. + 1.0);
     int iterations = 10;
     float scale = clamp(sin(iTime)*0.71 + 1.7,-1.,2.0);
    vec3 a1 = vec3(1,1,1) + offset;
    vec3 a2 = vec3(-1,-1,1) + offset;
    vec3 a3 = vec3(1,-1,-1) + offset;
    vec3 a4 = vec3(-1,1,-1) + offset;
     vec3 c;
     float dist, d;
     int i = 0;
     for(int n=0; n < iterations; n++) {
          c = a1; 
          dist = length(z-a1);
          d = length(z-a2); if (d < dist) { c = a2; dist=d; }
          d = length(z-a3); if (d < dist) { c = a3; dist=d; }
          d = length(z-a4); if (d < dist) { c = a4; dist=d; }
          z = scale * z - c * (scale-1.0);
          i++;
     }

     return (length(z)-2.0) * pow(scale, float(-i));
}

float sminCubic(float a, float b, float k)
{
    float h = max(k-abs(a-b), 0.0);
    return min(a, b) - h*h*h/(6.0*k*k);
}

float map(vec3 p) {
    float plane = sdPlane(p);
    float sierpinski1 = sdSierpinski(p, vec3(0,0,0));   
    float sierpinski2 = sdSierpinski(p, vec3(1,0,0));
    float d = sminCubic(sierpinski1, plane,0.1);
    return d;
}

vec3 normal(vec3 p) {
	vec2 e = vec2(0.0, SURF_DIST*0.001);
    return -normalize(vec3(
        map(p-e.yxx)-map(p+e.yxx),
        map(p-e.xyx)-map(p+e.xyx),
        map(p-e.xxy)-map(p+e.xxy)
    ));
}



float RayMarch(vec3 ro, vec3 rd) {
    float d0 = 0.;
    float d = 1.0;
    vec3 p;
    for (int i = 0; i < MAX_STEPS; ++i) {
        if (d > SURF_DIST && d0 < MAX_DIST) {
            p = ro + rd * d0;
            d = map(p);
            
            d0 += d;
        }
    }
    return d0;
}



float GetLight(vec3 p) {
    vec3 lightPos = vec3(1, 3, -5. + iTime*10.0);
    //lightPos.xz += vec2(sin(iTime), cos(iTime))*2.;
    vec3 l = normalize(lightPos-p);
    vec3 n = normal(p);
    
    float dif = clamp(dot(n, l), 0., 1.);
    float d = RayMarch(p+n*SURF_DIST*2., l);
    if(d<length(lightPos-p)) dif *= .1;
    
    return dif;
}

float light(vec3 p, vec3 dir) {
    float light = GetLight(p);
    float total = clamp(0.5 + light, 0.0, 1.0);
    return total;
}




vec3 trace(vec3 ro, vec3 rd) {
	float d0 = 0.;
    float d = 1.0;
    vec3 p;
    for (int i = 0; i < MAX_STEPS; ++i) {
        if (d > SURF_DIST && d0 < MAX_DIST) {
            p = ro + rd * d0;
            d = map(p);
            d0 += d;
        }
    }
    vec3 bg = vec3(0.0,0.0,0.1);
    vec3 col;
    if (d < SURF_DIST) {
        // Phong shading Reinder
        vec3 lightPos = vec3(1, 3, -5. + iTime*10.0);
        vec3 worldPos = ro + d * rd;
        vec3 N = normalize (worldPos);
        vec3 V = -rd;
        vec3 L = normalize (lightPos - worldPos);
        vec3 R = reflect (-L, N);
        float spec = pow(max(dot(R, V), 0.0), 16.);
        float diff = max(dot(N, L), 0.0);
        float intensity = (1. / dot(lightPos - worldPos, lightPos - worldPos));
    	col = vec3(0.1,0.5,1)*light(p-SURF_DIST*rd, rd); + vec3(0.1,0.5,1)*pow(vec3(0.5,0.5,0.5), vec3(2.2))*spec*intensity;
    	//col = 0.4 + 0.5*cos(light(p-SURF_DIST*rd, rd) + vec3(.5,3.5,3.5)) + vec3(0.1,0.3,0.4)*pow(vec3(0.5,0.5,0.5), vec3(2.2))*spec*intensity;
    } else {
        col = bg;    
    }
    return col;
}



void main()
{   
    vec3 col = vec3(0.0);
    for(int i =-1; i<2; i++){
        for(int j =-1; j<2; j++){
            vec2 uv = (gl_FragCoord.xy + vec2(i,j)*.5) / iResolution.xy * 2.0 - 1.0;
    uv.y *= iResolution.y / iResolution.x;

    
    vec3 ro = vec3(0, 3, -4.5 + iTime*10.0);
    vec3 rd = normalize(vec3(uv.x-.15, uv.y-.2, 1));
    
    col += trace(ro, rd);
    }
    }

    
    
    col *= 0.11111111111;
    col = pow(col, vec3(0.5));
    fragColor = vec4(col, 1.0);	
}