gangsta

raytracing development blog

Archive for March, 2006

Big old reorganisation

vaseline

Well it’s taken a long time to get to this stage! That’s not a vaseline lens shader, it’s testing the filtering system with a 3-pixel radius box filter. Although the picture looks not a lot different, a huge amount has changed under the surface. It’s now multi-threaded, and renders in buckets which can be freed dynamically as soon as they’re finished, so in theory I can now render an arbitrarily large image.

The biggest challenge in getting to this stage was managing the synchronization issues caused by multithreading. Initially I just had each thread render a bucket, which was then passed off to the display. This was fine as long as all buckets were kept in memory, but if you want to delete buckets when they’re no longer needed you run into trouble because the multipixel filter requires samples from neighbouring buckets. If each thread renders a bucket, how do you know when a bucket’s really finished with and it’s safe to delete the samples it contains?

The solution was to divide and conquer! “One class, one responsibility” is the order of the day. I moved all the rendering code to a functor that is called by the threads. The buckets now simply define regions in the image plane, and the order in which they’re sampled. The actual samples are stored in a SampleCache object which is responsible for managing the memory and can allocate samples in blocks as required. Since the renderer functors just ask the bucket queue for the next pixel’s worth of samples, I have only one point of write access to lock for multithreading (which cuts down the overhead from fiddling with mutexes), and it’ll be trivial to implement adaptive sampling by having the buckets monitor the variance and add samples as required.

There won’t be another update for a fair while as I have to implement some form of scene description as I’m pretty fed up of rendering a hard-coded cornell box all the time :)

No comments