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

Subdivision surfaces, displacement, and smooth normals

Gary_B_
Beginner
611 Views

This is my first post to the forum, so to the developers I'd like to give kudos for such a clean api and a well performing implementation.  It's been a pleasure to use.

Now on to my question: Is there any advice for getting smooth subdivision normals while using displacement? I'm defining RTCORE_RETURN_SUBDIV_NORMAL in my build configuration. I'd like to avoid hacking on the sources in favor of working within the Embree design as intended. Should I consider moving to the development branch of the git repository? What's the intent with that branch regarding the typical client?

This is one example from the source code (which I'm sure the developers are already very familiar with) that is nuking the smooth normal return. The same conditional is effectively in place for each ray type.

#if defined(RTCORE_RETURN_SUBDIV_NORMAL)
        if (likely(!hit_patch->hasDisplacement()))
          {         
        Vec3fa normal = hit_patch->normal(r.v,r.u);
        r.Ng = normal;
          }
#endif

 

 

0 Kudos
4 Replies
SvenW_Intel
Moderator
611 Views

To implement smooth normals for displacement mapped surfaces one needs the derivatives dPdu and dPdv of the hit point. This feature will be added in the upcoming Embree release. Have a look in to the displaced_geometry tutorial of the devel branch of Embree. At the top one can enable smooth normals for the displaced surface.

0 Kudos
Gary_B_
Beginner
611 Views

That looks great. The fact that it's based on a generally useful interpolation scheme is even better.

Thanks!

0 Kudos
Gary_B_
Beginner
611 Views

Now that we have release 2.6 I have a few more questions on subdivision surface normal interpolation involving displacement and the new rtcInterpolate function.

When calling rtcInterpolate what should I expect of the "P" argument that returns the interpolated value?  For the buffer type I’m passing RTC_VERTEX_BUFFER. Should it essentially match the value of ray.org + ray.tfar*ray.dir (outside of precision differences)?  Or is it returned as a point on the subdivision surface that has *not* been displaced yet?  Also, should the “dPdu” and “dPdv” values be displaced surface derivatives or undisplaced?

I know there are numerous ways for me to get this wrong, but so far all of my efforts have left me with surface normals that don’t seem to match the displaced surface even if I apply the displacement myself assuming rtcInterpolate isn’t doing that.

The actual ray intersection is properly tracking the displaced surface.  Once I understand which geometry I should expect rtcInterpolate to return I may have better questions.

0 Kudos
SvenW_Intel
Moderator
611 Views

The rtcInterpolate function does not handle displacements directly, it only returns the position (P output) and derivatives (dPdu and dPdv outputs) at the passed u/v location.

However, the application knows the displacement function and can calculate the derivatives of the final surface Q based on these. Assuming a shader displaces by D along the geometry normal, then dQdu can be approximated very accurately the following:

dQdu = dPdu + Ng*dDdu

Have a look at the displacement_geometry tutorial and enable ENABLE_SMOOTH_NORMALS at the top.

 

0 Kudos
Reply