I have a small path tracer, and I am trying to figure out how to implement some basic BRDFs. Here's a brief description of the pipeline I use (without recursion):
1) For each pixel:
1.1) For each sample:
1.1.1) I construct a path.
1.1.2) I calculate the contribution of this path.
1.1.3) I calculate the "probability" of this path.
1.1.4) Finally, I calculate the overall color value(taking into account number of samples, "probability" and contribution of the path).
1.2) Take the sum of all samples' values and write it to the pixel.
So, I calculate the direction of reflected rays in the step 1.1.1) I construct a path
.
For now, I have implemented diffuse reflection, specular reflection, glossy reflection, refraction. Now I want to implement a complex BRDF, let's say Cook-Torrance BRDF. I see that it contains several components (diffuse reflection and specular reflection). How should I trace these rays to get the combination? Should I choose between diffuse_ray/specular_ray randomly and then accumulate the values(multiplied by some coefficients) as usual?(like, if a random value is more than 0.5 then I trace a diffuse ray, otherwise - specular) Or should I trace multiple rays from each intersection?
How is it usually implemented in physically-based renderers?
P.S. If somebody knows some good articles on this topic I would be glad to see them. I tried to read pbrt but it seems very complex and huge to me. And some things there are implemented differently, like the camera model and other stuff.
A first step might be to let your BRDF decide how the ray should bounce. If it's a combination of multiple methods, assign a probability in the BRDF to each method, and then have the BRDF pick one according to the given probabilities.
For example, suppose you want a BRDF that's a combination of specular and diffuse reflection. When you instantiate the BRDF, you might tell it that you want 60% specular and 40% diffuse. Then, when your path tracer queries the BRDF to get the reflected ray direction, the BRDF can internally calculate a specular ray 60% of the time and a diffuse ray 40% of the time.
EDIT - another, perhaps more accurate approach would be to have the BRDF use the provided probabilities to generate a reflected direction by interpolating between the two methods. In our example above, when queried, the BRDF calculates a specular ray and a diffuse ray for every intersection, and returns a new ray whose direction is a linear interpolation of 60% of the calculated specular ray and 40% of the calculated diffuse ray.