Intel® Embree Ray Tracing Kernels
Discussion forum on the open source ray tracing kernels for fast photo-realistic rendering on Intel® CPU(s)

Wrong normal returned

Al_N_
Beginner
1,002 Views

Hello again,

I'm having problems with embree returning the wrong normal. Here's what I did to test this, create a sphere where the front faces are all facing out, shoot rays from outside towards the sphere and often the dot(raydir, Ng) returns positive as oppose to negative.

I have no clue what's going on and yes I do have ROBUST set. Can you help? thank you.

0 Kudos
9 Replies
BenthinC_Intel
Employee
1,002 Views

Hi,

The triangle geometry normal (which is returned in the ray hit structure) is computed by:

e1 = v0-v1, e2 = v2-v0, Ng = e1 x e2

Obviously the normal orientation depends on the order of v0,v1,v2. As long as all your input triangles are correctly oriented you should be able to modify your front/back-face test to get consistent results.

Hope this helps.

0 Kudos
Al_N_
Beginner
1,002 Views

Hi and thanks for the answer but the problem isn't that because I tested it with many shapes, even a simple cube and it still does it. I also use my own normal calculation and still have few out of millions. If I use my own kdtree instead it works fine with the exact same code. I wonder, how is it affected by tnear and does the returned tfar adjusted properly to account for tnear?

0 Kudos
SvenW_Intel
Moderator
1,002 Views

The winding order of the triangles determines which direction the geometry normal is pointing into. Just switch two vertices of each triangles to invert the winding order, or negate the returned Ng.

0 Kudos
Keymaster
New Contributor I
1,002 Views

Just a wild guess, but if you transform the vertices with a matrix with negative parity, you have to switch the order of triangles so the face orientation is preserved.

For 4*3 affine TM you can compute parity using:

INLINE float parity() const {
   return dot(cross(getColumn(0), getColumn(1)), getColumn(2));
}

0 Kudos
Al_N_
Beginner
1,002 Views

Thank you guys but the problem is not the winding order. It seems to happen because of the float error. How do you handle a corner of a room for example, when a ray hit wall 1 at a distance of 0.000001 from wall 2 and the ray bounces towards wall 2, tfar return 0 as a distance and return wall 1 as the hit object, even if I use the filter function to skip self hit. It should at least return wall 2 as the object hit even if tfar return 0.

0 Kudos
SvenW_Intel
Moderator
1,002 Views

Try to enable RTC_SCENE_ROBUST mode at scene construction time. This will almost guarantee that your mesh will be watertight when intersecting and should fix the missed intersection with wall 2.

If you filter out the hit to wall 1 using the filter functions, you should not get wall 1 as hit reported. Alternatively, you can also try to initialize tnear to some small epsilon (e.g. 1E-5) to avoid self intersections.

0 Kudos
Al_N_
Beginner
1,002 Views

I did this too but the problem happen with large values. For example, if you have 2 triangles on top of each other but separated by 0.0001 and your ray origin is at 9.77777E15 and shoot a ray to the triangles, using ray.org + ray.dir * tfar will have the hit point before the 2 triangles or perhaps after both triangles, messing everything up. In the case of a corner, if the ray from outside happen to hit wall 1 at a distance of 1e-10 of wall 2, the hit point is pass both walls, or before, or on wall 2, sometimes wall 1, because of the float precision error how do we ensure proper hit point even with super small or super big values? I thought by using tnear=0 and using the filter to detect self hit would work but it doesn't because of the hit point being too far after or before, hitting something different in some cases.

0 Kudos
SvenW_Intel
Moderator
1,002 Views

If you are really concerned about these corner cases you could use the filter functions to collect all hits along the ray into some list. After that you can manage the corner cases by hand.

0 Kudos
Al_N_
Beginner
1,002 Views

I'm not concerned about the corners, I'm concerned about the artifacts and I'm trying to find a way to make this work without artifacts which seems to always come from the corners.

0 Kudos
Reply