Category: Bug Hunting

2009-08-21

Permalink 02:07:27 am, by Olliebrown Email , 331 words, 3573 views   English (US)
Categories: GSoC 2009, Bug Hunting

A Bit of Unit Testing

I had a thought on how to do some basic unit testing to eliminate one possibility for error in my code. Each of the distribution functions I've implemented has never been tested, just copied out of the book (or worked up by myself) and assumed correct. This includes the code to distribute rays from a spotlight. So, I decided to write a quick program that would visualize each of these distribution functions as a way of verifying them (and also a first step towards testing the spotlight code).

Here's some images for each distribution:

Equal distribution around the hemisphere
This is a visualizaiton of the EqualScatter function that randomly distributes rays around the hemisphere. Initially I found an error here that distributed rays to the full sphere instead of the hemisphere but as you can see, this has been fixed.

Diffusely distributing across the hemisphere.
This is the DiffuseScatter function which scatters rays across the hemisphere that fall-off according to the cosine function away from the surface normal. Note the less-dense rays near the surface.

Stratified sampling around the hemisphere.
This is the StratifiedSample function which discretizes the hemisphere into an MxN grid and sends out one random ray in each grid cell. The grid has small cells around the normal that increase in size towards the surface to simulate diffuse reflection. Note less density at the surface and the relatively more even distribution around the hemisphere.

I found, by doing this, that there was an error in my equal distribution function. Namely, it was distributing rays in the entire sphere not just the hemisphere. Easy fix. this would results in lots of lost photons and did help brighten the photon simulation which is always good considering how much darker it is than the raytracing version.

Here's the spotlight with different 'outter' values:

Distribution from a spotlightWider Distribution from a spotlightNarrower distribution from a spotlight.
These three images show the spotlight photon distribution function set with different 'outer' values. Note that spotlight falloff between inner and outer is not supported.

This all looks good so I think the spotlight code is correct assuming I've interpreted the parameters correctly.

2009-08-14

Permalink 08:07:52 pm, by Olliebrown Email , 749 words, 3727 views   English (US)
Categories: GSoC 2009, Bug Hunting, Misc.

Calibration Revisited

My handling of light attenuation turned out to be incorrect. Res and Martin set me straight. I had the conceptual model that distance attenuation accounts for the phenomenon of light losing power as it travels through a medium (even just the atmosphere). This is called attenuation in physics and optics but in graphics this is not what distance attenuation is accounting for. Distance attenuation accounts for the fact that as light moves away from its source the energy spreads out (I assume like a wavefront spreading out). It does so like the surface of a sphere so the 'realistic' distance^2 factor accounts for this spreading out perfectly.

The consequence of this type of attenuation (the correct type) is that photon mapping attenuates automatically. We are distributing photons equally around the sphere of the light source and when they land they will be distributed according to how far away they are from the light. The density of this distribution already has this spreading effect built in automatically.

So, to really do calibration between raytracing and photon mapping I need to remove the attenuation from the photons (already done) and then switch all the lights to use 'realistic' attenuation (which is not the default). My apologies to res for second guessing his advice as this was his original suggestion. As soon as I did this it became apparent that things were dramatically more comparable between raytracing and photon mapping:

Raytracer
Photon Mapper
4.0
Raytraced 4.0 power lights

Photonmapped 1.0 power lights (4M photons, 4K samples)
6.0
Raytraced 6.0 power lights

Photonmapped 6.0 power lights (4M photons, 4K samples)
8.0
Raytraced 8.0 power lights

Photonmapped 8.0 power lights (4M photons, 4K samples)
10.0
Raytraced 10.0 power lights

Photonmapped 10.0 power lights (4M photons, 4K samples)
12.0
Raytraced 12.0 power lights

Photonmapped 12.0 power lights (4M photons, 4K samples)

These images show the results of direct lighting computed with the raytracer and the photon mapper. Each one is given the exact same input however they do not result in the exact same output. Furthermore, the difference is not constant or linear. Note that the images shown above match the range of the graph below from the lower knee up to the point that the curves cross (16 - 48 on the x-axis).

As you can see, despite the similarity resulting from the change to realistic attenuation there is still a marked difference in the exposure of the two. After revisiting this from many different angles, over and over again, and after changing the code in different ways and attempting both a mathetamical and visual calibration I've decided that this issue is going to have to wait. Here's an example of the problem:

Comparison of Average Luminance w/ Proposed Calibration
This graph compares the average luminance of the images generated by raytracing and photon mapping for light sources ranging from 0.25 to 50.0 in power (in 1.0 increments). There are four lights in the scene so this is a scene luminance from 1 to 200 (the x-axis of the graph). Note that the shape of the two curves is essentially the same (a standard exposure curve with a knee and shoulder) but that the have significant differences in where the curves features are occurring.

Note that the raytracing and photon mapping graphs have similar but miss-aligned shapes. This miss-alignment is the problem. There is no easy way to simply fudge things and fix it as it will be entirely dependent on the scene being rendered. Furthermore, I'm starting to think (after talking with colleagues) that there is a mistake somewhere in either the RT code or the PM code that is causing this miss-alignment and simply fudging things to fix it is not a permanent solution (or one that I should be spending so much time on).

So, three days gone on this but at least I have something to show for it. New configuration options! (well, and a lot of frustration!) Here's the new options:

'forcerealistic' - This option can be enabled or disabled and will force all the static and pseudo-dynamic lights in a world to use 'realistic' attenuation mode. This saves the trouble of having to re-do your world in order to use it with photon mapping.

'lightpowerscale' - Scale all the lights in a scene by the given scaling factor. This scale is applied to the light color which is essentially the same as it's power. When you use 'forcerealistic' things tend to get much darker so the lights need to be scaled up to compensate. Again, this option avoids having to edit the world file to achieve this.

'pmlightscale' - Like 'lightpowerscale' this will scale all the static and pseudo dynamic lights in the scene but only for the photon mapping phase. This is in addition to any scaling applied by 'lightpowerscale'. This allows you to fudge things from the command line and bring the exposure of the photon mapping simulation and the raytracer in line with one another.

2009-08-11

Permalink 09:45:48 pm, by Olliebrown Email , 272 words, 2994 views   English (US)
Categories: GSoC 2009, Code Progress, Bug Hunting

Attenuation & Calibration

After posting about my intention to calibrate the energy between photonmapping and raytracing 'res' sent me a message concerning attenuation. This reminded me that I had previously considered that light was being attenuated in the direct lighting raytracer but didn't seem to be in the photonmapper. I had left this in light of larger problems with the photonmapper but as res pointed out, it is critical to address this prior to calibration.

So, I explored the Light class and noticed that it has an internal mechanism to call an attenuation function that will attenuate for distance based on the attenuation coefficients and mode. I decided to move this function (ComputeAttenuation()) from the protected section of the class to the public section so I could access it from the photonmapping code. So now, each photon gets attenuated after each bounce by the distance it traveled according to the attenuation parameters of the light it was emitted from. This small change already made a big difference in the quality of the simulation! It also caused the calibration problem to become even worse as everything got noticeably dimmer in the photonmap.

So, now we're ready to calibrate. To do this, I adjusted the lights from 1.0 down to 0.1 in the world file in 0.1 increments (changing each color channel equally) and generated lightmaps that contained direct light only (one with raytracing, one with photon mapping). For now, I'm just trying to do a visual comparison between the results and scale the photonmapping version until it approximately matches the raytraced version. You can see the progress below. I will add more as I am able.

Raytracer
PM Before
PM After
0.1 Raytraced 0.1 power lights 1K photons, 100 samples per element Calibrated PM 0.1 power lights
0.3 Raytraced 0.3 power lights 10K photons, 100 samples per element Calibrated PM 0.3 power lights
0.5 Raytraced 0.5 power lights 100K photons, 100 samples per element Calibrated PM 0.5 power lights
0.7 Raytraced 0.7 power lights 1M photons, 100 samples per element Calibrated PM 0.7 power lights
0.9 Raytraced 0.9 power lights Photonmapped 0.9 power lights Calibrated PM 0.9 power lights

2009-07-23

Permalink 07:37:55 pm, by Olliebrown Email , 425 words, 2148 views   English (US)
Categories: GSoC 2009, Code Progress, Bug Hunting

When in Doubt, Visualize

That should be the mantra of every graphics programmer ... at least, that's what some professor told me one time.

I worked up a direct visualization of the photon emission stage by simply drawing points in space for each photon. I set the color of each point to the power of the photon and now I'm seeing something very important. The power is not attenuating ... AT ALL. That's why we aren't getting any shadows and that's probably why everything is a constant power and too dim.

I thought that I could safely ignore the photon power until milestone 2 but I think I need to deal with it now so that's going to be the current task.

Here's the visualizations:

Directly visualizing the Cornell Box Photon Map
Directly visualizing the Cornell Box Photon Map with 1000 photons emitted total (250 from each light).

Directly visualizing the Cornell Box Photon Map
Directly visualizing the Cornell Box Photon Map with 10,000 photons emitted total (2,500 from each light).

Directly visualizing the Cornell Box Photon Map
Directly visualizing the Cornell Box Photon Map with 100,000 photons emitted total (25,000 from each light).

Directly visualizing the Cornell Box Photon Map
Directly visualizing the Cornell Box Photon Map with 1,000,000 photons emitted total (250,000 from each light).

Note: the number of photons listed is the number of emitted photons. Since photons are recorded each bounce there are actually MANY more being added to the map and drawn. With russian roulette in play, the photons are bouncing about 5 times on average so multiply the number of emitted photons by 6 to get the number being drawn and the number of rays being traced. This is all still happing quite efficiently. The last case has about 6M rays to trace and it does so in only a few minutes. Not bad! Unfortunately, the splatting/final gather phase is painfully slow still. I think it's because the kd-Tree for the photon map is not being properly balanced.

Some Observations about these images:

  • Almost no photons are landing under the boxes (which is as it should be). The ones that appear to be there are actually on the front face of the boxes. I thought this was a problem as there is light appearing in the light map in these areas but it must be getting there in the splatting/gathering phase
  • The photons are VERY uniformly distributed. Again, this is as it should be since we are doing purely diffuse bounces.
  • The shadows are missing. My new theory is that this is because we are not attenuating the power after each bounce
  • Each scene just gets brighter and brighter. This shouldn't happen as the power should be evenly divided between the photons emitted. This is also a problem with the power attenuation.
Permalink 04:35:36 pm, by Olliebrown Email , 378 words, 1620 views   English (US)
Categories: GSoC 2009, Code Progress, Bug Hunting

Status Update

So far, it's been a lot of house cleaning. There's still several key problems with the photon map algorithm that did not resolve themselves as I expected.

The key change was to the photon emitting phase. I added a progress structure to this phase so that we could see when it was happening and how many rays it was creating. More importantly, I changed the photon scattering code to scatter photons diffusely instead of specularly. In the end, we are going to need both but for now, the diffuse scattering is more important and I don't think the specular scattering was being done right anyways. My hope is that by changing to diffuse and by ramping up the number of photons being emitted we would get better results right away. This has not been the case.

There are two key problems in the final light maps that have yet to be resolved:

  1. They are WAY too dim. About a tenth of the brightness we get with the direct lighting version.

  2. There are no shadows. PM should get the shadows if you shoot enough photons and we're shooting millions so they should be there.

While these are not the only problems, these problems are the most troubling ones and ones that I theorized were caused by improper photon scattering.

To proceed, I'm going to finish up the scattering with both diffuse and specular components chosen with statistical russian roulette (exactly as suggested in Jensen's book) and then start working on the splatting / gathering phase of the simulation. The code for this phase comes straight from Jensen's book so mostly I'm just going to confirm that its correct before I start to play with it and debug the implementation.

Here's some visuals for what's going on. These images are the actual lightmaps generated by lighter2. In both cases lmdensity was set to 10.0 so that the images generated would be high enough resolution to examine directly:

Cornell Box lightmap - Direct lighting only
This is the current production state of lighter2. Only direct illumination is simulated which captures shadows well but no global effects.

Cornell Box lightmap - Indirect lighting only
This is the state of the photon mapping implementation after my changes (and with an artificial brightening by 4 throughout). Shadows are missing, flat surfaces are noisy and light is getting into places it shouldn't.

OllieBrown

Info about progress on my Google Summer of Code 2009 project on Advanced Lighting & Shading in CrystalSpace.

April 2014
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
             
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30      

Search

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 270

powered by
b2evolution