Last active
November 22, 2021 05:15
-
-
Save CharStiles/327768a23e5e64b7a9d6163ae305b15b 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: charstiles | |
// Title: raymarch at at parsons | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
uniform vec2 u_resolution; | |
uniform vec2 u_mouse; | |
uniform float u_time; | |
const int step = 128; | |
const float maxDist = 10.3; | |
const float PI = 3.141592658; | |
const float smallNumber = 0.02; | |
// http://www.iquilezles.org/www/articles/palettes/palettes.htm | |
// As t runs from 0 to 1 (our normalized palette index or domain), | |
//the cosine oscilates c times with a phase of d. | |
//The result is scaled and biased by a and b to meet the desired constrast and brightness. | |
vec3 cosPalette( float t, vec3 a, vec3 b, vec3 c, vec3 d ) | |
{ | |
return a + b*cos( 6.28318*(c*t+d) ); | |
} | |
float sphere(vec3 pos, float rad){ | |
return length(pos) - rad; | |
} | |
// Repeat around the origin by a fixed angle. | |
// For easier use, num of repetitions is use to specify the angle. | |
float pModPolar(inout vec2 p, float repetitions) { | |
float angle = 2.*PI/repetitions; | |
float a = atan(p.y, p.x) + angle/2.; | |
float r = length(p); | |
float c = floor(a/angle); | |
a = mod(a,angle) - angle/2.; | |
p = vec2(cos(a), sin(a))*r; | |
// For an odd number of repetitions, fix cell index of the cell in -x direction | |
// (cell index would be e.g. -5 and 5 in the two halves of the cell): | |
if (abs(c) >= (repetitions/2.)) c = abs(c); | |
return c; | |
} | |
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 scene(vec3 pos){ | |
vec3 modSpace = vec3(5.,2.,2.); | |
pos = mod(pos,modSpace) - 1.; | |
float s = sphere(pos, 0.4); | |
pModPolar(pos.xy,3.0); | |
float s2 = sphere(pos +( sin(u_time)*0.6), 0.2); | |
return smin(s,s2,(cos(u_time*2.)+1.)* 0.2); | |
} | |
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; | |
} | |
vec3 estimateNormal(vec3 p) { | |
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; | |
} | |
vec4 trace(vec3 camOrigin, vec3 dir){ | |
vec3 ray = camOrigin; | |
float totalDist = 0.; | |
float dist; | |
for(int i = 0 ; i < step; i ++){ | |
dist = scene(ray); | |
totalDist += dist; | |
if (dist < 0.001){ | |
vec3 n = estimateNormal(ray); | |
float l = lighting(ray, dir, n); | |
vec3 color = cosPalette(totalDist, | |
vec3(0.5, 0.5, 0.5), | |
vec3(0.5, 0.5, 0.5), | |
vec3(1.0, 1.0, 0.5), | |
vec3(0.80, 0.90, 0.30)); | |
return vec4(color * l, 1.0); | |
// return vec4(cosPalette(totalDist, | |
// vec3(0.5, 0.5, 0.5), | |
// vec3(0.5, 0.5, 0.5), | |
// vec3(1.0, 1.0, 0.5), | |
// vec3(0.80, 0.90, 0.30)), 1.0); | |
//return vec4(hsv2rgb(vec3(totalDist, | |
//1.0,1.0)),1.0);//;/maxDist); | |
} | |
if (totalDist > maxDist){ | |
return vec4(0); | |
} | |
ray += dist*dir; | |
} | |
return vec4(0.0); | |
} | |
void main() { | |
vec2 uv = gl_FragCoord.xy/u_resolution.xy; | |
uv = (uv *2.0) - vec2(1.0); | |
uv.x *= u_resolution.x/u_resolution.y; | |
vec3 camOrigin = vec3(0.0,0.0,-1.0); | |
vec3 rayOrigin = vec3(uv.x + camOrigin.x, | |
uv.y + camOrigin.y, | |
camOrigin.z + 1.0); | |
vec3 camTarget = vec3(0,sin(u_time), 2); | |
vec3 dir = lookAt(uv, camOrigin, camTarget); | |
//vec3 dir = rayOrigin - camOrigin; | |
vec4 color = trace(camOrigin,dir); | |
gl_FragColor = color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment