37 #ifndef _RIX_PHOTON_GUIDING_H_
38 #define _RIX_PHOTON_GUIDING_H_
44 #include "RiTypesHelper.h"
48 #define SAMPLING_STABILITY_FACTOR 1e-4f
62 const RtBBox& boundingBox,
63 float enlarge = 0.1f);
84 const RtPoint3& origin,
85 const RtNormal3& normal,
90 PRMAN_INLINE
bool canSample(
const RtPoint3& origin)
const;
95 friend class RixPhotonGuiding;
101 const RixPhotonGuiding* photonGuiding);
115 const RtPoint3& projectionPoint,
168 const RtPoint3& origin,
169 const RtNormal3& normal,
174 RtVector3& direction,
182 const RtPoint3& origin,
184 const RtVector3& direction)
const;
204 const RtPoint3& position,
212 const RtPoint3& position,
213 const RtNormal3& normal,
214 const RtVector3& direction,
223 const RtVector3& dirToEnv,
224 const RtPoint3& posInScene,
225 const RtPoint3& center,
238 PRMAN_INLINE
void init(
float enlarge);
241 RtBBox m_boundingBox;
247 RtPoint3 m_corners[8];
256 : m_probability(probability)
258 assert(m_probability >= 0.0f && m_probability <= 1.0f);
259 m_boundingBox.min = RtPoint3(0.0f);
260 m_boundingBox.max = RtPoint3(0.0f);
270 m_boundingBox = boundingBox;
274 PRMAN_INLINE
const RtBBox&
277 return m_boundingBox;
284 return m_probability;
291 return m_hasVolume && m_probability > 0.0f;
300 if (sample < m_probability)
302 sample = sample / m_probability;
307 sample = (sample - m_probability) / (1.0f - m_probability);
319 const RtPoint3& origin,
320 const RtNormal3& normal,
323 return !(m_boundingBox.Contains(origin)) &&
325 !(Dot(normal, m_boundingBox.min - origin) < 0.0f &&
326 Dot(normal, m_boundingBox.max - origin) < 0.0f));
334 return !m_boundingBox.Contains(origin);
344 const RtPoint3& origin,
345 const RtNormal3& normal,
350 RtVector3& direction,
357 direction = posOnPlane - origin;
359 float dist2 = Dot(direction, direction);
360 direction.Normalize();
361 cosTheta = AbsDot(direction, normal);
373 const RtPoint3& origin,
375 const RtVector3& direction)
const
378 float nvInv = 1.0f / Dot(bbp.
m_n, direction);
380 float dno = bbp.
m_d - Dot(bbp.
m_n, origin);
382 RtVector3 hitRay = dno * nvInv * direction + origin - bbp.
m_c;
383 float hitS = Dot(hitRay, bbp.
m_s);
384 float hitT = Dot(hitRay, bbp.
m_t);
389 RtVector3 d = posOnPlane - origin;
421 const RtPoint3& position,
424 RtVector3 hitRay = position - bbp.
m_c;
425 hitRay -= bbp.
m_n * bbp.
m_n.Dot(hitRay);
427 RtVector3 hrn = hitRay;
429 assert(AbsDot(hrn, bbp.
m_n) < 0.001f);
431 float hitS = Dot(hitRay, bbp.
m_s);
432 float hitT = Dot(hitRay, bbp.
m_t);
446 const RtPoint3& position,
447 const RtNormal3& normal,
448 const RtVector3& direction,
456 float otherPdf =
directionPdf(position, bboxProjection, direction);
469 const RtVector3& dirToEnv,
470 const RtPoint3& posInScene,
471 const RtPoint3& center,
475 RtVector3 v = dirToEnv * radius;
476 RtPoint3 centerPoint = v + center;
479 RtVector3 projectionPoint = v * 2.0f + center;
485 float dno = bbp.
m_d - Dot(bbp.
m_n, posInScene);
486 RtVector3 hit = -dno * v + posInScene;
503 const RtVector3 t1 = (n.x * n.x > n.y * n.y) ? RtVector3(0.0f, 1.0f, 0.0f)
504 : RtVector3(1.0f, 0.0f, 0.0f);
513 RixPhotonGuiding::init(
float enlarge)
519 RtVector3 expand = (m_boundingBox.max - m_boundingBox.min) * enlarge;
520 m_boundingBox.min -= expand;
521 m_boundingBox.min += expand;
525 m_corners[0] = m_boundingBox.min;
526 m_corners[1] = m_boundingBox.max,
527 m_corners[2] = RtPoint3(m_boundingBox.min.x, m_boundingBox.min.y, m_boundingBox.max.z);
528 m_corners[3] = RtPoint3(m_boundingBox.min.x, m_boundingBox.max.y, m_boundingBox.min.z);
529 m_corners[4] = RtPoint3(m_boundingBox.max.x, m_boundingBox.min.y, m_boundingBox.min.z);
530 m_corners[5] = RtPoint3(m_boundingBox.min.x, m_boundingBox.max.y, m_boundingBox.max.z);
531 m_corners[6] = RtPoint3(m_boundingBox.max.x, m_boundingBox.min.y, m_boundingBox.max.z);
532 m_corners[7] = RtPoint3(m_boundingBox.max.x, m_boundingBox.max.y, m_boundingBox.min.z);
533 m_center = (m_boundingBox.max + m_boundingBox.min) * 0.5f;
534 m_hasVolume = m_boundingBox.Volume() > 0.0f;
543 : m_photonGuiding(photonGuiding)
556 const RtPoint3& projectionPoint)
558 assert(!m_photonGuiding->m_boundingBox.Contains(projectionPoint));
559 assert(m_photonGuiding != NULL);
561 m_projectionPoint = projectionPoint;
563 m_n = m_photonGuiding->m_center - projectionPoint;
565 RtPoint3 cpp = m_n * 0.5f;
566 m_c = cpp + projectionPoint;
574 float dno = m_d - Dot(m_n, projectionPoint);
576 m_stCoords[0] = m_stCoords[1] = FLT_MAX;
577 m_stCoords[2] = m_stCoords[3] = -FLT_MAX;
579 for (
int i = 0; i < 8; ++i)
581 RtVector3 v = m_photonGuiding->m_corners[i] - projectionPoint;
583 float nvInv = 1.0f / Dot(m_n, v);
585 RtVector3 hitRay = dno * nvInv * v - cpp;
586 float hitS = Dot(hitRay, m_s);
587 float hitT = Dot(hitRay, m_t);
588 m_stCoords[0] = std::min(m_stCoords[0], hitS);
589 m_stCoords[1] = std::min(m_stCoords[1], hitT);
590 m_stCoords[2] = std::max(m_stCoords[2], hitS);
591 m_stCoords[3] = std::max(m_stCoords[3], hitT);
594 m_sizeS = m_stCoords[2] - m_stCoords[0];
595 m_sizeT = m_stCoords[3] - m_stCoords[1];
604 const RtPoint3& projectionPoint,
610 assert(m_photonGuiding != NULL);
611 assert(!m_photonGuiding->m_boundingBox.Contains(projectionPoint));
613 m_projectionPoint = projectionPoint;
624 m_stCoords[0] = m_stCoords[1] = FLT_MAX;
625 m_stCoords[2] = m_stCoords[3] = -FLT_MAX;
627 for (
int i = 0; i < 8; ++i)
629 RtPoint3 cornerpt = m_photonGuiding->m_corners[i];
630 float dist = Dot(m_n, (cornerpt - c));
631 RtVector3 hitRay = cornerpt - dist * m_n - c;
632 float hitS = Dot(hitRay, m_s);
633 float hitT = Dot(hitRay, m_t);
634 m_stCoords[0] = std::min(m_stCoords[0], hitS);
635 m_stCoords[1] = std::min(m_stCoords[1], hitT);
636 m_stCoords[2] = std::max(m_stCoords[2], hitS);
637 m_stCoords[3] = std::max(m_stCoords[3], hitT);
640 m_sizeS = m_stCoords[2] - m_stCoords[0];
641 m_sizeT = m_stCoords[3] - m_stCoords[1];
649 return m_sizeS * m_sizeT;
654 PRMAN_INLINE RtPoint3
659 return m_c + (m_sizeS * sx + m_stCoords[0]) * m_s +
660 (m_sizeT * sy + m_stCoords[1]) * m_t;
665 PRMAN_INLINE RtPoint3
670 return m_c + cs * m_s + ct * m_t;
681 return (cs >= m_stCoords[0] && cs <= m_stCoords[2] &&
682 ct >= m_stCoords[1] && ct <= m_stCoords[3]);
692 float mid = 0.5f * (m_stCoords[2] + m_stCoords[0]);
694 m_stCoords[2] = mid + min * 0.5f;
695 m_stCoords[0] = mid - min * 0.5f;
699 float mid = 0.5f * (m_stCoords[3] + m_stCoords[1]);
701 m_stCoords[3] = mid + min * 0.5f;
702 m_stCoords[1] = mid - min * 0.5f;
706 #endif // _RIX_PHOTON_GUIDING_H_