Photon mapping

Started by
13 comments, last by greenhybrid 17 years, 4 months ago
Before I delve into explaining precisely what I'm doing, I'll just ask a simple question. I think I have the photon map set up properly - the photon tracing stage seems to be going smoothly and the distribution is good. However, when estimating the radiance of required points for for the frame buffer, I'm getting some really uncool results. Here's a screenshot of search radius = 1, max number of photons in search radius = 50 (up to 50 samples are averaged to get the queried value) link r = 1, np = 400 link r = 1, np = 1500 link As far as I've read, 200-400 photons are more than adequate to get a good estimate of the radiation at the required points, also in more complex scenes. Also note that there's more than enough photons in the search radius for np = 50 and np = 400 (np = 1500 varies from 40 - 1500 photons in the search radius). Looking at the second image, you'll notice that all of the surfaces are "checkered", which implies bad or uneven distribution (which is nevertheless structured). I'm pretty sure this isn't a matter of distribution so much as proper radiance estimation. I mean, am I supposed to use 1500+ samples to get a good image. Check out this place - scroll down to "2. Area Lights and Soft Shadows" and take notice of the third image (hotlinking for your convenience): No such checkeredness. Also notice how my third image has circles that have formed around the bright spot (which I can't really explain either since the light source is a point and photon distribution is guaranteed to be uniform) and how the floor is still checkered when viewed close up. This leads me to suspect that I'm missing a final phase in my renderer or (since most things seem to be working quite nicely, including the generation of good results with large parameters), there's probably some fundmental flaw in my code. Can anyone suggest what could be wrong off the top of their head (eg how many samples should be enough)? [Edited by - irreversible on December 12, 2006 10:05:31 PM]
Advertisement
Your screenshots are password protected, so nobody can see them.


How exactly are you doing the visualization of the photon map?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Hm - I though I made sure hotlinking was working. Oh well - quickfixed the problem.

I have been using the following method: since packed photon direction is commonly represented through two 8-bit variables (theta and phi, which is the method I'm using right now), these rather naturally map to a 256x256 grid of intensity values that can be exported as a bitmap (to see relative spherical distribution in all directions).

Also, by looking at the produced images after the render, it's easy to deduce that photons have to be present in the correct pattern to form the quite evidently correct lighting pattern. Knowing these two things, I can know that there's a linear distribution of photons throughout the scene and that the distribution itself is correct.

What is lacking is the finesse (the smooth transitions) that should be produced in the render pass by radiance estimation. I hope you can open the images now (sadly, each in a separate window) to see what I have in mind. By clicking on Original Size on the eSnips page, you can view the images in their native 512x512 size.

As stated above, I can get decent results, but only by using an inexorbitant number of photons for the estimation, which - for lack of a better term - is way too damn slow.

I'm using Jensen's code so there shouldn't hopefully be anything too unexpected. The estimation code looks like this:

for(i = 1; i <= np.found; i++)  {  TPhoton *p = np.index;  //use direct mapping with no culling  irrad[0] += p->power[0];  irrad[1] += p->power[1];  irrad[2] += p->power[2];  }double tmp=(1.0f / PI) / (np.dist2[0]);irrad[0] *= tmp;irrad[1] *= tmp;irrad[2] *= tmp;
Direct visualization of the photon map is extremely inefficient, as Jensen notes repeatedly. The real wins come from combining a direct lighting pass (Whitted style) with partial irradiance data from the photon map. Jensen details several techniques for this in the photon mapping book as well as freely available papers all over his site.

In short, what you're getting is precisely what you should be getting.


Also, note that it is generally advisable to use a stratified stochastic distribution of emitted photons, not a purely uniform one.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

I once implemented photon mapping (it's a while back I admit) and what I remember is that I got poor results from the built-in VS2005 random generator. Use the mersenne twister instead, it's faster and much better. That solved similar problems for me.

EDIT: Didn't read the last post above mine; looking at your images it indeed looks like you use an even distribution. Keep it, but add randomness (using the Mersenne Twister).
Quite counter-intuitively, after a little bit of pondering, it seems obvious to use a smaller number of emitted photons, a relatively small number of photons in the estimation and a larger radius to achieve a greater sense of smoothness. This, of course, is only suitable for an ambient diffuse light - directional lights and caustics require just the opposite.

In any case, if the pixellation is normal, then that's that I suppose :). I added the Mersenne twister - I'm not sure of the benefits just yet - the visual quality didn't improve much; however, I haven't done any speed benchmarking with respect to rand() - on large scenes this could make a world of difference.

Thanks for the feedback, guys!
The speed of your PRNG is essentially irrelevant, unless it's stupidly slow. The real costs are in intersection tests and KD-tree traversal for the photon map lookups.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Yeah - I noticed; that's why I was dismayed that 1500+ test samples were needed to be collected to get decent results.
If you plan on using the photon map for indirect or direct lighting, then you should also look into the "final gather" operation, which is computationally expensive (instead of querrying the photon map at that point, it shoots out hundreds of rays over the hemisphere and querries the photon map at those points). This prevents direct visualization of the error associated with the photon map, and generally produces decent results for indirect illumination, though I'm a bit too rusty to remember if it also produces good results for direct illumination.
I don't think direct illumination is a good goal for photon mapping, unless you truly have static scenes. Occlusion problems will become readily apparent in dynamic scenes, but the eye will be more forgiving for indirect lighting. It is my understanding that this is generally the adopted view with radiosity solutions as well.

Along the same lines, real-time raytracing engines are accepting the fact that primary rays are better processed through a rasterizer than through actual path tracing - which should be done for secondary rays (including global illumination algorithms if implemented). The raster engine is just so much faster...

This topic is closed to new replies.

Advertisement