Skip to content

Instantly share code, notes, and snippets.

@lunasorcery
Created September 19, 2018 21:16
Show Gist options
  • Save lunasorcery/b5b4502827e481b46253079ea6ba6da8 to your computer and use it in GitHub Desktop.
Save lunasorcery/b5b4502827e481b46253079ea6ba6da8 to your computer and use it in GitHub Desktop.
#version 410 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
uniform sampler2D texChecker;
uniform sampler2D texNoise;
uniform sampler2D texTex1;
uniform sampler2D texTex2;
uniform sampler2D texTex3;
uniform sampler2D texTex4;
layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything
#define pi (acos(-1.))
#define iTime (4 * fGlobalTime / pi)
vec2 rotate(vec2 a, float b)
{
float c = cos(b);
float s = sin(b);
return vec2(
a.x * c - a.y * s,
a.x * s + a.y * c
);
}
float sdTorus( vec3 p, vec2 t )
{
vec2 q = vec2(length(p.xz)-t.x,p.y);
return length(q)-t.y;
}
float sdSphere(vec3 p, float r)
{
return length(p)-r;
}
float tick()
{
float t = sin(iTime)*.5+.5;
// t = smoothstep(0,1,t);
return t*2-1;
}
vec2 halfScene(vec3 p)
{
//p.x += tick()*(sign(p.z));
//p.z = abs(p.z);
p.x = mod(p.x+2, 4)-2;
float env = max(
max(p.y,-p.z),
-sdTorus(p, vec2(1,.25))
);
p.xz = rotate(p.xz, iTime);
p.z -= sign(cos(iTime));
float ball = sdSphere(p,.25);
return vec2(min(env,ball), env<ball?1:0);
}
vec2 scene(vec3 p)
{
vec3 pA = p;
vec3 pB = p;
pA.x += tick();
pB.x -= tick();
pB.z *= -1;
vec2 a = halfScene(pA);
vec2 b = halfScene(pB);
return vec2(min(a.x,b.x),a.x<b.x?a.y:b.y);
}
vec3 trace(vec3 cam, vec3 dir)
{
vec3 accum = vec3(1);
for(int bounce=0;bounce<3;++bounce)
{
float t;
vec2 k;
for(int i=0;i<100;++i)
{
k = scene(cam+dir*t);
t += k.x;
if (k.x < .001 || k.x > 10)
break;
}
// sky hack
if (k.x > 10)
k.y = 2;
vec3 h = cam+dir*t;
vec2 o = vec2(.001, 0);
vec3 n = normalize(vec3(
scene(h+o.xyy).x-scene(h-o.xyy).x,
scene(h+o.yxy).x-scene(h-o.yxy).x,
scene(h+o.yyx).x-scene(h-o.yyx).x
));
if (k.y == 2)
{
// sky
return vec3(dir.y*.15+.1) * vec3(.5,1,.8) * 2.;
//return mix(.1,.4,dir.y*.5+.5);
return vec3(0,0,1);
}
if (k.y == 1)
{
float A = .1;
float B = scene(h+n*A).x;
float fakeAO = clamp(B/A,0,1);
fakeAO = pow(fakeAO,.6)*.2+.8;
float light = n.y*.5+.5;
vec3 color = vec3(.3,1,.7)*.8;
h.x += tick() * sign(h.z);
if(h.y > -.001)
color += smoothstep(.071,.07,length(fract(h.xz*4)-.5));
// floor
return light * fakeAO * accum * color;
}
else
{
// balls
float fresnel = pow(1.-dot(-dir,n),3);
fresnel = mix(.04,1.,fresnel);
accum *= fresnel;
cam = h + n*.0015;
dir = reflect(dir, n);
}
}
return vec3(0);
}
void main(void)
{
vec2 uv = gl_FragCoord.xy / v2Resolution.xy-.5;
uv.x *= v2Resolution.x / v2Resolution.y;
//uv *= 1.+length(uv)*.4;
//vec3 cam = vec3(0,0,-2);
//vec3 dir = normalize(vec3(uv, 1));
//for(int i=0;i<3;++i)
{
//uv *= 0.99;
vec3 cam = vec3(uv*4,-5);
vec3 dir = vec3(0,0,1);
cam.yz = rotate(cam.yz, atan(1,sqrt(2)));
dir.yz = rotate(dir.yz, atan(1,sqrt(2)));
cam.xz = rotate(cam.xz, pi/4);
dir.xz = rotate(dir.xz, pi/4);
//out_color[i] = trace(cam,dir).x;
out_color.rgb = trace(cam,dir);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment