[Haskell-cafe] announce: Glome.hs raytracer
Jim Snow
jsnow at cs.pdx.edu
Wed Mar 26 17:33:20 EDT 2008
I have recently posted a haskell port of my ocaml raytracer, Glome:
http://syn.cs.pdx.edu/~jsnow/glome/
It supports spheres and triangles as base primitives, and is able to
parse files in the NFF format used by the standard procedural database
(http://tog.acm.org/resources/SPD/). It uses a bounding interval
heirarchy acceleration structure, so it can render fairly complicated
scenes in a reasonable amount of time. Shadows and reflections are
supported, but not specular highlights or refraction.
It's still slower than the ocaml version, but at least they're in the
same ballpark (and a good part of that difference may be inefficiencies
in my BIH traversal). I would welcome any advice on making it go faster
or use less memory.
I compile the program with "ghc Glome.hs --make -fasm -O2 -threaded
-fglasgow-exts -funbox-strict-fields -fbang-patterns -fexcess-precision
-optc-ffast-math -optc-O2 -optc-mfpmath=sse -optc-msse2". (I assume the
-optc options don't do anything unless you compile via C.)
Here are some of my current concerns:
-Multi-core parallelism is working, but not as well as I'd expect: I get
about a 25% reduction in runtime on two cores rather than 50%. I split
the default screen size of 512x512 into 16 blocks, and run "parMap" on
those blocks with a function that turns the screen coordinates of that
block into a list of (x,y,r,g,b) tuples that get drawn as pixels to the
screen through OpenGL by the original thread.
-Memory consumption is atrocious: 146 megs to render a scene that's a
33k ascii file. Where does it all go? A heap profile reports the max
heap size at a rather more reasonable 500k or so. (My architecture is
64 bit ubuntu on a dual-core amd.)
-Collecting rendering stats is not easy without global variables. It
occurs to me that it would be neat if there were some sort of write-only
global variables that can be incremented by pure code but can only be
read from within monadic code; that would be sufficient to ensure that
the pure code wasn't affected by the values. The sorts of things I'm
looking for are the number of calls to "trace" per image, the number of
BIH branches traversed and ray/triangle and ray/sphere intersections per
pixel. (Disclaimer: I don't really fully understand monads, so I may
be oblivious to an obvious solution.)
-Is there a fast way to cast between Float and Double? I'm using Float
currently, and the only reason is because that's what the OpenGL api
expects. I'd like to be able to use either representation, but the only
way to cast that I've found so far is "float_conv x =
fromRational(toRational x)", which is too slow.
thanks,
-jim
More information about the Haskell-Cafe
mailing list