Raymarching Resources

Hi, thanks for taking interest in ray marching, it is seriously my favorite technique for fun shader programming. It has a lot of use in the future with all this drive towards physically based rendering techniques driven by platforms like Nvidia RTX.

Here is the code that was given in the article:

#ifdef GL_ES
precision highp float;
#endif

uniform float time;
uniform vec2 resolution;

varying vec3 v_normal;
varying vec2 v_texcoord;

// define some constants
const int steps = 128;
const float smallNumber = 0.001;
const float maxDist = 10.;

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 min(sphere,ground);
}

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 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;

gl_FragColor = trace(rayOrigin, direction);
}

I put together a list of my favorite functions, this has a lot of 2D SDFs:

https://gist.github.com/CharStiles/e6fec016967c6c8fd648aa4b6c0055cc

Here is a reel of some more work that I have done with shaders:

Next Steps

These are some specific suggestions from me if you want to continue learning but don’t know how to start.

1. Learn the maths from The Book of Shaders
** If you haven’t looked at this already, look through it! Its wonderfully paced and has a lot of versatile useful information. [https://thebookofshaders.com/]

2. Get into more tutorials!
** This tutorial here: https://github.com/ajweeks/RaymarchingWorkshop is super thorough and really useful!

3. Get involved with the community online
*** Toplap.org is the hub for livecode community. You can join lurk channel (its like slack) and join the visual channel https://talk.lurk.org/channel/visualists

*** you can see some amazing raymarched scenes online at shadertoy.com