Done by TPathTracer
class in
RayTracer
unit.
Surface lights are used: every shape with non-zero
emissiveColor
is considered a light emitter.
For each image pixel many random paths are checked and final pixel color
is the average color gathered from all paths.
Path length is determined by a given minimal path length and a Russian-roulette parameter. Every path will have at least the specified minimal length, and then Russian-roulette will be used to terminate the path. E.g. if you set minimal path length to 3 and Russian-roulette parameter to 0.5 then 1/2 of all paths will have length 3, 1/4 of all paths will have length 4, 1/8 of all paths will have length 5 etc.
Russian-roulette makes sure that the result is unbiased, i.e. the expected value is the correct result (the perfect beautiful realistic image). However, Russian-roulette introduces also a large variance, visible as a noise on the image. That's why forcing some minimal path length helps. Sensible values for minimal path length are around 1 or 2. Of course, the more the better, but it will also slow down the rendering. You can set minimal length to 0, then Russian-roulette will always be used to decide about path termination (expect a lot of noise on the image!).
Actually our path-tracer does something more than a normal
path-tracer should: for every pixel it checks
PrimarySamplesCount
of primary rays,
and then each primary ray that hits something splits into
NonPrimarySamplesCount
. So in total we check
PrimarySamplesCount
*
NonPrimarySamplesCount
paths.
This optimization comes from the fact that there is no need to take many
PrimarySamplesCount
, because all primary rays hit
more-or-less the same thing, since they have very similar direction.
To get really nice results path-tracer requires a different
materials description. I added
a couple of additional fields to Material
node
to describe physical material properties (for Phong's BRDF).
If these fields are not specified in Material
node,
path-tracer tries to calculate them
from normal material properties, although this may result in a poor-looking
materials. There's also a program kambi_mgf2inv
available that let's you convert MGF files to VRML 1.0 generating correct
values for these additional Material
fields.
Shadow cache is used, this makes path-tracer a little faster. Also you can generate the image pixels in more intelligent order than just line-by-line: you can use Hilbert or Peano space-filling curves. In combination with shadow cache this can make path-tracing faster (shadow cache should hit more often). Although in practice space-filling curves don't make any noticeable speed difference. Undoubtedly, there are many possibilities how to improve the speed of our path-tracer, and maybe one day space-filling curves will come to a real use.