Last active
March 13, 2020 20:22
-
-
Save CharStiles/4fca35f81adc6020c4debb86702c2727 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Author: CHAR | |
// Title: RAYMARCH ART AT RECURSE | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
uniform vec2 u_resolution; | |
uniform vec2 u_mouse; | |
uniform float u_time; | |
float PI = 3.1415; | |
float PHI = 1.61803398874989; | |
vec3 hsv2rgb(vec3 c) | |
{ | |
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | |
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); | |
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); | |
} | |
float smin( float a, float b, float k ) | |
{ | |
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); | |
return mix( b, a, h ) - k*h*(1.0-h); | |
} | |
float fBlob(vec3 p) { | |
p = abs(p); | |
if (p.x < max(p.y, p.z)) p = p.yzx; | |
if (p.x < max(p.y, p.z)) p = p.yzx; | |
float b = max(max(max( | |
dot(p, normalize(vec3(1., 1, 1))), | |
dot(p.xz, normalize(vec2(PHI+1., 1.)))), | |
dot(p.yx, normalize(vec2(1., PHI)))), | |
dot(p.xz, normalize(vec2(1., PHI)))); | |
float l = length(p); | |
return l - 1.5 - 0.2 * (1.5 / 2.)* cos(min(sqrt(1.01 - b / l)*(PI / 0.25), PI)); | |
} | |
void pR(inout vec2 p, float a) { | |
p = cos(a)*p + sin(a)*vec2(p.y, -p.x); | |
} | |
float scene(vec3 ray){ | |
float floor = (ray.y + 1.2) - | |
cos(ray.x * 10.)* 0.2 - sin(ray.y* 10.); | |
float radius = 0.5; | |
ray = ray - vec3(0.,0.,2.0); | |
vec3 ray2 = ray; | |
pR(ray2.yz,u_time); | |
float blob = fBlob(ray2); | |
vec3 modSpace = vec3(1.0, 10.,5.0); | |
ray = mod(ray, modSpace) - 0.5*modSpace; | |
float sphere2 = length(ray+ vec3(sin(u_time))) - radius; | |
ray += vec3(0.,0.,(sin(u_time) + 1.0) * 0.2); | |
float sphere = length(ray) - radius; | |
return smin(smin(blob, sphere,0.6), sphere2,0.6) ; | |
} | |
vec3 estimateNormal(vec3 p) { | |
float smallNumber = 0.002; | |
vec3 n = vec3( | |
scene(vec3(p.x + smallNumber, p.yz)) - | |
scene(vec3(p.x - smallNumber, p.yz)), | |
scene(vec3(p.x, p.y + smallNumber, p.z)) - | |
scene(vec3(p.x, p.y - smallNumber, p.z)), | |
scene(vec3(p.xy, p.z + smallNumber)) - | |
scene(vec3(p.xy, p.z - smallNumber)) | |
); | |
return normalize(n); | |
} | |
float lighting(vec3 origin, vec3 dir, vec3 normal) { | |
vec3 lightPos = vec3(cos(u_time)*20., sin(u_time), 12.); | |
vec3 light = normalize(lightPos - origin); | |
float diffuse = max(0., dot(light, normal)); | |
vec3 reflectedRay = 2. * dot(light, normal) * normal - light; | |
float specular = max(0., (pow(dot(reflectedRay, light), 3.))); | |
float ambient = 0.05; | |
return ambient + diffuse + specular; | |
} | |
// cosine based palette, 4 vec3 params | |
vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d ) | |
{ | |
return a + b*cos( 6.28318*(c*t+d) ); | |
} | |
vec4 trace(vec3 rayOrigin, vec3 dir){ | |
vec3 ray = rayOrigin; | |
float dist = 0.; | |
float totalDist = 0.; | |
float maxDist = 1.; | |
for (int i = 0; i < 32 ; i++){ | |
dist = scene(ray); | |
if(dist < 0.0001){ | |
vec4 distCol = vec4(1. - vec4(totalDist/maxDist)); | |
vec3 hsvCol = palette( | |
distCol.r, vec3(0.5, 0.5, 0.5) , | |
vec3(0.5, 0.5, 0.5) , | |
vec3(2.0, 1.0, 0.0 ), | |
vec3(0.50, 0.20, tan(u_time))); | |
vec4 lightingCol = vec4(lighting(rayOrigin,dir,estimateNormal(ray))); | |
return lightingCol; | |
} | |
totalDist += dist; | |
ray += dist * dir; | |
} | |
return vec4(0.); | |
} | |
vec3 lookAt(vec2 uv, vec3 camOrigin, vec3 camTarget){ | |
vec3 zAxis = normalize(camTarget - camOrigin); | |
vec3 up = vec3(0,1,0); | |
vec3 xAxis = normalize(cross(up, zAxis)); | |
vec3 yAxis = normalize(cross(zAxis, xAxis)); | |
float fov = 2.; | |
vec3 dir = (normalize(uv.x * xAxis + uv.y * yAxis + zAxis * fov)); | |
return dir; | |
} | |
void main() { | |
vec2 st = gl_FragCoord.xy/u_resolution.xy; | |
st.x *= u_resolution.x/u_resolution.y; | |
vec2 uv = (st*2.0) - 1.0; | |
vec3 rayOrigin = vec3(uv, 0.); | |
vec3 camOrigin = vec3(0., 0., -1.); | |
vec3 camTarget = vec3(sin(u_time),cos(u_time), 2); | |
vec3 direction = lookAt(uv, camOrigin, camTarget); | |
// vec3 camOrigin = vec3(0.,0.,sin(u_time)-1.); | |
// vec3 rayOrigin = vec3(camOrigin.xy + | |
// uv, camOrigin.z + 1.); | |
// vec3 dir = normalize(rayOrigin-camOrigin); | |
gl_FragColor = trace(rayOrigin, direction); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment