Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TDisk.ipp
Go to the documentation of this file.
1#pragma once
2
5
6namespace ph::math
7{
8
9template<typename T>
11{
12 return TDisk(1);
13}
14
15template<typename T>
16inline TDisk<T>::TDisk(const T radius) :
17 m_radius(radius)
18{
19 PH_ASSERT_GT(radius, static_cast<T>(0));
20}
21
22template<typename T>
23inline T TDisk<T>::getArea() const
24{
25 return constant::pi<T> * m_radius * m_radius;
26}
27
28template<typename T>
29inline TVector3<T> TDisk<T>::sampleToSurface(const std::array<T, 2>& sample) const
30{
31 const auto surfacePos2D = sampleToSurface2D(sample);
32 return TVector3<T>(surfacePos2D.y, static_cast<T>(0), surfacePos2D.x);
33}
34
35template<typename T>
36inline TVector3<T> TDisk<T>::sampleToSurface(const std::array<T, 2>& sample, T* const out_pdfA) const
37{
38 const auto surfacePos2D = sampleToSurface2D(sample, out_pdfA);
39 return TVector3<T>(surfacePos2D.y, static_cast<T>(0), surfacePos2D.x);
40}
41
42template<typename T>
43inline TVector2<T> TDisk<T>::sampleToSurface2D(const std::array<T, 2>& sample) const
44{
45 PH_ASSERT_IN_RANGE_INCLUSIVE(sample[0], static_cast<T>(0), static_cast<T>(1));
46 PH_ASSERT_IN_RANGE_INCLUSIVE(sample[1], static_cast<T>(0), static_cast<T>(1));
47 PH_ASSERT_GE(m_radius, static_cast<T>(0));
48
49 const T r = std::sqrt(sample[0]);
50 const T phi = constant::two_pi<real> * sample[1];
51
52 const auto localUnitPos = TVector2<T>(
53 r * std::cos(phi),
54 r * std::sin(phi));
55
56 return localUnitPos.mul(m_radius);
57}
58
59template<typename T>
60inline TVector2<T> TDisk<T>::sampleToSurface2D(const std::array<T, 2>& sample, T* const out_pdfA) const
61{
62 PH_ASSERT(out_pdfA);
63 *out_pdfA = uniformSamplePdfA();
64
65 return sampleToSurface2D(sample);
66}
67
68template<typename T>
70 const std::array<T, 2>& sample,
71 const TVector3<T>& normal,
72 const TVector3<T>& offset) const
73{
74 const auto& diskPos2d = sampleToSurface2D(sample);
75 const auto& basis = TOrthonormalBasis3<T>::makeFromUnitY(normal);
76
77 return (basis.getZAxis() * diskPos2d.x) +
78 (basis.getXAxis() * diskPos2d.y) +
79 offset;
80}
81
82template<typename T>
84 const std::array<T, 2>& sample,
85 T* const out_pdfA,
86 const TVector3<T>& normal,
87 const TVector3<T>& offset) const
88{
89 PH_ASSERT(out_pdfA);
90 *out_pdfA = uniformSamplePdfA();
91
92 return sampleToSurfaceOriented(sample, normal, offset);
93}
94
95template<typename T>
96inline T TDisk<T>::uniformSamplePdfA() const
97{
98 // PDF_A is 1/(pi*r^2)
99 return static_cast<T>(1) / getArea();
100}
101
102}// end namespace ph::math
A 2-D disk with normal facing up (0, 1, 0).
Definition TDisk.h:19
TVector3< T > sampleToSurfaceOriented(const std::array< T, 2 > &sample, const TVector3< T > &normal=TVector3< T >(0, 1, 0), const TVector3< T > &offset=TVector3< T >(0)) const
Definition TDisk.ipp:69
T getArea() const
Definition TDisk.ipp:23
TVector3< T > sampleToSurface(const std::array< T, 2 > &sample) const
Definition TDisk.ipp:29
static TDisk makeUnit()
Definition TDisk.ipp:10
TVector2< T > sampleToSurface2D(const std::array< T, 2 > &sample) const
Definition TDisk.ipp:43
TDisk()=default
static TOrthonormalBasis3 makeFromUnitY(const TVector3< T > &unitYAxis)
Definition TOrthonormalBasis3.ipp:16
Represents a 2-D vector.
Definition TVector2.h:19
Represents a 3-D vector.
Definition TVector3.h:17
constexpr T two_pi
Value of .
Definition constant.h:27
constexpr T pi
Value of .
Definition constant.h:15
Math functions and utilities.
Definition TransformInfo.h:10