36 #include <cugar/linalg/vector.h> 37 #include <cugar/linalg/matrix.h> 38 #include <cugar/basic/numbers.h> 39 #include <cugar/bsdf/differential_geometry.h> 43 #define ONE_OVER_PIf 0.31830988618f 46 #ifndef ONE_OVER_TWO_PIf 47 #define ONE_OVER_TWO_PIf 0.15915494309f 51 #define HALF_PIf 1.57079632679f 54 #ifndef ONE_OVER_HALF_PIf 55 #define ONE_OVER_HALF_PIf 0.63661977236f 58 #define LTC_USE_INVDET 64 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
82 static void preprocess(
const uint32 size,
const Matrix3x3f* tabM, float4* tab, float4* tab_inv)
84 for (uint32 j = 0; j < size; ++j)
85 for (uint32 i = 0; i < size; ++i)
87 Matrix3x3f M = transpose(tabM[i + j*size]);
94 tab[i + j*size] = make_float4(a, b, c, d);
102 tab_inv[i + j*size] = make_float4(
112 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
113 LTC(
const float cosTheta,
const float4* tabM,
const float4* tabMinv,
const float* tabA,
const uint32 size)
115 const float theta = acos(fabsf(cosTheta));
117 const float theta_unit = theta * ONE_OVER_HALF_PIf * size;
118 const float theta_floor = floorf(theta_unit);
119 const float theta_c1 = theta_unit - theta_floor;
120 const float theta_c0 = 1.0f - theta_c1;
122 const int t1 = max(0, min((
int)size - 1, (
int)theta_floor));
123 const int t2 = min((
int)size - 1, t1 + 1);
125 amplitude = tabA[t1*size] * theta_c0 +
126 tabA[t2*size] * theta_c1;
128 m =
Vector4f(tabM[t1*size]) * theta_c0 +
136 m_inv =
Vector4f(tabMinv[t1*size]) * theta_c0 +
137 Vector4f(tabMinv[t2*size]) * theta_c1;
161 #if defined(LTC_USE_INVDET) 163 detMinv = fabsf(m_inv.x * m_inv.z - m_inv.w * m_inv.z*m_inv.y);
166 detM = fabsf(m.x * m.z - m.w * m.z*m.y);
170 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
175 m.x * L.x + m.w * L.z,
180 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
187 m_inv.y * L.x + m_inv.x * L.z);
190 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
193 #if defined(LTC_USE_INVDET) 194 Vector3f Loriginal = inv_transform(L);
195 const float l =
length(Loriginal);
197 const float InvJacobian = detMinv / (l*l*l);
199 const float D = ONE_OVER_PIf * max(0.0
f, Loriginal.z / l);
200 return D * InvJacobian;
202 const Vector3f Loriginal = normalize(inv_transform(L));
203 const Vector3f L_ = transform(Loriginal);
205 const float l =
length(L_);
206 const float InvJacobian = (l*l*l) / detM;
209 const float D = ONE_OVER_PIf * max(0.0
f, Loriginal.z);
211 return D * InvJacobian;
219 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
222 return acosf(dot(p0,p1)) * dot( normalize(cross(p0,p1)),
Vector3f(0,0,1) );
227 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
239 return fabsf(r) * ONE_OVER_TWO_PIf;
244 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
262 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
265 if (phi.y - phi.x == 2.0f*M_PIf)
268 const float phi_1 = phi.x*0.75f + phi.y*0.25f;
269 const float phi_2 = (phi.x + phi.y)*0.5
f;
270 const float phi_3 = phi.x*0.5f + phi.y*0.75f;
278 else if (phi.y - phi.x >= M_PIf)
281 const float phi_2 = (phi.x + phi.y)*0.5
f;
296 #if defined(LTC_USE_INVDET) 304 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
305 LTCBsdf(
const float _roughness,
const float4* _tabM,
const float4* _tabMinv,
const float* _tabA,
const uint32 _size) :
306 roughness(_roughness),
312 const int a = max(0, min((
int)size - 1, (
int)floorf(sqrtf(roughness) * size)));
321 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
324 const Vector3f N = geometry.normal_s;
326 const float NoV = dot(N, V);
327 const float NoL = dot(N, L);
329 if (NoV * NoL <= 0.0
f)
335 const Vector3f B = normalize(cross(N, V));
342 LTC ltc(fabsf(NoV), tabM, tabMinv, tabA, size);
344 return ltc.amplitude * ltc.p(local_L) / fabsf(NoL);
349 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
352 const Vector3f N = geometry.normal_s;
354 const float NoV = dot(N, V);
355 const float NoL = dot(N, L);
357 if (NoV * NoL <= 0.0
f)
361 const Vector3f B = normalize(cross(N, V));
368 LTC ltc(fabsf(NoV), tabM, tabMinv, tabA, size);
370 const float p = ltc.p(local_L);
372 return p > 0.0f ? ltc.amplitude : 0.0f;
377 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
380 const Vector3f N = geometry.normal_s;
382 const float NoV = dot(N, V);
383 const float NoL = dot(N, L);
386 const Vector3f B = normalize(cross(N, V));
393 LTC ltc(fabsf(NoV), tabM, tabMinv, tabA, size);
396 f = (NoV * NoL <= 0.0f) ?
398 ltc.amplitude * p / fabsf(NoL);
400 if (measure == kProjectedSolidAngle)
406 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
409 const Vector3f N = geometry.normal_s;
411 const float NoV = dot(N, V);
412 const float NoL = dot(N, L);
415 const Vector3f B = normalize(cross(N, V));
422 LTC ltc(fabsf(NoV), tabM, tabMinv, tabA, size);
424 float p = ltc.p(local_L);
426 return (measure == kProjectedSolidAngle) ? p / fabsf(NoL) : p;
431 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
441 const Vector3f N = geometry.normal_s;
443 const float NoV = dot(N, V);
445 LTC ltc(fabsf(NoV), tabM, tabMinv, tabA, size);
456 local_L.z = -local_L.z;
459 const Vector3f B = normalize(cross(N, V));
465 const float NoL = dot(N, L);
469 local_L.z = -local_L.z;
472 p_proj = p / fabsf(local_L.z);
474 g = (NoV * NoL <= 0.0f || p == 0.0f) ?
481 template <
typename RandomGeneratorT>
482 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
497 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
510 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
515 const Vector3f N = geometry.normal_s;
517 const float NoV = dot(N, V);
519 return LTC(fabsf(NoV), tabM, tabMinv, tabA, size);
524 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
529 const float2 phi)
const 540 const Vector3f N = geometry.normal_s;
541 const Vector3f B = normalize(cross(N, V));
545 M[0][0] = dot(T, geometry.tangent);
546 M[0][1] = dot(T, geometry.binormal);
548 M[1][0] = dot(B, geometry.tangent);
549 M[1][1] = dot(B, geometry.binormal);
561 const float4* tabMinv;
569 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
574 if (L[0].z > 0.0) config += 1;
575 if (L[1].z > 0.0) config += 2;
576 if (L[2].z > 0.0) config += 4;
577 if (L[3].z > 0.0) config += 8;
586 else if (config == 1)
589 L[1] = -L[1].z * L[0] + L[0].z * L[1];
590 L[2] = -L[3].z * L[0] + L[0].z * L[3];
592 else if (config == 2)
595 L[0] = -L[0].z * L[1] + L[1].z * L[0];
596 L[2] = -L[2].z * L[1] + L[1].z * L[2];
598 else if (config == 3)
601 L[2] = -L[2].z * L[1] + L[1].z * L[2];
602 L[3] = -L[3].z * L[0] + L[0].z * L[3];
604 else if (config == 4)
607 L[0] = -L[3].z * L[2] + L[2].z * L[3];
608 L[1] = -L[1].z * L[2] + L[2].z * L[1];
610 else if (config == 5)
614 else if (config == 6)
617 L[0] = -L[0].z * L[1] + L[1].z * L[0];
618 L[3] = -L[3].z * L[2] + L[2].z * L[3];
620 else if (config == 7)
623 L[4] = -L[3].z * L[0] + L[0].z * L[3];
624 L[3] = -L[3].z * L[2] + L[2].z * L[3];
626 else if (config == 8)
629 L[0] = -L[0].z * L[3] + L[3].z * L[0];
630 L[1] = -L[2].z * L[3] + L[3].z * L[2];
633 else if (config == 9)
636 L[1] = -L[1].z * L[0] + L[0].z * L[1];
637 L[2] = -L[2].z * L[3] + L[3].z * L[2];
639 else if (config == 10)
643 else if (config == 11)
647 L[3] = -L[2].z * L[3] + L[3].z * L[2];
648 L[2] = -L[2].z * L[1] + L[1].z * L[2];
650 else if (config == 12)
653 L[1] = -L[1].z * L[2] + L[2].z * L[1];
654 L[0] = -L[0].z * L[3] + L[3].z * L[0];
656 else if (config == 13)
661 L[2] = -L[1].z * L[2] + L[2].z * L[1];
662 L[1] = -L[1].z * L[0] + L[0].z * L[1];
664 else if (config == 14)
667 L[4] = -L[0].z * L[3] + L[3].z * L[0];
668 L[0] = -L[0].z * L[1] + L[1].z * L[0];
670 else if (config == 15)
675 if (n == 3) L[3] = L[0];
676 if (n == 4) L[4] = L[0];
SphericalMeasure
Definition: differential_geometry.h:50
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float hemispherical_sector_integral(const Matrix3x3f &T, const float2 theta, const float2 phi) const
Definition: ltc.h:263
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void f_and_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, Vector3f &f, float &p, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: ltc.h:378
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float small_hemispherical_sector_integral(const Matrix3x3f &T, const float2 theta, const float2 phi) const
Definition: ltc.h:245
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float hemispherical_sector_integral(const DifferentialGeometry &geometry, const Vector3f V, const float2 theta, const float2 phi) const
Definition: ltc.h:525
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: ltc.h:322
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE bool invert(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, RandomGeneratorT &random, Vector3f &z, float &p, float &p_proj) const
Definition: ltc.h:483
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 clip_quad_to_horizon(cugar::Vector3f L[5])
Definition: ltc.h:570
Defines various spherical mappings.
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float clipped_polygon_integral(const uint32 n, const cugar::Vector3f p[5]) const
Definition: ltc.h:228
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void inverse_pdf(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const Vector3f u, float &p, float &p_proj) const
Definition: ltc.h:498
Definition: differential_geometry.h:59
float random()
Definition: tiled_sampling.h:44
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_HOST CUGAR_DEVICE Vector3f from_spherical_coords(const Vector2f &uv)
Definition: mappings_inline.h:33
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float clipped_edge_integral(const cugar::Vector3f p0, const cugar::Vector3f p1) const
Definition: ltc.h:220
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE LTC get_ltc(const DifferentialGeometry &geometry, const Vector3f V) const
Definition: ltc.h:511
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void sample(const Vector3f u, const DifferentialGeometry &geometry, const Vector3f V, Vector3f &L, Vector3f &g, float &p, float &p_proj) const
Definition: ltc.h:432
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f_over_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: ltc.h:350
CUGAR_HOST CUGAR_DEVICE Vector3f square_to_cosine_hemisphere(const Vector2f &uv)
Definition: mappings_inline.h:119
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 length(const vector_view< Iterator > &vec)
Definition: vector_view.h:228
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: ltc.h:407