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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to