diff --git a/src/testrender/raytracer.h b/src/testrender/raytracer.h index eef7f2a3e..a8a9845c8 100644 --- a/src/testrender/raytracer.h +++ b/src/testrender/raytracer.h @@ -40,9 +40,14 @@ class OptixRenderer; // FIXME -- should not be here inline OSL_HOSTDEVICE void ortho(const Vec3& n, Vec3& x, Vec3& y) { - x = (fabsf(n.x) > .01f ? Vec3(n.z, 0, -n.x) : Vec3(0, -n.z, n.y)) - .normalize(); - y = n.cross(x); + // https://research.pixar.com/docs/2017.Others.DBCHKLV.pdf + // Duff, et al. "Building an Orthonormal Basis, Revisited", JCGT 6(1) 2017. + float sign = copysignf(1.0f, n.z); + const float a = -1.0f / (sign + n.z); + const float b = n.x * n.y * a; + + x = Vec3(1.0f + sign * n.x * n.x * a, sign * b, -sign * n.x); + y = Vec3(b, sign + n.y * n.y * a, -n.y); } diff --git a/src/testrender/sampling.h b/src/testrender/sampling.h index 69ec6909a..06665c821 100644 --- a/src/testrender/sampling.h +++ b/src/testrender/sampling.h @@ -16,7 +16,8 @@ struct TangentFrame { // build frame from unit normal static OSL_HOSTDEVICE TangentFrame from_normal(const Vec3& n) { - // https://graphics.pixar.com/library/OrthonormalB/paper.pdf + // https://research.pixar.com/docs/2017.Others.DBCHKLV.pdf + // Duff, et al. "Building an Orthonormal Basis, Revisited", JCGT 6(1) 2017. const float sign = copysignf(1.0f, n.z); const float a = -1 / (sign + n.z); const float b = n.x * n.y * a;