I'm currently working on a simple raytracer, and until now I've successfully implemented several features, like antialiasing, depth of field and soft shadows with area lights. An image representing my work could be this one:
(there's no AA here)
The next step was adding reality to the render with some global illumination algorithm, so I decided to move to the photon mapping way, which seemed the easiest one.
To do so I read some papers I found on the web, such as this one: http://graphics.stanford.edu/courses/cs348b-01/course8.pdf
which is very well written.
Now my program can shoot photons in the scene and store them after the first bounce (diffuse or specular), then scale the power of every single photon to LIGHT_POWER / PHOTON_AMOUNT. A direct visualization of this is represented in these images, where I shot 1000k and 50k photons, each allowed to bounce 6 times, for a total of 5000k and 250k photons in the global map:
I thought the effect is right, so I moved to the next part, the one where the photons within a certain radius over the intersection point of the raytraced rays are used to calculate the indirect illumination.
In my raytracer I do as follows:
for each pixel I send a ray trough it to intersect the scene and calculate the direct illumination (dot(N, L) * primitive.color * primitive.diffuseFactor * light.power)
, and the specular term;
Here is the tricky part: I look for the nearest photons which lie in a fixed radius disc around the point of intersection and sum the light produced by each one this way:
for each photon within radius calculate light the same way as for direct lighting (dot(-photonDir, N) * primitive.color * photonColor) and sum everything up.
When every interesting photon has been processed and added its contribution to the final color I divide it by the area of the disc which defines the search area.
The problem is that doing so I don't get the desired result, in particular the ceiling is very dark compared to images I found on the web (I can't get how the ceiling can be as bright as the floor if the latter has an additional contribution from the direct lighting, and how it can be white if the photons on it are only red or green).
An image representing the problem is the following:
This has been rendered using 150k photons, with 4 bounces each, and the direct illumination has been divided by PI.
Also, if you know how I can remove those ugly artifacts from the corners, please tell me.
First, thanks a lot for all your help.
Second, I'm here to announce that after some trouble and after a period in which I didn't touch the code, I finally got it.
I haven't understood what I was doing wrong, maybe the algorithm to get a random direction within a hemisphere, maybe the photon gathering pass... The point is that after reformatting a bit the code (and after implementing a final gathering step and a 2.2 gamma correction) I was able to render the following with 200k photons, 10 diffuse bounces, 20 samples for direct lighting and 100 samples of FG (taken in random - cosine weighted - direction).
I'm very happy with this since it looks almost the same as a reproduction of the scene in c4d path traced with V-Ray.
I still haven't clear what is the utility to store the photon's incident direction, ahahahahahahah, but it works, so it's ok.
Thank's again.