[Haskell-cafe] announce: Glome.hs-0.3 (Haskell raytracer)

Jim Snow jsnow at cs.pdx.edu
Fri Apr 25 00:34:06 EDT 2008

Andrew Coppin wrote:
> Wow. The POV-Ray guys are talking about Haskell [or rather, my 
> personal addiction to it] and the Haskell guys are talking about 
> POV-Ray... on the same day... How unlikely is that? ;-)
That's odd; I had a personal addiction to POV-Ray for a few years, and 
just now have started using Haskell.

> I've been using POV-Ray for a long time. I like it for several reasons:
> 1. It's the only program I've ever seen [on a PC] that does ray 
> tracing. [I'm sure there must be others...]
> 2. It's the only program I've seen that can render *real* curves, not 
> fake trickery with triangle meshes.
> 3. It can render *arbitrary* mathematical surfaces. Want to render a 
> 3D slice of the 4D cubic Mandelbrot set? No problem!
> 4. It has a novel "scene description language", which does far more 
> than describe scenes. It's Turing-complete, and you can build physics 
> engines with it. [It's painfully slow though!]
The Scene Description Language (SDL) is the best and worst thing about 
POV-Ray.  It's very intuitive and user-friendly, so a person can 
reasonably write a complex scene in pure code without using an external 
GUI editor.  Unfortunately, the SDL is so complex it's well-nigh 
impossible to support in other third-party applications.  It's also 
slow.  I don't know if this is still the case, but the standard way of 
doing an animation was to reference a "clock" variable in your scene 
source code that went from 0 to 1; for instance, a command to make a 
swing swing back and forth might looks like this:

"rotate 15*sin((clock/2)*seconds*(2*pi)-((2/3)*pi))*x"

"seconds" here is a variable set to the number of seconds in the 
animation, and "x" is the X axis unit vector <1,0,0>.  The (2/3)*pi 
thing is to make it swing out of phase with the other swings.

(this rather obfuscatory example taken from an actual ancient povray 
source file, you can see a rendering here: 

The scene then has to be re-parsed for every frame.  For complex scenes, 
the scene parsing could take longer than the actual render.

There are many other PC programs that do ray tracing, but POV-Ray is the 
only one I've had any experience with.

> The POV-Ray team is currently working on the first multi-threaded 
> version. [After years of saying it would never happen.] It's taking a 
> while. (That's partly because the developers take product quality very 
> seriously.) It should be interesting when it's done, but it's still 
> taking a while.
> Personally, I'd quite like to write my own ray tracer to address some 
> of these limitations. But every time I try, I end up hitting design 
> issues [Haskell works very differently to Java] or performance issues 
> [which I don't even know how to begin debugging]. Not to mention that 
> POV-Ray uses sophisticated techniques like volume bounding that I know 
> nothing about. (There's nothing like using an inherantly superior 
> algorithm to make your code orders of magnitude faster...)
I haven't really run into any issues where Haskell didn't let me do what 
I want, except for the performance counters thing mentioned way back at 
the beginning of this thread (and which I've more or less given up on 
for now, since the acceleration structure seems to be working okay and I 
have other things to work on).

I would certainly welcome any patches to Glome if you want to contribute 
in some way rather than write something from scratch.

A good acceleration structure definitely makes everything go a lot 
faster.  It's the difference between rendering a scene in a few seconds 
or ten minutes.

BIH is what I'm using.  It's relatively new.  Here's a paper about it:  

The actual constructor is based loosely on this pseudocode: 

Evan Laforge wrote:
> Not knowing anything about raytracing, one of the things I found
> interesting about the paper was that he claimed that the speedups were
> from using coherent ray packets, and that the shader model was
> orthogonal, and enough much is spent raycasting that the shader code
> to make much difference.  The implication was that you could graft a
> packet style raycasting engine onto even povray and give it a nice
> speed boost... though you might have to lose the nifty "real" shapes
> to tessellated approximations.
> Is this accurate?  True but reality is more complicated?
You don't need to drop support for the whole multitude of primitives, 
though the ones that are packet-friendly will render faster.  Many 
modern ray tracers spend most of their time traversing the acceleration 
structure rather than doing intersection tests with actual geometry, so 
all you really need to do to get most of the benefit of packet tracing 
is to make the acceleration structure support packets.  (For the actual 
geometry, you can fall back on mono-rays.)  I tried 2x2 packets out last 
night and got about a 10-15% speed improvement on the level-3 SPD 
sphereflake.  (Shadow and reflection rays are still mono rays; if I 
converted them over, the improvement would presumably be more 
significant.)  The simplifying assumption you make when you're 
traversing the acceleration structure with packets is that if one ray in 
the packet hits a bounding volume, you assume that they all do.  That 
adds a little overhead if the rays are coherent (all starting near a 
common origin and pointing in almost the same direction), or a lot of 
overhead if they aren't coherent.  If used appropriately, the 
performance gains outweigh the overhead by a considerable margin.

Jon Harrop wrote:
> On Thursday 24 April 2008 20:29:50 Andrew Coppin wrote:
>> > 2. It's the only program I've seen that can render *real* curves, not
>> > fake trickery with triangle meshes.
> What you called "fake trickery with triangle meshes" is the core of all modern 
> computer graphics. Focussing on ray tracing instead of that is rather missing 
> the point, IMHO.
I agree that triangles are very important, and I support them in Glome.  
Cones and spheres and boxes and the like can be made into some fairly 
elaborate scenes, but you can't really make, say, a realistic human 
figure out of those sorts of primitives.  Also, real data sets like 
terrain or 3d-scanned geometry are easy to represent as triangles.  On 
the other hand, sometimes all you want is a box or a shiny sphere and 
it's silly (not to mention a waste of memory) to represent either as a 
bunch of triangle.  So it's appropriate to support both approaches, so 
you can do whatever makes the most sense for the application.

Ray tracing and triangles isn't an either-or thing.  Some ray tracers 
only support triangles.  There is a speed penalty for supporting other 
kinds of primitives, because then the ray tracer has to branch to figure 
out which ray-intersection test to run on each primitive, but I think 
the flexibility is worth the cost.


More information about the Haskell-Cafe mailing list