My first (decent) **raymarched distance field**!

The geometry in the scene is described as a "Distance Function",
which returns the nearest distance to the scene from any arbitrary
3D point; that means we need to think about the geometry in
terms of its distance from $P$, which really bends me head.

- Raymarching a Distance Field function! :D
- Surface normals obtained using a differential function.
- Really cheap Ambient Occlusion, with help from
**mu6k**. - Exponential distance function for 'metaball' effect, with help from
**iq**. - Multiple texture samplers and 'materials'. Woohoo
**sarcasm**.

We cast a 'ray' out from each fragment, and iterate a point
along the ray $t \times |\vec r_d|$ by **adding the distance to the scene:** $d + t$,
for an arbitrary number of iterations (100 iterations of a *for* loop in this case).
$\vec r_d$ is the ray direction vector, and $t$ is the distance along the ray.

Once we have reached some minimum threshold of $d$ (the distance to the scene from
the point on the ray), the point on the ray is so close to the scene that we can
assume that the point is very near to the geometry.

Alternatively, if $t$ is so large that we are sure it is outside the scene,
we can break the raymarcher loop, and perform some other type of colour compution;
perhaps a 'sky' environment.

From there, we can do all sorts of linear algebra magic to move the 'camera'
and create the 'purdy colours' you see on your display.

We wish to construct a "look-at" reference frame in order to find the direction
at which to fire the ray. To construct a 3D Cartesian reference frame, we need
3 vectors that are perpendicular to each other: $w$ (the direction), $u$ (the vector orthonormal to $w$ and an arbitrary $up$
vector), and $v$ (the vector orthonormal to $w$ and $u$).

$$ up = 0x + 1y + 0z $$ $$ w = | target - ro | $$ $$ u = | w \times up | $$ $$ v = | u \times w | $$ |

We can express our coordinate system as a generic transform by packing it into a 3D matrix: $$ M = \left[ \begin{matrix} u_x & u_y & u_z \\ v_x & v_y & v_z \\ w_x & w_y & w_z \\ \end{matrix} \right] $$ Finally, we obtain the new ray direction by multiplying it with our coordinate system. $$ rd' = | M \times rd| $$ $$ = | rd_xu + rd_yv + rd_zw | $$

The lighting you're seeing here is no more than the application of **Lambert's Law**
and some Phong specular reflectance.

The 'sky' colour is computed as such, where $\vec C$ is the final fragment colour,
$\vec c_a$ & $\vec c_b$ are arbitrary RGB colours, $\vec r_d$ is the ray direction, and
$\vec L$ is the light direction vector:
$$ \vec C = \vec c_a \times \vec r_d \cdot \vec L + \vec c_b \times \vec r_d \cdot -\vec L $$
We obtain the surface normal at any collision point by obtaining the difference between
two points a small distance around the collision.

The entire render is drawn onto no more than two triangles (a quad), shaded with the following GLSL Fragment Shader code. I've tried to comment the code reasonably well for your learning pleasure!

© Deinyon Davies 2014

Math notation powered by MathJax ®