Skip to content

Instantly share code, notes, and snippets.

@x5lcfd
Last active August 3, 2018 11:24
Show Gist options
  • Save x5lcfd/21c6edfba363cf077a726fc99d133746 to your computer and use it in GitHub Desktop.
Save x5lcfd/21c6edfba363cf077a726fc99d133746 to your computer and use it in GitHub Desktop.
a simple distance field raymarcher
// https://www.shadertoy.com/view/lltczj
// https://www.reddit.com/r/twotriangles/comments/1hy5qy/tutorial_1_writing_a_simple_distance_field/
const int MAX_ITER = 100;
const float MAX_DIST = 20.0;
const float EPSILON = 0.001;
float sphere(vec3 pos, float radius)
{
return length(pos) - radius;
}
float box(vec3 pos, vec3 size)
{
return length(max(abs(pos) - size, 0.0));
}
float distfunc(vec3 pos)
{
return sphere(pos, 1.0);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec3 cameraOrigin = vec3(2.0, 2.0, 2.0);
vec3 cameraTarget = vec3(0.0, 0.0, 0.0);
vec3 upDirection = vec3(0.0, 1.0, 1.0);
vec3 cameraDir = normalize(cameraTarget - cameraOrigin);
vec3 cameraRight = normalize(cross(upDirection, cameraOrigin));
vec3 cameraUp = cross(cameraDir, cameraRight);
vec2 screenPos = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
screenPos.x *= iResolution.x / iResolution.y;
vec3 rayDir = normalize(cameraRight * screenPos.x + cameraUp * screenPos.y + cameraDir);
float totalDist = 0.0;
vec3 pos = cameraOrigin;
float dist = EPSILON;
for (int i = 0; i < MAX_ITER; i++)
{
// Either we've hit the object or hit nothing at all, either way we should break out of the loop
if (dist < EPSILON || totalDist > MAX_DIST)
break; // If you use windows and the shader isn't working properly, change this to continue;
dist = distfunc(pos); // Evalulate the distance at the current point
totalDist += dist;
pos += dist * rayDir; // Advance the point forwards in the ray direction by the distance
}
if (dist < EPSILON)
{
vec2 eps = vec2(0.0, EPSILON);
vec3 normal = normalize(vec3(
distfunc(pos + eps.yxx) - distfunc(pos - eps.yxx),
distfunc(pos + eps.xyx) - distfunc(pos - eps.xyx),
distfunc(pos + eps.xxy) - distfunc(pos - eps.xxy)));
float diffuse = max(0.0, dot(-rayDir, normal));
float specular = pow(diffuse, 32.0);
vec3 color = vec3(diffuse + specular);
fragColor = vec4(color, 1.0);
}
else
{
fragColor = vec4(0.0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment