[Haskell-cafe] Announce: glome-hs-0.51 (Haskell raytracer,
now with type classes)
Jim Snow
jsnow at cs.pdx.edu
Sun May 25 02:35:39 EDT 2008
A new version of my raytracer has been posted:
http://syn.cs.pdx.edu/~jsnow/glome/
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/glome-hs-0.51
(This should really be named 0.5.1, but I didn't think of that until
after I uploaded it to hackage.)
There's not much new functionality, but it now uses type classes for the
supported primitives, and has been optimized a bit more. Much of the
tutorial I hastily wrote for 0.4.x
(http://www.haskell.org/haskellwiki/Glome_tutorial) is now quite out of
date.
Most of the primitives have been moved to their own module, with the
exception of SolidItem (an existential type used to make composite
primitives), [SolidItem] (allowing me to treat lists of Solids like
single solids), Void (a non-object, equivalent to []::[SolidItem]), and
Instance (used for transformations). It might be possible to move those
to their own modules as well, but it would require mutual recursion
between modules, and that's probably more trouble than it's worth. (I
made an attempt at that, but I quickly gave up.)
I also gave up on trying to use a global mutable variable to count the
number of bounding hierarchy nodes a particular ray hits; instead, I
added rayint_debug, which behaves just like rayint (the standard
ray-object intersection routine), except that it returns an integer
(that I can use to count whatever I like) along with the ray
intersection. Using a global counter in this instance would have been
much simpler, but I don't think I understand "seq" well enough to be
able to force the increment to actually happen.
http://syn.cs.pdx.edu/~jsnow/glome/Screenshot-glome-hs-bih.png
The resulting renders can be very useful to determine where Glome is
spending most of its time, and to verify that the the bounding interval
hierarchy is really doing the right thing.
I also added packet tracing, which makes it possible to trace four rays
at a time, using a specialized ray intersection method "packetint".
(This is a common technique to amortize the acceleration structure's
memory lookup cost over multiple rays.) It seemed to be a big win when
I first implemented it before converting over to type classes, but now
it seems to be faster without it, so I probably made a mistake somewhere.
A cosmetic change is that Glome now renders into a drawlist instead of
directly to the screen, so the whole image doesn't get laboriously
re-traced whenever there's window damage. Unfortunately, that means you
can't watch as it draws anymore, which was a useful way of knowing which
parts of the image were slow to render.
I've started looking more seriously into optimization (suggestions
welcome). Don Stewart's blog post
(http://cgi.cse.unsw.edu.au/~dons/blog/2008/05/16#fast) was quite
useful, but it seems like there's a lot of arcane knowledge required to
understand what's really happening in "core" code. Is there any better
reference than Andrew Tolmach's paper "An External Representation for
the GHC Core Language (2001)"
http://citeseer.ist.psu.edu/tolmach01external.html?
-jim
More information about the Haskell-Cafe
mailing list