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

Issue with RTC_GEOMETRY_TYPE_DISC_POINT intersect

Sunier__Romain
Beginner
1,572 Views

Hi,

in order to move our in house renderer to an embree accelerated solution i made some integration tests.

After several tests with RTC_GEOMETRY_TYPE_DISC_POINT intersect, I found a weird behavior.

I tried to build a fonction that gather multiple hits but some points were never intersected.

I simplified the case and i found that if the ray starts inside a box of 2 time the point radius, the hit never occurs.

You can try the following exemple:

RTCDevice device = rtcNewDevice( NULL );
RTCScene scn = rtcNewScene( device );

auto RTCGeom = rtcNewGeometry( device, RTC_GEOMETRY_TYPE_DISC_POINT);

Parts *point = (Parts*)rtcSetNewGeometryBuffer( RTCGeom,
RTC_BUFFER_TYPE_VERTEX,
0, RTC_FORMAT_FLOAT4,
sizeof(Parts), 1);

// Parts ( x,y,z,radius )
point[0] = { 0, 0, 0 ,4 };

// finally commit rtc geometry changes
rtcCommitGeometry( RTCGeom );
rtcAttachGeometry( scn, RTCGeom );
rtcCommitScene( scn );

// init ray inside "box" of size radius
RTCRayHit rayHit;

rayHit.ray.org_x = 0;
rayHit.ray.org_y = 0;
rayHit.ray.org_z = -1; // less than 2 x radius

rayHit.ray.dir_x = 0;
rayHit.ray.dir_y = 0;
rayHit.ray.dir_z = 1;

rayHit.ray.mask = 1;
rayHit.ray.time = 0;

rayHit.ray.tnear = 0;
rayHit.ray.tfar = 100000000;

rayHit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
rayHit.hit.primID = RTC_INVALID_GEOMETRY_ID;
rayHit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;

RTCIntersectContext context;
rtcIntersect1( scn, &context, &rayHit);

if( rayHit.hit.geomID != RTC_INVALID_GEOMETRY_ID )
{
std::cerr<<"found hit inside "<<std::endl;
}
else
{
std::cerr<<"no hit inside"<<std::endl;
}

// init ray outside "box" of size radius
RTCRayHit rayHit2;

rayHit2.ray.org_x = 0;
rayHit2.ray.org_y = 0;
rayHit2.ray.org_z = -10; // more than 2 x radius

rayHit2.ray.dir_x = 0;
rayHit2.ray.dir_y = 0;
rayHit2.ray.dir_z = 1;

rayHit2.ray.mask = 1;
rayHit2.ray.time = 0;

rayHit2.ray.tnear = 0;
rayHit2.ray.tfar = 100000000;

rayHit2.hit.geomID = RTC_INVALID_GEOMETRY_ID;
rayHit2.hit.primID = RTC_INVALID_GEOMETRY_ID;
rayHit2.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;

RTCIntersectContext context2;
rtcIntersect1( scn, &context2, &rayHit2);

if( rayHit2.hit.geomID != RTC_INVALID_GEOMETRY_ID )
{
std::cerr<<"found hit outside"<<std::endl;
}
else
{
std::cerr<<"no hit outside"<<std::endl;
}

 

The result is :

no hit inside

found hit outside

 

Did i miss something or there is an issue with Point / Curves geometry ( as they both use the same intersector )

0 Kudos
1 Solution
SvenW_Intel
Moderator
1,557 Views

This is a feature to avoid self intersections when shooting secondary rays from the hit point.

You can disable this feature by setting the CMake config EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR to 0. But then you have to take care of self intersections of ray oriented points and flat curve types yourself by starting secondary rays the curve/point radius away of the curve/point.

View solution in original post

0 Kudos
2 Replies
SvenW_Intel
Moderator
1,558 Views

This is a feature to avoid self intersections when shooting secondary rays from the hit point.

You can disable this feature by setting the CMake config EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR to 0. But then you have to take care of self intersections of ray oriented points and flat curve types yourself by starting secondary rays the curve/point radius away of the curve/point.

0 Kudos
Sunier__Romain
Beginner
1,548 Views

Thanks a lot, this solution perfectly works. You saved my day.

 

0 Kudos
Reply