Light-tracer weights back
Board:
Home
Board index
Raytracing
General Development
(L) [2019/07/09] [ost
by b_old] [Light-tracer weights] Wayback!I'm currently trying to implement a basic light-tracer. The resulting images don't have the expected brightness, however. I strongly suspect it is related to sample weights, when I connect to the camera. For now I only consider a pin hole camera with a lens radius of zero.
I apply the following weights. The formulas are taken from PBRT 3 [LINK https://github.com/mmp/pbrt-v3/blob/master/src/cameras/perspective.cpp#L203 PerspectiveCamera::Sample_Wi()]:
Code: [LINK # Select all]float a = (res_x * res_y) / num_light_paths;
// cos_theta = angle between light ray and image plane normal
// t = distance between camera and shading point
float b = 1.f / ((t * t) / cos_theta);
// A = area of rectangle defined by camera frustum at z = 1
float c = 1.f / (A * cos_theta * cos_theta * cos_theta * cos_theta);
// pixel = a * b * c * sample.evaluate()
When I vary the field of view the image brightness changes noticeably. I wonder whether I calculate A the wrong way, or does this look generally wrong?
(L) [2019/07/10] [ost
by shocker_0x15] [Light-tracer weights] Wayback!>> b_old wrote: ↑Tue Jul 09, 2019 8:29 am
I strongly suspect it is related to sample weights, when I connect to the camera. For now I only consider a pin hole camera with a lens radius of zero.
Does “connect to the camera” mean that you are trying to do NEE with light tracing?
If so, I have feeling that your weight calculation contains many factors that shouldn’t be there.
e.g. image plane area at z = 1, and too many cosine factors.
Weight calculation contains only lens area and perhaps measure conversion factor (area measure to solid angle measure) depending on the implementation.
(L) [2019/07/10] [ost
by shocker_0x15] [Light-tracer weights] Wayback!However sometimes I see an implementation of path tracing which omits the division by the PDF of the first intersection (i.e. PDF for the next vertex to a point on lens).
If you want to match the result to the implementation like this, you need to take additional factors to light-tracing into the account.
(L) [2019/07/11] [ost
by b_old] [Light-tracer weights] Wayback!>> shocker_0x15 wrote: ↑Wed Jul 10, 2019 5:23 pm
Does “connect to the camera” mean that you are trying to do NEE with light tracing?
If so, I have feeling that your weight calculation contains many factors that shouldn’t be there.
e.g. image plane area at z = 1, and too many cosine factors.
Weight calculation contains only lens area and perhaps measure conversion factor (area measure to solid angle measure) depending on the implementation.
Yes, NEE.
I have found out by trial and error that the following formula seems to work for me (I'm leaving out (res_x * res_y) / num_light_paths here, but that is really needed):
Code: [LINK # Select all]1.f / (Scalar_factor * (t * t) * (cos_theta_2 * cos_theta_2))
The problem is, that I don't know how to calculate scalar_factor. I know, that it is related to field of view and image ratio, because if I manually tweak it for certain settings I can scale it with ratio * delta_fov_squared (e.g. delta_fov_squared = 2 * 2, for double the fov) and the error will stay the same.
So in a way, this is the area of the image plane at a certain value of z.
Why do you think it shouldn't be there?
(L) [2019/07/11] [ost
by shocker_0x15] [Light-tracer weights] Wayback!>> Why do you think it shouldn't be there?
I think it depends on the ground truth implementation.
What is your expected brightness? Is it the result of path tracing?
If so, does it contain the division by PDF to generate the first intersection point (the second vertex if the first is on lens)?
(L) [2019/07/11] [ost
by b_old] [Light-tracer weights] Wayback!>> shocker_0x15 wrote: ↑Thu Jul 11, 2019 8:51 am
I think it depends on the ground truth implementation.
What is your expected brightness? Is it the result of path tracing?
If so, does it contain the division by PDF to generate the first intersection point (the second vertex if the first is on lens)?
Ground truth in this case are my other integrators. One is pathtracing including the division by PDF, another is pathtracing with NEE, a third is the combination of both with MIS. They are all consistent, and that is what I'm trying to match with the lighttracer.
(L) [2019/07/11] [ost
by shocker_0x15] [Light-tracer weights] Wayback!I don’t mean the naive pathtracer implementation by “division by PDF to generate the first intersection point”.
Do your path tracing implementation (both with and without NEE) take the “PDF to generate the first intersection point” into account? That PDF is a PDF to generate a primary ray from a camera.
 >> Why do you think it shouldn't be there?
The PDF of sampling a point on lens doesn’t contain factors like the area of image plane.
Factors like the area of image plane are contained in the PDF to generate a primary ray.
(L) [2019/07/12] [ost
by b_old] [Light-tracer weights] Wayback!>>
I don’t mean the naive pathtracer implementation by “division by PDF to generate the first intersection point”.
Do your path tracing implementation (both with and without NEE) take the “PDF to generate the first intersection point” into account? That PDF is a PDF to generate a primary ray from a camera.
No, I'm not taking this PDF into account. In PBRT this weight is always set to 1, right? Or is this another PDF you are talking about?
If I understand you correctly, by omitting this PDF in the pathtracer I need an additional weigh in the lightracer, right?
 >>
The PDF of sampling a point on lens doesn’t contain factors like the area of image plane.
Factors like the area of image plane are contained in the PDF to generate a primary ray.
Quoting PBRT again, are you talking about the following [LINK https://github.com/mmp/pbrt-v3/blob/master/src/cameras/perspective.cpp#L223 PDF]?
Code: [LINK # Select all]*pdf = (dist * dist) / (AbsDot(lensIntr.n, *wi) * lensArea);
As you say, there is no area of the image plane involved. But in the next line We() is called, which does include the image plane area, so I thought that I effectively need both.
Empirical results show, that I do need the image plane ratio in there somehow. Maybe because I don't consider it for primary rays?
Additionally I noticed the reconstruction filter also affects the brightness with the lighttracer. EDIT: This is probably because my filter function is not normalized.
(L) [2019/07/13] [ost
by shocker_0x15] [Light-tracer weights] Wayback!>> If I understand you correctly, by omitting this PDF in the pathtracer I need an additional weigh in the lightracer, right?
Correct.
 >> Quoting PBRT again, are you talking about the following PDF?
Yes.
We need to pay attention when talking about light-tracing (and Bidirectional Path Tracing), so I need the questions.
I found code I implemented Veach-style BPT on PBRT-v2.
I used dirPDF / cos_theta as the extra factor that light-tracer should multiply to the contribution to match the result to other strategies.
"dirPDF" here is the PDF to generate a primary ray which corresponds to connecting ray (lens point and the end vertex of light path). That has the following form:
dirPDF = 1.0 / (pow(cos_theta, 3) * virtualPlaneArea);
(only valid for valid pixels)
It seems the same to your calculation "c" in the original post if virtualPlaneArea is correct.
I can't verify the other factors "a" and "b" which depend on your renderer.
(L) [2019/07/16] [ost
by b_old] [Light-tracer weights] Wayback!I spent a little more time on this, but mainly fixing tangential issues, like e.g. normalizing the reconstruction filter.
To wrap this up, what seems to work for me is using 2.0 * A (A = virtual image plane) in the formulas I posted originally. I cannot explain the factor of 2, but I tested a couple of scenes/camera configurations, and it seems to converge to the same result as the pathtracer.
Thanks for the discussion!
EDIT:
I finally found the reason for the 2.0! Accidentally I was counting splatted particles twice when combining with the samples of the forward integrator. Fixing this, also got rid of the factor.
back