You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is there a canonical way to compute the limit surface normal using your API? I've seen in one of your examples N = normalize( cross( dPu, dPv) );, but this is numerically unstable at rounded corners, since dPu and dPv become parallel. I would imagine there are other places it struggles as well, e.g. examples from #947. I was a little surprised your evaluate API doesn't return a surface normal, so I'm hoping you have some guidance for a reliable solution?
We’ve run into similar instability when computing surface normals from dPdu and dPdv. Since our subdivision system uses the Bfr API, could we port the approach used to handle degenerate cases in the GLSL shaders? If not, what reliable alternative would you recommend for computing normals using BFR? We currently compute vertex normals in post-subdivision by averaging the contribution from adjacent faces.
Sorry for the delay dealing with this. There has been some discussion and development internally on extending the API to provide surface normals, but it has stalled given other Pixar priorities (an update here was warranted long ago).
In the meantime, I have some code I can share that can be used externally to resolve common degenerate cases. It does not port the shader implementations (more on that later) but has a sound mathematical basis and is similarly effective. It makes use of second derivatives in cases where the first derivatives are zero or parallel and the simple cross product fails.
I'll package that up as an extension to one of the Bfr tutorials and try to post a branch soon.
I've prepared a branch on my fork (tutorial_normal_eval) with some code to deal with this issue until OpenSubdiv provides its own solution:
I've modified ./tutorials/bfr/tutorial_1_2 (a simple tessellation example that generates points and normals in Obj format) with additional external code to make use of second derivatives when the simple cross product of first derivatives fails.
Some of the new external code is written to be completely independent of OpenSubdiv while some is written to work with it, i.e. making use of the independent solution with Bfr::Surface (see patchNormal.cpp for the former and extendedSurface.cpp for the latter).
A directory of example shapes was also created to verify the improvement. This includes most cases noted in the old issue #947 cited above along with a few others.
See the README file added to the tutorial directory first for an overview and more information.
Thanks @barfowl for this! We have a few assets that cause some issues with the original normal computation, I'll test it with them and see if your new method resolves it.
Activity
davidgyu commentedon Jun 26, 2025
Filed as internal issue #OSD-460
rgirish28 commentedon Oct 9, 2026
We’ve run into similar instability when computing surface normals from dPdu and dPdv. Since our subdivision system uses the Bfr API, could we port the approach used to handle degenerate cases in the GLSL shaders? If not, what reliable alternative would you recommend for computing normals using BFR? We currently compute vertex normals in post-subdivision by averaging the contribution from adjacent faces.
barfowl commentedon Oct 11, 2026
Sorry for the delay dealing with this. There has been some discussion and development internally on extending the API to provide surface normals, but it has stalled given other Pixar priorities (an update here was warranted long ago).
In the meantime, I have some code I can share that can be used externally to resolve common degenerate cases. It does not port the shader implementations (more on that later) but has a sound mathematical basis and is similarly effective. It makes use of second derivatives in cases where the first derivatives are zero or parallel and the simple cross product fails.
I'll package that up as an extension to one of the Bfr tutorials and try to post a branch soon.
barfowl commentedon Oct 19, 2026
I've prepared a branch on my fork (tutorial_normal_eval) with some code to deal with this issue until OpenSubdiv provides its own solution:
See the README file added to the tutorial directory first for an overview and more information.
rgirish28 commentedon Oct 27, 2026
Thanks @barfowl for this! We have a few assets that cause some issues with the original normal computation, I'll test it with them and see if your new method resolves it.