NOTE: This site has just upgraded to Forester 5.x and is still having some style and functionality issues, we will fix them ASAP.

example. ray marching (naïve) [ag-0019]

The following renders a scene with a unit sphere at the origin, the camera at \((0,0,8)\) and looking at the origin, through a screen of height 1.0, centered at 5.0 from the camera.

The color of pixels are adjusted so that they are brighter the closer they are to the camera, as if there is a light source at the camera. As it takes a fixed step size of 0.1 (not small enough), the sphere is not rendered smoothly, and clearly shows the stepping artifacts.

/* The SDF for a sphere with radius r */
float sdSphere(vec3 p, float r)
{
  return length(p) - r;
}

/* The SDF for a scene with a unit sphere at the origin */
float sdScene(in vec3 pos) {
    return sdSphere(pos, 1.0);
}

#define EPSILON 0.01
#define T_MAX 10.0
#define DELTA_T 0.1
#define SDF_FUNCTION sdScene

/* Ray marching (naïve) */
float rayMarch(in vec3 ro, in vec3 rd) {

    float t = 0.0;

    while(t < T_MAX) {
        vec3 rt = ro + t * rd;
        float ft = SDF_FUNCTION(rt);
        
        if(ft < EPSILON) return t;

        t += DELTA_T;
    }
    
    return T_MAX;
}

/* The main function to render the scene per pixel */
void mainImage(out vec4 pixelColor, in vec2 pixelCoordinate) {
    
    // set up uv coordinates on the screen
    float aspect = iResolution.x/iResolution.y;
    vec2 uv = pixelCoordinate/iResolution.xy;
    uv -= vec2(0.5, 0.5);
    uv *= 2.0 * vec2(aspect, 1.0);

    // set up camera and view ray
    float observerDistance = 8.0;
    vec3 ro = vec3(0.0, 0.0, observerDistance);
    vec3 ta = ro - vec3(uv, 5.0);
    vec3 rd = normalize(ta - ro);

    // ray march
    float t = rayMarch(ro, rd);
    float hit = t != T_MAX ? 1.0 : 0.0;

    // adjust the color to look just bright enough
    float baseRatio = 0.65;
    // the closer, the brighter
    float distRatio = baseRatio + smoothstep(0.0, 1.0 - baseRatio, 1.0 - t / observerDistance);
    vec3 col = distRatio * vec3(1.0);

    // transparent if not hit
    pixelColor = vec4(col, hit);
}
simplified from zmcbeth's Raymarch 3.0
Code /* The SDF for a sphere with radius r */ float sdSphere(vec3 p, float r) { return length(p) - r; } /* The SDF for a scene with a unit sphere at the origin */ float sdScene(in vec3 pos) { return sdSphere(pos, 1.0); } #define EPSILON 0.01 #define T_MAX 10.0 #define DELTA_T 0.1 #define SDF_FUNCTION sdScene /* Ray marching (naïve) */ float rayMarch(in vec3 ro, in vec3 rd) { float t = 0.0; while(t < T_MAX) { vec3 rt = ro + t * rd; float ft = SDF_FUNCTION(rt); if(ft < EPSILON) return t; t += DELTA_T; } return T_MAX; } /* The main function to render the scene per pixel */ void mainImage(out vec4 pixelColor, in vec2 pixelCoordinate) { // set up uv coordinates on the screen float aspect = iResolution.x/iResolution.y; vec2 uv = pixelCoordinate/iResolution.xy; uv -= vec2(0.5, 0.5); uv *= 2.0 * vec2(aspect, 1.0); // set up camera and view ray float observerDistance = 8.0; vec3 ro = vec3(0.0, 0.0, observerDistance); vec3 ta = ro - vec3(uv, 5.0); vec3 rd = normalize(ta - ro); // ray march float t = rayMarch(ro, rd); float hit = t != T_MAX ? 1.0 : 0.0; // adjust the color to look just bright enough float baseRatio = 0.65; // the closer, the brighter float distRatio = baseRatio + smoothstep(0.0, 1.0 - baseRatio, 1.0 - t / observerDistance); vec3 col = distRatio * vec3(1.0); // transparent if not hit pixelColor = vec4(col, hit); }