# Bidirectional Path Tracing questions

I'm coding a Bidirectional Path Tracing application for school in C++ and I have some questions (I haven't found useful explanations on the web)

1) Why does the EyePath have one more vertex?

2) When I compute the direct illumination during the EyePath creation, do I need to take account of the value of the previous vertex? I'm asking that because I saw it in some code but it seems weird.

3) I don't understand very well how to connect both paths. Randomly? Everyone with everyone? For the moment I randomly connect one vertex with another one.

4) Our PBRT book implements a contribution according to Eyepath and LightPath length. Do I need to do it, given that all the objects in my scene geometry are diffuse?

5) Are new rays randomly generated in a hemisphere at every bounce?

All objects are diffuse.

For the moment I get this result with 15 samples:

6) Do you have any idea what's going on ?

Thanks you for all of your replies :)

1) Why does the EyePath have one more vertex?

Compared to what ? I'm guessing you're talking about the half path starting from the eye being one vertex longer than the half path starting from the light source? If so, that is could be done because that very first ray starting from the eye is completely constrained (it must go from the camera through a particular pixel), so it isn't random. To keep the randomization & computation "balanced" between both half paths, this ray is considered additional. In general if you have several bounces, it won't matter either way.

2) When I compute the direct illumination during the EyePath creation, do I need to take account of the value of the previous vertex?

What value is that? if it's the direct/indirect illumination computed on that previous vertex, then no, this light flow has no business going to the next vertx and then back up to the eye. If however you were talking about the weighting and filtering accumulated from the eye to to thet point, then yes those transfer funtion should be carried over all the way through.

3) I don't understand very well how to connect both paths. Randomly? Everyone with everyone? For the moment I randomly connect one vertex with another one.

There are many strategies, but the goal is to link both half-paths with visibility path. You could chose a point randomly in your geometry and attempt to link both half-paths through that point, but then the generated points will have no guarantee of being in visibility from either half-paths, and uniformly sampling the surface of your entire geometry would be a tough task.

Rather, you should generate your links so you have at least some guarantee. For instance, you could generate points by sampling the hemisphere of the end of either half-paths and raycasting it into your geometry - this way the visibility to that half-path at least is guaranteed.

If you do it from both sides sequentially you may even reduce variation due to one geometry being in a more pathological configuration - don't put all your eggs in the same basket!

The ideal of course would be to chose a junction point C so that it is in visibility of both half-path ends everytime, that is typically impossible in non-trivial geometries.

Finally the Everyone with everyone strategy is not good if I understood your meaning. If you meant sample both hemispheres, project both samples into the geometry to obtain many couples and attempt to join those couples with a visibiltiy test, then you're back to square one - you've only lenghtened both paths by 1 ray.

4) Our PBRT book implements a contribution according to Eyepath and LightPath length. Do I need to do it, given that all the objects in my scene geometry are diffuse?

I don't really understand what that contribution is but I'm guesing this:

To reduce variance, the path length is left free, typically using russian roulette. Every time your path survives the roulette, its contribution is amplified (divided) by the change of surviving. Normally the length (accumulated distance is of no concern because light does not dim along a ray (it only dims in density along a widening one of light, but we're samppling rays here).

5) Are new rays randomly generated in a hemisphere at every bounce?

All objects are diffuse.

With diffuse objects the light coming in from any direction will have the same contribution to the outgoing radiation (apart from the cosine factor, I'll come back to it) by the sheer definition of a "diffuse" surface. The stratified sampling theory tells us the optimal sampling strategy is uniform, so yeah, randomly generating rays in the hemisphere is what works best for diffuse surfaces.

That said, If we come back to my note about the cosine factor, there is a better sampling strategy, which is the cosine sampling. Instead of sampling uniformly, then dividing by the cosine factor, you could cosine-weighted sample the hemisphere, and ommit the division altogether. This would bring denser ray where the constribution will be greatest (so lower variance) and remove a division and cosine operation. This is typically done almost all the time, to the point that many people even forget to bring back the cosine division for non-diffuse surfaces!

For the moment I get this result with 15 samples:

6) Do you have any idea what's going on ?

This looks like the first iteration of a fine-looking image. What is bothering you, exactly?

To me the graining is because you may need more samples. The only thing I find odd is that your light doesn't seem to be sampled by the direct rays from the camera (it is 'invisible' to the eye). This could mean some of your intermediate rays might also miss it, resulting in wrong lighting and artifacts.