## pbrt-v2 grid code traversal problem

Practical and theoretical implementation discussion.
joedizzle
Posts: 21
Joined: Sat Dec 03, 2011 5:08 pm
Location: Nairobi, Kenya
Contact:

### pbrt-v2 grid code traversal problem

Hello everyone,

I've been writing a small path tracer code in java, referencing both SmallVCM and PBRT. I have noticed some problem with the grid accelerator code of pbrt-v2 in which I've referenced their code (complete port to java) and the specific part is the setting up ray for traversal in the grid.

Code: Select all

 if (ray.d[axis] >= 0) {
// Handle ray with positive direction for voxel stepping
NextCrossingT[axis] = rayT +
(voxelToPos(Pos[axis]+1, axis) - gridIntersect[axis]) / ray.d[axis];
DeltaT[axis] = width[axis] / ray.d[axis];
Step[axis] = 1;
Out[axis] = nVoxels[axis];
}
The problem comes with division with ray direction in calculating the NextCrossingT[axis]. Notice that it may yield a negative infinity and positive infinity if the denominator is either -0 or +0 based on IEEE-754 floating point arithmetic standards. This came across whereby I incorporated DirectionalLight (distant delta point light) and I've configured it to generate ray direction if given theta and phi values as spherical coordinates. It has a very big impact when generating shadow rays in which there is no proper intersection. Is it a bug by itself or probably my code is wrong, I just rectified it by avoiding generating -0 values. I also noticed pbrt-v3 does not include grid code, probably there is no plan to include it hence that's why I've put this as a separate topic by itself.

joedizzle
Posts: 21
Joined: Sat Dec 03, 2011 5:08 pm
Location: Nairobi, Kenya
Contact:

### Re: pbrt-v2 grid code traversal problem

Corrected handling of -0 values.

mattpharr
Posts: 9
Joined: Sat Jun 20, 2015 8:59 pm

### Re: pbrt-v2 grid code traversal problem

Huh, very interesting!

So what seems to be happening is that with a -0 direction component, then that dimension's NextCrossingT ends up being negative infinity, and in turn in the ray stepping loop, that dimension is always chosen (wrongly), then it bogus-ly steps along that axis, which is hopeless, since the ray doesn't actually pass through those voxels, and then valid intersections are missed?

I'm curious whether changing

Code: Select all

        if (ray.d[axis] >= 0) {

to

Code: Select all

        if (ray.d[axis] >= 0 && ray.d[axis] != -0) {

makes a difference? (Alternatively, do you have a test case you can share?)

Thanks,
Matt