38 #ifndef RixShadingUtils_h 39 #define RixShadingUtils_h 66 #define F_PI (3.14159265f) 67 #define F_TWOPI (6.283185307f) 68 #define F_FOURPI (12.56637061f) 69 #define F_INVPI (0.318309886f) 70 #define F_INVPISQ (0.1013211836f) 71 #define F_INVTWOPI (0.15915494309f) 72 #define F_INVFOURPI (0.0795774715f) 73 #define F_PIDIV2 (1.57079632679f) 74 #define F_PIDIV4 (0.785398163397f) 75 #define F_DEGTORAD (0.017453292520f) 76 #define F_RADTODEG (57.2957795131f) 77 #define F_INVLN2 (1.44269504089f) 78 #define F_INVLN4 (0.72134752f) 79 #define F_LOG2E (1.44269504088896f) 80 #define F_SQRT2 (1.41421356237f) 81 #define F_MAXDIST (1.0e10f) 82 #define F_SQRTMIN (1.0842021721e-19f) 83 #define F_MINDIVISOR (1.0e-6f) 93 static const RtFloat3 k_ZeroF3(0.0f);
95 static const RtFloat2 k_ZeroF2(0.0f);
97 static const float k_ZeroF(0.0f);
98 static const float k_OneF(1.0f);
99 static const RtMatrix4x4 k_IdentityMatrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
112 _BitScanForward64( &r, v );
114 #else // Linux, OS X, gcc or clang 115 return __builtin_ctzll( v );
131 template <
typename T>
148 return (x == x) && (x != std::numeric_limits<float>::infinity()) &&
149 (x != -std::numeric_limits<float>::infinity());
151 return std::isfinite(x);
164 return x < y ? x : y;
170 return x < y ? x : y;
176 return x > y ? x : y;
182 return x > y ? x : y;
188 return x < min ? min : (x > max) ? max : x;
194 return x < min ? min : (x > max) ? max : x;
200 return (x - floorf(x));
209 float n = float(
int(x/y));
210 float result = x - n*y;
211 if (result < 0.f) result += y;
258 float etaSq = eta * eta;
259 float rcos_tSq = 1.0f - etaSq * (1.0f - rcos_i * rcos_i);
260 if (rcos_tSq <= 0.0f)
264 float rcos_t = std::sqrt(rcos_tSq);
265 float rpar = (eta * rcos_t - rcos_i) / (eta * rcos_t + rcos_i);
266 float rper = (eta * rcos_i - rcos_t) / (eta * rcos_i + rcos_t);
267 *Kr = 0.5f * (rpar * rpar + rper * rper);
280 float VdN = Dot(Nn, Vn);
296 *Rn = 2.0f * VdN * Nn - Vn;
298 float etaSq = eta * eta;
299 float rcos_tSq = 1.0f - etaSq * (1.0f - rcos_i * rcos_i);
300 if (rcos_tSq <= 0.0f)
308 float rcos_t = std::sqrt(rcos_tSq);
309 float rpar = (eta * rcos_t - rcos_i) / (eta * rcos_t + rcos_i);
310 float rper = (eta * rcos_i - rcos_t) / (eta * rcos_i + rcos_t);
311 *Kr = 0.5f * (rpar * rpar + rper * rper);
313 *Tn = sign * (eta * rcos_i - rcos_t) * Nn - eta * Vn;
336 for (
int i = 0; i < nPts; ++i)
339 Kt[i] = 1.0f - Kr[i];
344 for (
int i = 0; i < nPts; ++i)
347 Kt[i] = 1.0f - Kr[i];
369 float cosSq = VdN * VdN;
370 float cos2eta = 2.f * eta * VdN;
371 float t0 = eta * eta + kappa * kappa;
372 float t1 = t0 * cosSq;
373 float rperp = (t0 - cos2eta + cosSq) / (t0 + cos2eta + cosSq);
374 float rpar = (t1 - cos2eta + 1.f) / (t1 + cos2eta + 1.f);
375 *Kr = 0.5f * (rpar + rperp);
393 float cosSq = VdN * VdN, sinSq = 1.f - cosSq, sin4 = sinSq * sinSq;
395 float t0 = eta * eta - kappa * kappa - sinSq;
396 float aSqPlusbSq = std::sqrt(t0 * t0 + 4.f * kappa * kappa * eta * eta);
397 float a = std::sqrt(0.5f * (aSqPlusbSq + t0));
399 float t1 = aSqPlusbSq + cosSq;
400 float t2 = 2.0f * a * VdN;
402 float rperpSq = (t1 - t2) / (t1 + t2);
404 float t3 = aSqPlusbSq * cosSq + sin4;
405 float t4 = t2 * sinSq;
407 float rparSq = rperpSq * (t3 - t4) / (t3 + t4);
409 *Kr = 0.5f * (rperpSq + rparSq);
432 float VdN = Dot(Nn, Vn);
435 *Rn = 2.0f * VdN * Nn - Vn;
451 if (eta.g == eta.r && kappa.g == kappa.r)
455 if (eta.b == eta.r && kappa.b == kappa.r)
457 else if (eta.b == eta.g && kappa.b == kappa.g)
479 float VdN = Dot(Nn, Vn);
482 *Rn = 2.0f * VdN * Nn - Vn;
496 float f = 1.0f - NdV;
506 float VdN = Dot(Nn, Vn);
507 return 2.0f * VdN * Nn - Vn;
515 return 2.0f * VdN * Nn - Vn;
526 float VdN = Dot(Vn, Nn);
539 float etaSq = eta * eta;
540 float rcos_tSq = 1.0f - etaSq * (1.0f - rcos_i * rcos_i);
541 if (rcos_tSq <= 0.0f)
548 float rcos_t = std::sqrt(rcos_tSq);
549 Tn = sign * (eta * rcos_i - rcos_t) * Nn - eta * Vn;
559 float* VdotNf = NULL)
562 float d = Dot(Vn, Nn);
579 float* VdotNb = NULL)
582 float d = Dot(Vn, Nn);
595 #define ALMOSTZERO 0.005f 615 assert(n.IsUnitLength());
616 assert(t0.IsUnitLength());
617 assert(t1.IsUnitLength());
623 float z = std::sqrt(xi.
y);
624 float r = std::sqrt(std::max(0.0f, 1.0f - xi.
y));
625 float x = r * cosf(e1);
626 float y = r * sinf(e1);
630 outDir = x * t0 + y * t1 + z * n;
633 assert(outDir.IsUnitLength());
647 n.CreateOrthonormalBasis(t0, t1);
667 float r = std::sqrt(std::max(0.0f, 1.0f - z * z));
668 float x = r * cosf(e1);
669 float y = r * sinf(e1);
673 outDir = x * t0 + y * t1 + z * n;
688 n.CreateOrthonormalBasis(t0, t1);
704 float cosAngle = cosf(coneAngle);
705 float z = xi.
y * (1.0f - cosAngle) + cosAngle;
706 float r = std::sqrt(std::max(0.0f, 1.0f - z * z));
707 float x = r * cosf(e1);
708 float y = r * sinf(e1);
712 outDir = x * t0 + y * t1 + z * n;
722 const RtFloat2& xi,
const float coneAngle,
728 n.CreateOrthonormalBasis(t0, t1);
738 outDir.z = 2.0f * xi.
y - 1.0f;
739 float sinTheta = 1.0f - outDir.z * outDir.z;
742 sinTheta = std::sqrt(sinTheta);
744 outDir.x = sinTheta * cosf(phi);
745 outDir.y = sinTheta * sinf(phi);
763 if (xi < thresholds[0])
769 for (
int i = 1; i < numThresholds; i++)
771 if (thresholds[i - 1] <= xi && xi < thresholds[i])
773 xi = (xi - thresholds[i - 1]) / (thresholds[i] - thresholds[i - 1]);
778 float lastThres = thresholds[numThresholds - 1];
779 xi = (xi - lastThres) / (1.0f - lastThres);
780 return numThresholds;
792 return (N.Dot(dir) < 0.0f) ? biasT : biasR;
804 float biasAmt =
RixTraceBias(org, N, dir, biasR, biasT);
810 return org + biasAmt * dir;
817 sincosf(phi, sinPhi, cosPhi);
818 #elif (defined(OSX) && defined(__clang__)) 819 __sincosf(phi, sinPhi, cosPhi);
833 return RtVector3(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta);
839 float sinPhi, cosPhi;
856 result.x = in.x * X.x + in.y * Y.x + in.z * Z.x;
857 result.y = in.x * X.y + in.y * Y.y + in.z * Z.y;
858 result.z = in.x * X.z + in.y * Y.z + in.z * Z.z;
882 return RtVector3(Dot(in, X), Dot(in, Y), Dot(in, Z));
886 template <
typename T>
888 RixMix(
const T& v0,
const T& v1,
float m)
890 return (1.0f - m) * v0 + m * v1;
895 template <
typename T>
907 x3 = x1 + dx * t * t * (3.f - 2.f * t);
915 template <
typename T>
927 x3 = x1 + dx * t * t;
935 template <
typename T>
947 x3 = t * dx * (2.f - t) + x1;
959 return val < min ? 0.0f : 1.0f;
971 : (val >= max ? 1.0f : (val - min) / (max - min));
978 : (val >= min ? 1.0f : (val - max) / (min - max)));
996 val = (val - min) / (max - min);
1004 val = 1.0f - (val - max) / (min - max);
1009 return val * val * (3.0f - 2.0f * val);
1024 val = 1.0f - (val - min) / (max - min);
1032 val = (val - max) / (min - max);
1037 return std::pow(2.0f, -8.0f * val * val);
1060 if (solidangle > 1.840302f)
1064 float omega_div_2pi = solidangle * 0.15915494f;
1067 float cosTheta = 1.0f - omega_div_2pi;
1068 assert(cosTheta > 0.0f);
1071 return std::sqrt(1.0f - cosTheta * cosTheta) / cosTheta;
1083 #define RixAlloca(s) alloca(s) 1099 assert(Nf.IsUnitLength());
1100 assert(Tn.IsUnitLength());
1102 if (Nf.AbsDot(Tn) < 0.995f)
1113 Nf.CreateOrthonormalBasis(TX, TY);
1132 float orthonormalCheck = z.Dot(Cross(x, y));
1133 if (orthonormalCheck < 0.98f)
1157 int numPts = sCtx->
numPts;
1160 for (
int i = 0; i < numPts; i++)
1162 newu[i] = u[i] + du[i];
1177 int numPts = sCtx->
numPts;
1180 for (
int i = 0; i < numPts; i++)
1182 newv[i] = v[i] + dv[i];
1199 int numPts = sCtx->
numPts;
1221 for (
int i = 0; i < numPts; i++)
1224 if(disp[i] == 0.f && dispU[i] == 0.f && dispV[i] == 0.0f)
1235 RtPoint3 P1 = du[i] * dPdu[i] + Norig[i] * dispU[i];
1236 RtPoint3 P2 = dv[i] * dPdv[i] + Norig[i] * dispV[i];
1237 Nn[i] = Cross(P1 - P0, P2 - P0);
1242 RtNormal3 computedNgn = Cross(du[i] * dPdu[i], dv[i] * dPdv[i]);
1243 computedNgn.Normalize();
1245 RtFloat const dotNg = Dot(computedNgn, Ngn[i]);
1262 Nuser_i.Normalize();
1284 computedNgn = -computedNgn;
1287 RtNormal3 const delta = Norig[i] - computedNgn;
1309 static const RtUString k_matteName(
"Ri:Matte");
1310 static const int k_matteLen =
sizeof(float);
1311 static const int k_matteDef = 0;
1313 int matte = k_matteDef;
1323 matteRet = state->GetAttribute(
1324 k_matteName, &matteVal, k_matteLen, &matteType, &matteCount);
1328 else if (matteCount == 1)
1329 matte = (int)matteVal;
1342 static const RtUString k_holdoutName(
"trace:holdout");
1343 static const int k_holdoutLen =
sizeof(float);
1344 static const int k_holdoutDef = 0;
1345 int holdout = k_holdoutDef;
1352 int holdoutRet = state->GetAttribute(
1353 k_holdoutName, &holdoutVal, k_holdoutLen, &holdoutType, &holdoutCount);
1357 holdout = (int)holdoutVal;
1363 RixImod(
const unsigned long a,
const unsigned long b)
1365 unsigned long n = a/b;
1378 RixHash(
const char *bufPtr,
unsigned long range=65535)
1380 unsigned long hash = 5381;
1382 while ((c =
int(*bufPtr++)))
1383 hash = ((hash << 5) + hash) ^ c;
1385 return float(
RixImod(hash,range));
1394 result.r = a.r < b.r ?
RixClamp(result.r, a.r, b.r) :
RixClamp(result.r, b.r, a.r);
1395 result.g = a.g < b.g ?
RixClamp(result.g, a.g, b.g) :
RixClamp(result.g, b.g, a.g);
1396 result.b = a.b < b.b ?
RixClamp(result.b, a.b, b.b) :
RixClamp(result.b, b.b, a.b);
1409 if (Dot(Vn, Ngn) >= 0.f)
1411 float VdotN = Dot(Vn, Nn);
1416 Nn -= amount * 1.01f * VdotN * Vn;
1423 #endif // RixShadingUtils_h PRMAN_INLINE RtVector3 RixChangeBasisFrom(RtVector3 const &in, RtVector3 const &X, RtVector3 const &Y, RtVector3 const &Z)
PRMAN_INLINE T RixMix(const T &v0, const T &v1, float m)
PRMAN_INLINE float RixSchlickFresnelWeight(float NdV)
PRMAN_INLINE float RixGaussStep(float min, float max, float val)
pxrcore::ColorRGB RtColorRGB
PRMAN_INLINE float RixMax(float x, float y)
virtual RixSCDetail GetPrimVar(const RtUString name, RixSCType *type, int *arraylen) const =0
Id for RixRenderState interface.
PRMAN_INLINE void RixFresnelDielectric(float VdN, float eta, float *Kr)
Ray footprint (radius) in V (type float)
PRMAN_INLINE void RixSinCos(float phi, float *sinPhi, float *cosPhi)
PRMAN_INLINE float RixFractional(float x)
Normalized shading normal (type RtFloat3)
T * AllocForPattern(int num)
PRMAN_INLINE void RixFresnelConductorApprox(float VdN, float eta, float kappa, float *Kr)
PRMAN_INLINE unsigned int RixFindFirstSetBit(unsigned long long v)
PRMAN_INLINE float RixRadiansToDegrees(float rads)
PRMANAPI const RtUString k_N
"N"
PRMAN_INLINE int RixChooseAndRemap(float &xi, int numThresholds, float *thresholds)
Id for geometric debugger interface.
PRMAN_INLINE unsigned long RixImod(const unsigned long a, const unsigned long b)
PRMAN_INLINE T RixSmoothMix(const T &x1, const T &x2, float t)
PRMAN_INLINE float RixDegreesToRadians(float degrees)
PRMAN_INLINE void RixAdjustNormal(float const amount, RtVector3 const &Vn, RtVector3 const &Ngn, RtNormal3 &Nn)
Ray footprint (radius) in U (type float)
Surface derivative in U (type RtFloat3)
PRMAN_INLINE float RixClamp(float x, float min, float max)
PRMAN_INLINE void RixCosDirectionalDistribution(const RtFloat2 &xi, const RtVector3 &n, const RtVector3 &t0, const RtVector3 &t1, RtVector3 &outDir, float &cosTheta)
PRMAN_INLINE RtVector3 RixReflect(const RtVector3 &Vn, const RtNormal3 &Nn)
PRMAN_INLINE int RixRefract(const RtVector3 &Vn, const RtNormal3 &Nn, float eta, RtVector3 &Tn)
PRMAN_INLINE float RixLinearStep(float min, float max, float val)
An interface for discovering the current state of the renderer.
Normalized view vector, points away from shading points (type RtFloat3)
PRMAN_INLINE RtVector3 RixSphericalDistribution(const RtFloat2 &xi)
PRMAN_INLINE T RixSignum(T x)
PRMAN_INLINE RtColorRGB RixLerpRGB(RtColorRGB const &a, RtColorRGB const &b, float const mix)
pxrcore::UString RtUString
virtual void EmitPointNormal(RtPoint3 p, RtNormal3 n, RtColorRGB c)=0
Normalized analytical undisplaced N (type RtFloat3)
PRMAN_INLINE float RixMin(float x, float y)
PRMAN_INLINE void RixComputeShadingBasis(RtNormal3 const &Nf, RtVector3 const &Tn, RtVector3 &TX, RtVector3 &TY)
PRMAN_INLINE float RixBoxStep(float min, float val)
Surface V parameterization (type float)
PRMAN_INLINE float RixHash(const char *bufPtr, unsigned long range=65535)
PRMAN_INLINE void RixFresnelConductor(float VdN, float eta, float kappa, float *Kr)
PRMAN_INLINE int RixIsFinite(float x)
PRMAN_INLINE RtVector3 RixChangeBasisTo(RtVector3 const &in, RtVector3 const &X, RtVector3 const &Y, RtVector3 const &Z)
PRMAN_INLINE float RixSolidAngle2Spread(float solidangle)
pxrcore::Matrix4x4 RtMatrix4x4
PRMAN_INLINE int RixIsMatte(RixShadingContext const &sCtx)
PRMAN_INLINE int RixIsHoldout(RixShadingContext const &sCtx)
PRMAN_INLINE void RixBump(RixShadingContext const *sCtx, float const *disp, float const *dispU, float const *dispV, RtNormal3 *Nn)
PRMAN_INLINE void RixDebugBasis(RixShadingContext *sc, RtPoint3 &o, RtVector3 &x, RtVector3 &y, RtVector3 &z)
Surface U parameterization (type float)
PRMAN_INLINE float RixMod(float x, float y)
virtual void SetBuiltinVar(BuiltinVar, float *var)=0
PRMAN_INLINE void RixShiftCtxInU(RixShadingContext *sCtx)
PRMAN_INLINE void RixUniformDirectionalDistribution(const RtFloat2 &xi, const RtVector3 &n, const RtVector3 &t0, const RtVector3 &t1, RtVector3 &outDir, float &cosTheta)
PRMAN_INLINE RtPoint3 RixApplyTraceBias(const RtPoint3 &org, const RtNormal3 &N, const RtVector3 &dir, const float biasR, const float biasT)
PRMAN_INLINE T RixEaseInMix(const T &x1, const T &x2, float t)
PRMAN_INLINE T RixEaseOutMix(const T &x1, const T &x2, float t)
PRMAN_INLINE RtNormal3 RixGetForwardFacingNormal(RtVector3 const &Vn, RtNormal3 const &Nn, float *VdotNf=NULL)
Surface derivative in V (type RtFloat3)
PRMAN_INLINE RtVector3 RixChangeBasis(RtVector3 const &in, RtVector3 const &X, RtVector3 const &Y, RtVector3 const &Z)
PRMAN_INLINE float RixTraceBias(const RtPoint3 &, const RtNormal3 &N, const RtVector3 &dir, float biasR, float biasT)
virtual RixInterface * GetRixInterface(RixInterfaceId id) const =0
PRMAN_INLINE float RixSmoothStep(float min, float max, float val)
PRMAN_INLINE RtNormal3 RixGetBackwardFacingNormal(RtVector3 const &Vn, RtNormal3 const &Nn, float *VdotNb=NULL)
Normalized geometric normal (type RtFloat3)
PRMAN_INLINE RtVector3 RixSphericalDirection(float sinTheta, float cosTheta, float sinPhi, float cosPhi)
PRMAN_INLINE void RixShiftCtxInV(RixShadingContext *sCtx)
virtual void GetBuiltinVar(BuiltinVar, int const **var) const =0
PRMAN_INLINE void RixUniformConeDistribution(const RtFloat2 &xi, const float coneAngle, const RtVector3 &n, const RtVector3 &t0, const RtVector3 &t1, RtVector3 &outDir, float &cosTheta)