Archive for April, 2011

Another ISPM update

April 25, 2011

Since the last update, I’ve updated the ray tracing kernel to use kd-trees instead of brute-forcing all of the triangles. Kd-trees are quite heavy on branching as is not exactly the best usage scenario for GPUs, but it’s a lot faster than the brute force variant on scenes containing a lot of triangles.

However, this is far from the only thing that has occupied my attention. I have been thinking about avoiding the quite expensive rendering of photon volumes each frame, and instead do some kind of caching of the result. There is simply no point in spending a lot of resources on updating indirect illumination each frame when it is such a low-frequency phenomena. Being inspired by Geomerics and DICE I decided to use light maps, rendered on the GPU. So I guess that I’m not implementing ISPM any more. Here are a couple of the problems that I can currently see with the approach:
*Noise – I’m guessing that to reduce noise, a large amount of rays and/or a low resolution light map is required
*Rendering of the light maps – My current approach uses DirectCompute to render the light map (which is a RWTexture2D), and it works fairly well. The problem is that data is not completely synchronized in the memory so one thread might overwrite data that was recently written by another thread, that is obviously bad. This leads to spots in the light map being slightly darker than they should be (and that, if updated each frame, the light map flickers).

The funny thing is that by solving the first of these two problems by adding more rays or lowering the resolution of the light map, I make the second problem worse. The solutions I currently have for the second problem does not completely remove the artifacts, just reduces them a lot. The first option is to render the light map at a much higher resolution, to reduce the risk of conflicting pixels, and then down sample it. However, this requires a lot of memory and down sampling could be quite costly. The other option is to trace a small subset of all rays and store the result in a separate texture, then this texture is additively blended onto the main light map. Depending on how many rays that is required in a scene and how much collisions that generally occur, I’m wildly guessing that somewhere around 10-100 iterations are necessary. These iterations can also be trivially amortized over several frames, and it’s really only necessary to perform such an update when the lighting condition changes.

I have quite a few more ideas that I would like to write about, but that will have to wait for another time.

Also, I have rewritten large chunks of my resource manager and written a simple thread pool to go with it. Now, resources are loaded asynchronously with a nicer API and the possibility to reload resources that are out of date. I must say that the last part is pretty convenient when experimenting with the shaders, no more restarts and instant result really rocks! My only regret is that I didn’t implement it sooner. I would love to post some source code, but since I’m quite new at multithreaded programming and there could be some very nasty and hard to track down bugs I think I’ll skip it this time.

~Daniel