Monday, July 24, 2017

Ray tracer demo

The next DDC release (v0.5.1) is currently being baked. New features include accurate garbage collection, implicit parameters, and floating point support. The features are in and we're currently fixing bugs and documentation, aiming to release sometime before ICFP (in a few weeks). Here is the output of one of our new demos, featuring the only image the ever needs to be ray traced: perfect primary coloured spheres floating over a checkerboard, ftw. The matching Disciple source code is here.

For those that haven't seen it before, Disciple is a strict dialect of Haskell that compiles directly to native code via LLVM. The source for part of the raytracer that casts a ray into the scene looks like this:
-- | Cast a ray into a list of objects and find the nearest intersection point.
object_cast (ray: Ray) (os0: List Object): Maybe (Object, Vec3)
 | Ray origin dir <- ray
 = go0 os0
        -- We haven't hit any objects yet.
        go0 Nil = Nothing

        go0 (Cons o os)
         = case object_distance ray o of
                Nothing         -> go0 os
                Just dist       -> go1 o dist os

        -- We already hit an object and we're testing others to see
        -- if they're closer.
        go1 oClose oDist Nil
         = Just (oClose, origin + vec3_muls dir oDist)

        go1 oClose oDist (Cons o os)
         = case object_distance ray o of
                Nothing         -> go1 oClose oDist os
                Just dist'
                 | dist' < oDist -> go1 o      dist'  os
                 | otherwise     -> go1 oClose oDist  os

Full source code on github