Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
SurfaceTracer.h
Go to the documentation of this file.
1#pragma once
2
3#include "World/Scene.h"
4#include "Core/HitProbe.h"
5#include "Core/SurfaceHit.h"
6#include "Core/LTA/lta.h"
12#include "Core/Ray.h"
13#include "Math/TVector3.h"
14#include "Math/Color/Spectrum.h"
20
21#include <Common/assertion.h>
22
23#include <limits>
24
25namespace ph { class SampleFlow; }
26
27namespace ph::lta
28{
29
34class SurfaceTracer final
35{
36public:
37 explicit SurfaceTracer(const Scene* scene);
38
51 const Ray& ray,
52 const SidednessAgreement& sidedness,
53 SurfaceHit* out_X) const;
54
64 const SurfaceHit& X,
65 const Ray& ray,
66 const SidednessAgreement& sidedness,
67 SurfaceHit* out_X) const;
68
73 BsdfSampleQuery& bsdfSample,
74 SampleFlow& sampleFlow,
75 SurfaceHit* out_X) const;
76
80 bool doBsdfSample(BsdfSampleQuery& bsdfSample, SampleFlow& sampleFlow) const;
81
86 bool doBsdfSample(
87 BsdfSampleQuery& bsdfSample,
88 SampleFlow& sampleFlow,
89 Ray* out_sampledRay) const;
90
94 bool doBsdfEvaluation(BsdfEvalQuery& bsdfEval) const;
95
99 bool doBsdfPdfQuery(BsdfPdfQuery& bsdfPdfQuery) const;
100
108 const SurfaceHit& Xe,
109 const SidednessAgreement& sidedness,
110 math::Spectrum* out_Le) const;
111
112private:
113 const Scene& getScene() const;
114
115 const Scene* m_scene;
116};
117
118// In-header Implementations:
119
120inline SurfaceTracer::SurfaceTracer(const Scene* const scene)
121 : m_scene(scene)
122{
123 PH_ASSERT(scene);
124}
125
127 const Ray& ray,
128 const SidednessAgreement& sidedness,
129 SurfaceHit* const out_X) const
130{
131 PH_ASSERT(out_X);
132
133 HitProbe probe;
134 if(!getScene().isIntersecting(ray, &probe))
135 {
136 return false;
137 }
138
140 sidedness.adjustForSidednessAgreement(*out_X);
141
142 return sidedness.isSidednessAgreed(*out_X, ray.getDir());
143}
144
146 const SurfaceHit& X,
147 const Ray& ray,
148 const SidednessAgreement& sidedness,
149 SurfaceHit* const out_X) const
150{
151 // Not tracing from uninitialized surface hit
153
154 const Ray refinedRay = SurfaceHitRefinery{X}.escape(ray.getDir());
155 return traceNextSurface(refinedRay, sidedness, out_X);
156}
157
159 BsdfSampleQuery& bsdfSample,
160 SampleFlow& sampleFlow,
161 SurfaceHit* const out_X) const
162{
163 Ray sampledRay;
164 if(!doBsdfSample(bsdfSample, sampleFlow, &sampledRay))
165 {
166 return false;
167 }
168
170 bsdfSample.inputs.getX(),
171 sampledRay,
172 bsdfSample.context.sidedness,
173 out_X);
174}
175
176inline bool SurfaceTracer::doBsdfSample(BsdfSampleQuery& bsdfSample, SampleFlow& sampleFlow) const
177{
178 const SurfaceHit& X = bsdfSample.inputs.getX();
179 const SurfaceOptics* const optics = X.getSurfaceOptics();
180 if(!optics)
181 {
182 return false;
183 }
184
185 optics->genBsdfSample(bsdfSample, sampleFlow);
186
187 return bsdfSample.outputs.isMeasurable();
188}
189
191 BsdfSampleQuery& bsdfSample,
192 SampleFlow& sampleFlow,
193 Ray* const out_sampledRay) const
194{
195 if(!doBsdfSample(bsdfSample, sampleFlow))
196 {
197 return false;
198 }
199
200 PH_ASSERT(out_sampledRay);
201 *out_sampledRay = Ray(
202 bsdfSample.inputs.getX().getPos(),
203 bsdfSample.outputs.getL(),
204 0,
205 std::numeric_limits<real>::max(),
206 bsdfSample.inputs.getX().getTime());
207
208 return true;
209}
210
212{
213 const SurfaceHit& X = bsdfEval.inputs.getX();
214 const SurfaceOptics* const optics = X.getSurfaceOptics();
215 if(!optics)
216 {
217 return false;
218 }
219
220 optics->calcBsdf(bsdfEval);
221
222 return bsdfEval.outputs.isMeasurable();
223}
224
225inline bool SurfaceTracer::doBsdfPdfQuery(BsdfPdfQuery& bsdfPdfQuery) const
226{
227 const SurfaceHit& X = bsdfPdfQuery.inputs.getX();
228 const SurfaceOptics* const optics = X.getSurfaceOptics();
229 if(!optics)
230 {
231 return false;
232 }
233
234 optics->calcBsdfPdf(bsdfPdfQuery);
235
236 return bsdfPdfQuery.outputs;
237}
238
240 const SurfaceHit& Xe,
241 const SidednessAgreement& sidedness,
242 math::Spectrum* const out_Le) const
243{
244 PH_ASSERT(out_Le);
245
246 const auto* const emitter = Xe.getSurfaceEmitter();
247
248 // Sidedness agreement between real geometry and shading normal
249 // (do not check for hemisphere--emitter may be back-emitting and this is judged by the emitter)
250 if(!emitter ||
251 emitter->getFeatureSet().hasNo(EEmitterFeatureSet::ZeroBounceSample) ||
252 !sidedness.isSidednessAgreed(Xe, Xe.getIncidentRay().getDir()))
253 {
254 return false;
255 }
256
257 emitter->evalEmittedEnergy(Xe, out_Le);
258 return true;
259}
260
261inline const Scene& SurfaceTracer::getScene() const
262{
263 PH_ASSERT(m_scene);
264
265 return *m_scene;
266}
267
268}// end namespace ph::lta
const SurfaceHit & getX() const
Definition BsdfEvalQuery.h:133
bool isMeasurable() const
Tells whether this evaluation has potential to contribute. All evaluated data should be usable if tru...
Definition BsdfEvalQuery.h:175
Information for obtaining a sample value from BSDF.
Definition BsdfEvalQuery.h:90
Input inputs
Definition BsdfEvalQuery.h:96
Output outputs
Definition BsdfEvalQuery.h:97
const SurfaceHit & getX() const
Definition BsdfPdfQuery.h:109
Information for the probability of generating a specific BSDF sample.
Definition BsdfPdfQuery.h:66
Output outputs
Definition BsdfPdfQuery.h:73
Input inputs
Definition BsdfPdfQuery.h:72
lta::SidednessAgreement sidedness
Definition BsdfQueryContext.h:19
const SurfaceHit & getX() const
Definition BsdfSampleQuery.h:179
const math::Vector3R & getL() const
Definition BsdfSampleQuery.h:215
bool isMeasurable() const
Tells whether this sample has potential to contribute. All sampled data should be usable if true is r...
Definition BsdfSampleQuery.h:260
Information for generating a BSDF sample.
Definition BsdfSampleQuery.h:141
Input inputs
Definition BsdfSampleQuery.h:147
BsdfQueryContext context
Definition BsdfSampleQuery.h:146
Output outputs
Definition BsdfSampleQuery.h:148
virtual void evalEmittedEnergy(const SurfaceHit &Xe, math::Spectrum *out_energy) const =0
Evaluate emitted energy from a point on the surface.
Lightweight ray intersection testing and reporting object. If an intersection is found,...
Definition HitProbe.h:27
Represents a ray in space.
Definition Ray.h:21
const math::Vector3R & getDir() const
Definition Ray.h:214
A sample with arbitrary dimensions with fine-grained sampling control.
Definition SampleFlow.h:19
A unified interface for accessing cooked content in a visual world.
Definition Scene.h:27
General information about a ray-surface intersection event.
Definition SurfaceHit.h:59
const Ray & getIncidentRay() const
Convenient method for getRay() where getReason() contains ESurfaceHitReason::IncidentRay.
Definition SurfaceHit.h:175
const Emitter * getSurfaceEmitter() const
Definition SurfaceHit.cpp:61
const SurfaceOptics * getSurfaceOptics() const
Definition SurfaceHit.cpp:67
math::Vector3R getPos() const
Definition SurfaceHit.h:186
const Time & getTime() const
Definition SurfaceHit.h:181
SurfaceHitReason getReason() const
Definition SurfaceHit.h:164
Describes how light interacts with a surface.
Definition SurfaceOptics.h:17
void calcBsdf(BsdfEvalQuery &eval) const
Executes a BSDF evaluation query. Respects sidedness policy.
Definition SurfaceOptics.cpp:17
void genBsdfSample(BsdfSampleQuery &sample, SampleFlow &sampleFlow) const
Executes a BSDF sample query. Respects sidedness policy.
Definition SurfaceOptics.cpp:32
void calcBsdfPdf(BsdfPdfQuery &pdfQuery) const
Executes a BSDF sample PDF query. Respects sidedness policy.
Definition SurfaceOptics.cpp:54
constexpr bool hasExactly(const FlagsSet &flagsSet) const
Checks whether this instance contains exactly the specified flags. No more, no less.
Definition TBitFlags.ipp:99
Definition SidednessAgreement.h:32
void adjustForSidednessAgreement(SurfaceHit &X) const
Definition SidednessAgreement.h:285
bool isSidednessAgreed(const math::Vector3R &Ng, const math::Vector3R &Ns, const math::Vector3R &vec) const
Definition SidednessAgreement.h:104
Algorithms for various hit point adjustments. For surface escaping routines, the generated ray is not...
Definition SurfaceHitRefinery.h:31
Common operations for surface tracing. This class also handles many subtle cases for surface tracing....
Definition SurfaceTracer.h:35
bool doBsdfPdfQuery(BsdfPdfQuery &bsdfPdfQuery) const
Definition SurfaceTracer.h:225
bool doBsdfEvaluation(BsdfEvalQuery &bsdfEval) const
Definition SurfaceTracer.h:211
bool traceNextSurfaceFrom(const SurfaceHit &X, const Ray &ray, const SidednessAgreement &sidedness, SurfaceHit *out_X) const
Find the next surface from a location. This variant also refines the surface hit point before startin...
Definition SurfaceTracer.h:145
bool bsdfSampleNextSurface(BsdfSampleQuery &bsdfSample, SampleFlow &sampleFlow, SurfaceHit *out_X) const
Uses BSDF sample to trace the next surface.
Definition SurfaceTracer.h:158
bool sampleZeroBounceEmission(const SurfaceHit &Xe, const SidednessAgreement &sidedness, math::Spectrum *out_Le) const
Definition SurfaceTracer.h:239
bool doBsdfSample(BsdfSampleQuery &bsdfSample, SampleFlow &sampleFlow) const
Definition SurfaceTracer.h:176
SurfaceTracer(const Scene *scene)
Definition SurfaceTracer.h:120
bool traceNextSurface(const Ray &ray, const SidednessAgreement &sidedness, SurfaceHit *out_X) const
Find the next surface. This variant does not refine the surface hit point. If refining is desired,...
Definition SurfaceTracer.h:126
Definition TTristimulusSpectrum.h:11
Light transport algorithms.
Definition enums.h:6
The root for all renderer implementations.
Definition EEngineProject.h:6
TEnumFlags< ESurfaceHitReason > SurfaceHitReason
Definition SurfaceHit.h:54