Last active
December 16, 2019 23:13
-
-
Save CharStiles/43c5cbe3f0ac88cbe76de4e03052c009 to your computer and use it in GitHub Desktop.
This file contains 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
#version 150 | |
//Char Stiles 2018 | |
// you can see what this renders to here: https://www.youtube.com/watch?v=gfJXa_MILdk&feature=youtu.be | |
// to run this code yourself download OSX Kodelife from Hexler. | |
// then create variables in the side panel for noise1 (sampler2D of noise), ans value1 (float) | |
uniform float time; | |
uniform vec2 resolution; | |
uniform vec2 mouse; | |
uniform vec3 spectrum; | |
uniform int frame1; | |
uniform sampler2D prevFrame; | |
uniform float value1; | |
uniform sampler2D noise1; | |
in VertexData | |
{ | |
vec4 v_position; | |
vec3 v_normal; | |
vec2 v_texcoord; | |
} inData; | |
out vec4 fragColor; | |
#define MAX_ITER 32 | |
#define MAX_DIST 500 | |
void pR(inout vec2 p, float a) { | |
p = cos(a)*p + sin(a)*vec2(p.y, -p.x); | |
} | |
// Shortcut for 45-degrees rotation | |
void pR45(inout vec2 p) { | |
p = (p + vec2(p.y, -p.x))*sqrt(0.5); | |
} | |
float pMod1(inout float p, float size) { | |
float halfsize = size*0.5; | |
float c = floor((p + halfsize)/size); | |
p = mod(p + halfsize, size) - halfsize; | |
return c; | |
} | |
float sdSphere( in vec3 p, in vec4 s ) | |
{ | |
return length(p-s.xyz) - s.w; | |
} | |
float sdEllipsoid( in vec3 p, in vec3 c, in vec3 r ) | |
{ | |
return (length( (p-c)/r ) - 1.0) * min(min(r.x,r.y),r.z); | |
} | |
float sdEllipsoid( in vec2 p, in vec2 c, in vec2 r ) | |
{ | |
return (length( (p-c)/r ) - 1.0) * min(r.x,r.y); | |
} | |
float sdTorus( vec3 p, vec2 t ) | |
{ | |
t += 0.1*texture(noise1,(p.zx+vec2(10 * spectrum.x))/6).x; | |
return length( vec2(length(p.xz)-t.x,p.y) )-t.y; | |
} | |
float funkySdTorus( vec3 p, vec2 t ) | |
{ | |
t += 0.1*texture(noise1,(p.zx+vec2(0.9))/6).x; | |
return length( vec2(length(p.xz)-t.x,p.y) )-t.y; | |
} | |
vec3 pMod3(inout vec3 p, vec3 size) { | |
vec3 c = floor((p + size*0.5)/size); | |
p = mod(p + size*0.5, size) - size*0.5; | |
return c; | |
} | |
// first object gets a capenter-style tongue attached | |
float fOpTongue(float a, float b, float ra, float rb) { | |
return min(a, max(a - ra, abs(b) - rb)); | |
} | |
float scene(vec3 p, bool b){ | |
float c = 2; // repeat every 2 units | |
vec3 op = p; | |
p = vec3(sin(p.x/10 + p.z)*50, cos(p.y/10 + p.z)*40, mod(p.z, 2.0) - 1.0) * 0.5; | |
pMod3(op, vec3(0,0,2)); | |
p = mix(op, p, sin(time) * 0.01 + 0.1); | |
float sp = sdSphere(p + vec3(0.5,0.5,1),vec4(0.03)); | |
pR(p.yz,90); | |
pR(p.xy,90); | |
float t = sdTorus(p ,vec2(1,0.1)); | |
return t; | |
//return fOpTongue(sp,t,0.3,1); | |
// return fOpUnionColumns(sp,t,.9,4); | |
} | |
float hex(vec2 p) { | |
p.x *= 0.57735*2.; | |
p.y += mod(floor(p.x), 2.)*.5; | |
p = abs((mod(p, 1.) - .5)); | |
return abs(max(p.x*1.5 + p.y, p.y*2.) - 1.); | |
} | |
// the following function is from https://www.shadertoy.com/view/llScR1 | |
float celli(in vec3 p){ p = fract(p)-.5; return dot(p, p); } | |
float cellTile2(in vec3 p){ | |
vec4 d; | |
d.x = celli(p - vec3(.81, .62, .53)); | |
p.xy = vec2(p.y-p.x, p.y + p.x)+hex(p.xy*0.2); | |
d.y = celli(p - vec3(.39, .2, .11)); | |
p.yz = vec2(p.z-p.y, p.z + p.y)+hex(p.yz*0.2); | |
d.z = celli(p - vec3(.62, .24, .06)); | |
p.xz = vec2(p.z-p.x, p.z + p.x)+hex(p.xz*0.2); | |
d.w = celli(p - vec3(.2, .82, .64)); | |
d.xy = min(d.xz, d.yw); | |
return min(d.x, d.y)*.5; | |
} | |
float bump(vec3 pos) { | |
float re = 0.; | |
re += cellTile2(pos*.25) * cellTile2(pos*1.1) * 3. + cellTile2(pos*1.2) * cellTile2(pos*4.4) * .5; | |
return re; | |
} | |
float SStrace(vec3 p, vec3 nor, vec3 li){ // second trace function to give it that gummy look | |
vec4 bg = vec4(0); | |
vec3 dir = p - li; // get the direction the ray is heading | |
p = p+(0.008*dir); // the position | |
float d = 0; | |
vec3 r = p; | |
float accum = 0; // total distance | |
for(int i = 0 ; i < MAX_ITER; i++){ | |
d = -scene(r,false); // we are doing marching from within the blobs | |
accum +=d; | |
r += d*dir; | |
if (d < 0.01){ | |
return accum; | |
} | |
if (r.z > MAX_DIST){ | |
return 0; | |
} | |
} | |
return 0; | |
} | |
float calcSSS( in vec3 pos, in vec3 nor, vec3 li ){ | |
return SStrace(pos, nor,li); | |
} | |
vec3 getNorm( vec3 p){ // get surrounding surface to calculate normal | |
vec2 v = vec2(0.,.1); | |
float nx = scene(p + v.yxx,false) - scene(p - v.yxx,false); | |
float ny = scene(p + v.xyx,false) - scene(p - v.xyx,false); | |
float nz = scene(p + v.xxy,false) - scene(p - v.xxy,false); | |
return normalize(vec3(nx,ny,nz)); | |
} | |
vec4 pong(vec3 p, vec3 lp, vec3 v, vec4 diff) // phong shiny | |
{ | |
vec3 l = normalize(lp - p); | |
vec3 n = getNorm(p); | |
float ndl = clamp(dot(n,l), 0.1, 1.0); // get angle for which light should bounce off | |
vec4 d = mix(vec4(0.0,0.0,0.0,0.0), diff, ndl);// mix it with the diffuse color | |
vec3 r = reflect(v, n); | |
float rdl = pow(clamp(dot(r, l), 0.0, 1.0),4.0); | |
vec4 s = mix(vec4(0.2,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1), rdl); | |
return d + s; | |
} | |
vec4 getMaterial(vec3 p, vec3 rd ){ | |
vec3 pn = getNorm(p); | |
vec3 li = vec3(cos(frame1/100.)*60,sin(frame1/100.)*30,p.z+10); //light source | |
vec3 matCol = vec3(10.4,4.7,6.0)*(+bump(p*0.4*(dot(vec3(0),pn),10))*3.5); // fleshy Color | |
float ss = -calcSSS(p, pn, li); | |
return vec4(matCol,1) * ((ss)) + (pong(p + (0.9*pn),li,rd,vec4(.4,.0,spectrum.x,1.0)) * texture(noise1,sin(time)*(p.xy+vec2(0.9))/6).x); | |
} | |
vec4 trace(vec3 o, vec3 dir){ | |
vec4 bg = texture(prevFrame,inData.v_texcoord) * vec4(0.999); // background Color | |
vec3 p = vec3(o.x , o.y , o.z); | |
float d = 0; | |
float accu = 0; | |
for(int i = 0 ; i < MAX_ITER; i++){ | |
d = scene(p,false); | |
p += d*dir; | |
accu += d; | |
if (d < 0.001){ | |
return getMaterial(p, dir); | |
} | |
if (accu > MAX_DIST){ | |
return bg; | |
} | |
} | |
return bg; | |
} | |
void main(void) | |
{ | |
vec2 uv = -1. + 2. * inData.v_texcoord; | |
uv.x *= resolution.x/resolution.y; | |
vec3 direction = normalize(vec3(uv, 0.)); | |
float t = 3 * value1; | |
float cz = time; | |
//setting up a 3D renderer via ray marching technique | |
float FOV = t*.9; | |
vec3 camera_origin = vec3(0., 1., cz); | |
vec3 lookAt = vec3(0.,1.,cz+1.); | |
vec3 forward = normalize(lookAt-camera_origin); | |
vec3 right = normalize(vec3(forward.z, 0., -forward.x )); | |
vec3 up = normalize(cross(forward,right)); | |
vec3 ro = camera_origin; | |
vec3 rd = normalize(forward + FOV*uv.x*right + FOV*uv.y*up); // camera direction | |
vec4 final = trace(vec3(uv,cz), rd); | |
float fog = pow(1. / (1. + final.x), .2); | |
fragColor = final; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment