Taking more than one sample per pixel does not only help to implement multisampling but it also makes it possible to have area lights, depth of field and some other nice things without a further cost. Our starting point is to choose some random points around a pixel center and consider all the radiance values computed for the rays shot from these points when calculating the final value of this particular pixel. Many strategies can be adopted for choosing these random points and combining radiance values we get. Easiest one is to select all the points just randomly. However, "just randomly" creates quite noisy images. Instead of this, we can adopt jittered sampling, multi-jittered sampling, n-rooks sampling and many more. I implemented jittered sampling and the results are quite satisfying. For the "combining" part, I basically take the average of the radiance values resulted from these rays.
Once you calculated the jittered sample for a pixel, you can use this sample for the area light and the depth of field part as well. For example, say you are going to take 36 samples for your scene. That means you will take 36 jittered sample points around the pixel, 36 different sample points on the area light and 36 different sample points on the aperture of the thin lens camera. Once you take one of this sample, you can use it for the others too. This way, you will have more uniformly distributed samples on each of the planes you are sampling. Of course, this may not apply if you want to take more samples for area lights but not for multisampling or for other combinations that you might want different number of samples.
Ray Tracing from the Ground Up explains these concepts clearly. Also, you can see this to pick a random point on a disk, which you are going to need for disk shaped area lights and for depth of field effect.
Apart from these subjects, I implemented what I've explained in the "lessons learned" part of the previous post. I reduced the rendering time from 1.34 seconds to 0.47 seconds for the image below.
|previous approach, 32 samples|
|mentioned approach, 169 samples|
|mentioned approach, 32 samples|
However, not unexpectedly, the resulting images are a bit noisy. Considering that we are going to take more and more samples when we deal with Monte Carlo method, this approach will be the right choice for sure.
Lastly, let us see what we rendered this week.
|output of glass_plates_point.xml|
kernel execution time: 1.34 seconds
|output of glass_plates_area.xml|
kernel execution time: 1.37 seconds
|output of dragon_spot_light.xml|
kernel execution time: 26.7 milliseconds
|output of dragon_spot_light_msaa.xml|
kernel execution time: 2.07 seconds
|output of spheres_dof.xml|
kernel execution time: 331 milliseconds
|output of metal_plates_area.xml|
kernel execution time: 1.07 seconds
|The dragon under an area light|