Skip to content

Instantly share code, notes, and snippets.

@CharStiles
Created April 23, 2020 18:20
Show Gist options
  • Save CharStiles/1e927c6240c492fd8c3baf002456dd27 to your computer and use it in GitHub Desktop.
Save CharStiles/1e927c6240c492fd8c3baf002456dd27 to your computer and use it in GitHub Desktop.
#ifdef GL_ES
precision highp float;
#endif
// These are defined by Kodelife, or whatever environment you are using.
uniform float time;
uniform vec2 resolution;
varying vec3 v_normal;
varying vec2 v_texcoord;
// Define some constants
const int steps = 128; // This is the maximum amount a ray can march.
const float smallNumber = 0.0001;
const float maxDist = 10.; // This is the maximum distance a ray can travel.
float scene(vec3 position){
// So this is different from the sphere equation above in that I am
// splitting the position into its three different positions
// and adding a 10th of a cos wave to the x position so it oscillates left
// to right and a (positive) sin wave to the z position
// so it will go back and forth.
float sphere = length(
vec3(
position.x + cos(time)/10.,
position.y,
position.z+ sin(time) +1.)
)-0.5;
// This is different from the ground equation because the UV is only
// between -1 and 1 we want more than 1/2pi of a wave per length of the
// screen so we multiply the position by a factor of 10 inside the trig
// functions. Since sin and cos oscillate between -1 and 1, that would be
// the entire height of the screen so we divide by a factor of 10.
float ground = position.y + sin(position.x * 10.) / 10.
+ cos(position.z * 10.) / 10. + 1.;
// We want to return whichever one is closest to the ray, so we return the
// minimum distance.
// return ground;
return min(sphere,ground);
}
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(10., -15., 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 origin, vec3 direction){
float dist = 0.;
float totalDistance = 0.;
vec3 positionOnRay = origin;
for(int i = 0 ; i < steps; i++){
dist = scene(positionOnRay);
// Advance along the ray trajectory the amount that we know the ray
// can travel without going through an object.
positionOnRay += dist * direction;
// Total distance is keeping track of how much the ray has traveled
// thus far.
totalDistance += dist;
// If we hit an object or are close enough to an object,
if (dist < smallNumber){
// return the distance the ray had to travel normalized so be white
// at the front and black in the back.
vec3 n = estimateNormal(positionOnRay);
float l = lighting(positionOnRay, direction, n);
vec3 color = 1. - vec3(totalDistance) / maxDist;
return vec4(color * l, 1.0);
return 1. - (vec4(totalDistance) / maxDist);
}
if (totalDistance > maxDist){
return vec4(0.); // Background color.
}
}
return vec4(0.);// Background color.
}
// main is a reserved function that is going to be called first
void main(void)
{
// We are redefining the UV coordinates (aka texcoords) to be 0,0 in the
// middle of the screen this is because its easier to work with the camera at
// (0,0) instead of (0.5,0.5) for the SDFs
vec2 uv = -1. + 2. * v_texcoord;
// Unfortunately our screens are not square so we must account for that.
uv.x *= (resolution.x / resolution.y);
vec3 rayOrigin = vec3(uv, 0.);
vec3 camOrigin = vec3(0., 0., -1.);
vec3 direction = camOrigin + rayOrigin;
// This reserved variable is what we must set the final color to
gl_FragColor = trace(rayOrigin, direction);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment