Tracing Rays, again
Raytracing somehow became a hobby of me… So why not try a Raytracer in Haskell? Raytracing is maths, and a functional language is just the natural fit for coding a raytracer. I can tell, because I coded raytracers in C, in C again, then in Java (including a GUI where you could drag-n-drop materials on the primitives), then in C++, in Java again, and now in Haskell. The language doesn’t matter, raytracing is fun in itself!
What do we need to get started? Spheres. Absolutely. And rays. So the “interesting” stuff we need is
-- a vector in R^3
type Vector = (Float, Float, Float)
-- a Ray has an origin and a direction
type Ray = (Point, Vector)
-- the roots of the equation a * x^2 + b * x + c = 0
roots :: Float -> Float -> Float -> [Float]
roots a b c = let d = b*b - 4*a*c
in if (d < 0.0) then []
else [ 0.5 * (-b + sqrt d), 0.5 * (-b - sqrt d) ]
-- intersect a ray with a spehere
intSphere :: Ray -> Float -> Point -> [ (Float, Intersection) ]
intSphere ray@(origin, rayDir) r center = map (\t -> (t, intAt t)) times
where
dir = origin `sub` center
a = sqLen rayDir
b = 2 * (rayDir `dot` dir)
c = (sqLen dir) - (r * r)
times = filter (> epsilon) (roots a b c)
hitPoint = positionAt ray
intAt t = (hitPoint t, normalAt t, ray)
normalAt t = normalize (center `sub` (hitPoint t))
and this gives us the very first image produced…

…which includes a bug where I exchanged the intersection position with the normal at the intersection point. I have to figure out how to apply type safety, but seeing an unit sphere we can ignore that for now. What do we see? It’s the “debug” integrator “rendering” a unit sphere located at (0, 0, 0). The debug integrator is inspired by pbrt; which I can recommend everyone remotely interested in raytracing more than words can describe. How long does rendering this 800×800 image take?
$ time ./a.out real 0m0.555s user 0m0.526s sys 0m0.011s
Half a second. It’s been a while since a last met Haskell, but it seems the Glasgow Haskell Compiler has come a long way since than. So, let’s move on. I want another sphere! And a plane!

$ time ./a.out real 0m1.356s user 0m1.275s sys 0m0.012s
user 0m1.109s
About this entry
You’re currently reading “Tracing Rays, again”, an entry on Waldheinz
- Published:
- 4.11.10 / 1am
- Category:
- English
- Tags:
- coding, graphics, haskell, raytracing


No comments
Jump to comment form | comments rss [?] | trackback uri [?]