wahn/rs_pbrt

Fix integrators (using enum samplers)

wahn opened this issue · 9 comments

wahn commented

Did we break anything by replacing the sampler traits by enum?

Integrator "ambientocclusion" :

> imf_diff -d -f pbrt_rust.exr pbrt.exr
pbrt_rust.exr pbrt.exr: no differences.
== "pbrt_rust.exr" and "pbrt.exr" are identical

Integrator "directlighting" "integer maxdepth" [10]:

> imf_diff -d -f pbrt_rust.exr pbrt.exr
pbrt_rust.exr pbrt.exr: no differences.
== "pbrt_rust.exr" and "pbrt.exr" are identical

Integrator "whitted" "integer maxdepth" [5]:

> imf_diff -d -f pbrt_rust.exr pbrt.exr
pbrt_rust.exr pbrt.exr: no differences.
== "pbrt_rust.exr" and "pbrt.exr" are identical

Integrator "path":

> imf_diff -d -f pbrt_rust.exr pbrt.exr
pbrt_rust.exr pbrt.exr: no differences.
== "pbrt_rust.exr" and "pbrt.exr" are identical

Integrator "bdpt":

> imf_diff -d -f pbrt_rust.exr pbrt.exr diff.jpg
differing pixels:	 81.946% (204866 of 250000)
average difference:	 12.432%
maximum difference:	 85.706%
Summary: Many pixels differ strongly.
== "pbrt_rust.exr" and "pbrt.exr" are different

diff

wahn commented

After commit a51aba2:

diff

wahn commented

C++ breakpoint:

b src/integrators/bdpt.cpp:424

Rust breakpoint:

b src/integrators/bdpt.rs:1030

Print L (or in Rust l) Spectrum values at breakpoint:

# first value C++, second value Rust
c = {0.269885153, 0.162629977, 0.162629977}
c = {0.269885153, 0.162629977, 0.162629977}
c = {0.19416213, 0.250923485, 0.19416213}
c = {0.19416213, 0.250923485, 0.19416213}
c = {0.608419597, 0.616556108, 0.608419597}
c = {13.6560163, 13.6641531, 13.6560163}

So, let's investigate why we get a different value for the third breakpoint hit.

wahn commented

I think I found the problem:

(gdb) b src/integrators/bdpt.cpp:233 if s == 0 && t == 3
(gdb) run
(gdb) finish
0.00676734932

vs. (Rust)

(gdb) b src/integrators/bdpt.rs:1549 if s == 0 && t == 3
(gdb) run
(gdb) finish
0.332957268
wahn commented

After commit 17b4442 we get a 100% match:

> imf_diff -d -f pbrt_rust.exr pbrt.exr
pbrt_rust.exr pbrt.exr: no differences.
== "pbrt_rust.exr" and "pbrt.exr" are identical
wahn commented

We still have differences with Integrator "mlt":

> imf_diff -d -f pbrt_rust.exr pbrt.exr diff.jpg
differing pixels:	 86.408% (216021 of 250000)
average difference:	 12.018%
maximum difference:	 86.603%
Summary: Many pixels differ strongly.
== "pbrt_rust.exr" and "pbrt.exr" are different

diff

wahn commented

Now (since commit 610bb56) the Integrator "mlt" works:

> imf_diff pbrt.exr pbrt_rust.exr 
differing pixels:	  0.001% (2 of 250000)
average difference:	  1.961%
maximum difference:	  1.961%
Summary: 2 pixels differ slightly.
== "pbrt.exr" and "pbrt_rust.exr" are similar

TODO: Check SPPMIntegrator and VolPathIntegrator ...

wahn commented

The test scene (caustic-proj.pbrt), using the SPPMIntegrator, renders differently for Rust vs. C++, but most likely this is due to the fact that for C++ I can use only OpenEXR files for the environment where for Rust I can use (currently) only HDR images:

diff

> imf_diff -d -f caustic-proj.exr pbrt_rust.exr diff.jpg
differing pixels:	  6.448% (16904 of 262144)
average difference:	  1.840%
maximum difference:	 47.242%
Summary: Many pixels differ strongly.
== "caustic-proj.exr" and "pbrt_rust.exr" are different

So let's fix the VolPathIntegrator and close the issue after that ...

wahn commented

Right now I commented some stuff out in the Rust code, so both versions (C++ vs. Rust) render differently. Let's fix that:

cloud

vs. (Rust version):

pbrt

wahn commented

C++ and Rust still render this test scene differently:

diff

> imf_diff -d -f pbrt_rust.exr cloud.exr diff.jpg 
differing pixels:	 84.024% (490026 of 583200)
average difference:	 22.066%
maximum difference:	 86.263%
Summary: Many pixels differ strongly.
== "pbrt_rust.exr" and "cloud.exr" are different

But the overall image looks OK enough for now:

pbrt

Debugging why there is still such a big difference has to be done in the future, but right now we can't compare the results because we use different textures for lighting anyway:

> diff cloud.pbrt cloud_no_exrs.pbrt 
18c18
<     LightSource "infinite" "string mapname" ["textures/skylight-morn.exr"]
---
>     LightSource "infinite" "string mapname" ["textures/skylight-morn.hdr"]

Let's close the issue for now. All algorithms/integrators should render reasonable well for Rust and similar enough comparing against the C++ version.