no canvas

Raymarching

in WebGL

Rémi Papillié / @wsmind

Introduction

Live coding setup

4 vertices - just a fullscreen quad


// Vertex shader

uniform vec2 resolution;
attribute vec2 position;
varying vec2 uv;

void main()
{
    uv = position;
    
    // compensate for screen ratio
    uv.x *= resolution.x / resolution.y;
    
    gl_Position = vec4(position, 0.0, 1.0);
}
					

Ray marching tracing

Traditional offline rendering

Shoot rays from camera

Intersect with scene geometry

Raytracing

Camera model

Position

One ray per pixel

FOV?

Scene model

Need to compute ray-geometry intersection

Simple plane example (y = 0)


float intersectPlane(vec3 pos, vec3 dir)
{
    return -pos.y / dir.y;
}
					

Distance fields

Distance to closest surface, defined for every point in space

map(position) -> distance


float plane(vec3 pos)
{
    // signed distance to plane y = 0
    return pos.y;
}
					

Distance fields

Distance fields


float intersectSphere(vec3 pos, vec3 dir)
{
    // solve pos + k*dir = unit sphere surface
    // dot(pos + k*dir, pos + k*dir) = 1

    // quadratic coefficients
    float a = dot(dir, dir);
    float b = 2.0 * dot(pos, dir);
    float c = dot(pos, pos) - 1.0;
    float discriminant = b * b - 4.0 * a * c;

    // only the positive root is useful
    return (-b - sqrt(discriminant)) / (2.0 * a);
}
                        

float sphere(vec3 pos, float radius)
{
    return length(pos) - radius;
}
                        

Sphere Tracing

aka "marching"

Playing with space

Box


float box(vec3 pos, vec3 size)
{
    return length(max(abs(pos) - size, 0.0));
}
                    

Rounded Box


float box(vec3 pos, vec3 size, float radius)
{
    return length(max(abs(pos) - size, 0.0)) - radius;
}
                    

Playing with space

Any math function works!

mod()

sin()

abs()

etc.

Playing with colors

Simple procedural materials

Fake lighting

Other Improvements

Normals

BRDFs

Scattering

Occlusion

Other ideas?

Tradeoffs

Very flexible, but slow

Some optimizations work (e.g. bounding boxes)

Make demos!

Perfect candidate for raymarching

http://cookie.paris

Questions?