Hi everyone,

I've tried to update my ray tracer to handle Monte Carlo path tracing rather than standard ray tracing, and I have got it working but I'd like to check my algorithm over as I'm unsure about a few things. Here's what I'm doing:

Base rendering routine: For each pixel (loop through y, x) and for each sample (loop through sample number, e.g. 100 rays/pixel) shoot a ray through a random point in the pixel, add the results and then divide by the number of samples.

My trace function does the following:

- For each initial pixel ray, assign an attenuation vector with the value (1, 1, 1) which will be decreased as the ray propagates

- If there's no intersection, return a background colour

- If the intersected shape has an emissive colour, return that colour with 100% probability

- Define the following:

float kd = shape->material.diffuseColour.sum(), ks = shape->material.specularColour.sum(), kt = shape->material.transmitColour.sum();

...where '.sum()' adds together all the components of the vector

- Choose whether to spawn a diffuse, specular or transmitted ray like this:

diffuseAttenuation = attenuation*shape->material.diffuseColour; //Per-component multiplication

diffuseProbability = kd/(kd + ks + kt);

**if **(diffuseAttenuation.findmax() > cutoff && random(0, 1) < diffuseProbability) //'.findmax()' returns largest component of vector

{

- find a random (cosine weighted) direction

- spawn a recursive ray in this direction (its attenuation vector is now equal to diffuseAttenuation)

- multiply it by the current diffuse colour and return.

}

**else**

{

specularAttenuation = attenuation*shape->material.specularColour;

specularProbability = ks/(ks + kt);

**if **(specularAttenuation.findmax() > cutoff && random(0, 1) < specularProbability)

{

- spawn a recursive ray in a perfectly reflected direction (its attenuation vector is now equal to specularAttenuation)

- multiply it by the specular colour and return

}

**else**

{

transmitAttenuation = attenuation*shape->material.transmitColour;

**if **(transmitAttenuation.findmax() > cutoff)

{

- spawn a recursive ray in a perfectly refracted direction (its attenuation vector is now equal to transmitAttenuation)

- multiply it by the transmission colour and return

}

}

}

...OK, so here's what I want to ask about:

- I've seen some sites/papers say that I should divide each ray by its probability, e.g. the colour returned by a diffuse ray should be divided by diffuseProbability, etc... - should I be doing this?

- Are there any things you can see wrong with my algorithm? I don;t have any books on this so I'm just going based on what I can lift from papers and various PDFs from unviersities, none of which seem to tell the full story.

Thanks!

p.s. here's a picture it rendered which took about 45 minutes at 500 samples per pixel. Is this the kind of speed that I should be expecting with this type of path tracing?

http://i.imgur.com/hdVfmXh.png

**Edited by george7378, 08 May 2014 - 07:38 AM.**