Last active
May 26, 2024 15:16
-
-
Save CharStiles/dd06c2e64595f49ad53c4027b7967a32 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
// 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; | |
} | |
// smoothly interpolate between two fuctions with k that controls the radious/distance of the smoothness. | |
// read more here about smin: https://iquilezles.org/www/articles/smin/smin.htm | |
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); | |
} | |
// All of these functions are hand picked from http://mercury.sexy/hg_sdf/ until you hit the danger zone >:) | |
// Rotate around a coordinate axis (i.e. in a plane perpendicular to that axis) by angle <a>. | |
// Read like this: R(p.xz, a) rotates "x towards z". | |
// This is fast if <a> is a compile-time constant and slower (but still practical) if not. | |
void pR(inout vec2 p, float a) { | |
p = cos(a)*p + sin(a)*vec2(p.y, -p.x); | |
} | |
// Repeat in three dimensions | |
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; | |
} | |
// Repeat in two dimensions | |
vec2 pMod2(inout vec2 p, vec2 size) { | |
vec2 c = floor((p + size*0.5)/size); | |
p = mod(p + size*0.5,size) - size*0.5; | |
return c; | |
} | |
// Same, but mirror every second cell so all boundaries match | |
vec2 pModMirror2(inout vec2 p, vec2 size) { | |
vec2 halfsize = size*0.5; | |
vec2 c = floor((p + halfsize)/size); | |
p = mod(p + halfsize, size) - halfsize; | |
p *= mod(c,vec2(2))*2. - vec2(1); | |
return c; | |
} | |
// 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; | |
} | |
// Box: correct distance to corners | |
float fBox(vec3 p, vec3 b) { | |
vec3 d = abs(p) - b; | |
vec3 toMax = min(d, vec3(0)); | |
return length(max(d, vec3(0))) + max(max(toMax.x,toMax.y), toMax.z); | |
} | |
// Blobby ball object. You've probably seen it somewhere. This is not a correct distance bound, beware. | |
#define PHI (pow(5.,0.5)*0.5 + 0.5) | |
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)); | |
} | |
// Torus in the XZ-plane | |
float fTorus(vec3 p, float smallRadius, float largeRadius) { | |
return length(vec2(length(p.xz) - largeRadius, p.y)) - smallRadius; | |
} | |
///////// YOU ARE APPROACHING DANGER ZONE (I am giving you the functions that we will go over in the next lesson) | |
// if you can see how to use them feel free to add them in the scene, but the scope of THIS class doesnt cover these | |
// I just wanted to give you the option in case you were bored of the above. | |
// The next two functions are standard diffuse lighting. | |
// you need the normal function to use the lighting function | |
vec3 estimateNormal(vec3 p) { | |
// define your own small number here or at the top | |
// im just not doing it here because in my workshop | |
// i have it as a const global. | |
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(time)*20., sin(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; | |
} | |
// Use this function to replace the defninition of dir to be able to look at the camera target | |
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment