Skip to content

Instantly share code, notes, and snippets.

@CharStiles
Last active April 14, 2024 03:13
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CharStiles/dd06c2e64595f49ad53c4027b7967a32 to your computer and use it in GitHub Desktop.
Save CharStiles/dd06c2e64595f49ad53c4027b7967a32 to your computer and use it in GitHub Desktop.
// 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