1 //******************************************************************************
2 ///
3 /// @file core/render/trace.h
4 ///
5 /// Declarations related to the @ref pov::Trace class.
6 ///
7 /// @copyright
8 /// @parblock
9 ///
10 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8.
11 /// Copyright 1991-2018 Persistence of Vision Raytracer Pty. Ltd.
12 ///
13 /// POV-Ray is free software: you can redistribute it and/or modify
14 /// it under the terms of the GNU Affero General Public License as
15 /// published by the Free Software Foundation, either version 3 of the
16 /// License, or (at your option) any later version.
17 ///
18 /// POV-Ray is distributed in the hope that it will be useful,
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 /// GNU Affero General Public License for more details.
22 ///
23 /// You should have received a copy of the GNU Affero General Public License
24 /// along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 ///
26 /// ----------------------------------------------------------------------------
27 ///
28 /// POV-Ray is based on the popular DKB raytracer version 2.12.
29 /// DKBTrace was originally written by David K. Buck.
30 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
31 ///
32 /// @endparblock
33 ///
34 //******************************************************************************
35 
36 #ifndef POVRAY_CORE_TRACE_H
37 #define POVRAY_CORE_TRACE_H
38 
39 // Module config header file must be the first file included within POV-Ray unit header files
40 #include "core/configcore.h"
41 
42 #include <vector>
43 
44 #include "core/bounding/bsptree.h"
45 #include "core/math/randomsequence.h"
46 #include "core/render/ray.h"
47 
48 namespace pov
49 {
50 
51 //##############################################################################
52 ///
53 /// @defgroup PovCoreRender Ray Tracing
54 /// @ingroup PovCore
55 ///
56 /// @{
57 
58 typedef struct Fog_Struct FOG;
59 class PhotonGatherer;
60 class SceneData;
61 class Task;
62 class ViewData;
63 
64 struct NoSomethingFlagRayObjectCondition : public RayObjectCondition
65 {
66     virtual bool operator()(const Ray& ray, ConstObjectPtr object, double) const;
67 };
68 
69 struct LitInterval
70 {
71     bool lit;
72     double s0, s1, ds;
73     size_t l0, l1;
74 
LitIntervalLitInterval75     LitInterval() :
76         lit(false), s0(0.0), s1(0.0), ds(0.0), l0(0), l1(0) { }
LitIntervalLitInterval77     LitInterval(bool nlit, double ns0, double ns1, size_t nl0, size_t nl1) :
78         lit(nlit), s0(ns0), s1(ns1), ds(ns1 - ns0), l0(nl0), l1(nl1) { }
79 };
80 
81 struct MediaInterval
82 {
83     bool lit;
84     int samples;
85     double s0, s1, ds;
86     size_t l0, l1;
87     MathColour od;
88     MathColour te;
89     MathColour te2;
90 
MediaIntervalMediaInterval91     MediaInterval() :
92         lit(false), samples(0), s0(0.0), s1(0.0), ds(0.0), l0(0), l1(0) { }
MediaIntervalMediaInterval93     MediaInterval(bool nlit, int nsamples, double ns0, double ns1, double nds, size_t nl0, size_t nl1) :
94         lit(nlit), samples(nsamples), s0(ns0), s1(ns1), ds(nds), l0(nl0), l1(nl1) { }
MediaIntervalMediaInterval95     MediaInterval(bool nlit, int nsamples, double ns0, double ns1, double nds, size_t nl0, size_t nl1, const MathColour& nod, const MathColour& nte, const MathColour& nte2) :
96         lit(nlit), samples(nsamples), s0(ns0), s1(ns1), ds(nds), l0(nl0), l1(nl1), od(nod), te(nte), te2(nte2) { }
97 
98     bool operator<(const MediaInterval& other) const { return (s0 < other.s0); }
99 };
100 
101 struct LightSourceIntersectionEntry
102 {
103     double s;
104     size_t l;
105     bool lit;
106 
LightSourceIntersectionEntryLightSourceIntersectionEntry107     LightSourceIntersectionEntry() :
108         s(0.0), l(0), lit(false) { }
LightSourceIntersectionEntryLightSourceIntersectionEntry109     LightSourceIntersectionEntry(double ns, size_t nl, bool nlit) :
110         s(ns), l(nl), lit(nlit) { }
111 
112     bool operator<(const LightSourceIntersectionEntry& other) const { return (s < other.s); }
113 };
114 
115 struct LightSourceEntry
116 {
117     double s0, s1;
118     LightSource *light;
119 
LightSourceEntryLightSourceEntry120     LightSourceEntry() :
121         s0(0.0), s1(0.0), light(nullptr) { }
LightSourceEntryLightSourceEntry122     LightSourceEntry(LightSource *nlight) :
123         s0(0.0), s1(0.0), light(nlight) { }
LightSourceEntryLightSourceEntry124     LightSourceEntry(double ns0, double ns1, LightSource *nlight) :
125         s0(ns0), s1(ns1), light(nlight) { }
126 
127     bool operator<(const LightSourceEntry& other) const { return (s0 < other.s0); }
128 };
129 
130 // TODO: these sizes will need tweaking.
131 typedef PooledSimpleVector<Media *, MEDIA_VECTOR_SIZE> MediaVector;
132 typedef PooledSimpleVector<MediaInterval, MEDIA_INTERVAL_VECTOR_SIZE> MediaIntervalVector;
133 typedef PooledSimpleVector<LitInterval, LIT_INTERVAL_VECTOR_SIZE> LitIntervalVector;
134 typedef PooledSimpleVector<LightSourceIntersectionEntry, LIGHT_INTERSECTION_VECTOR_SIZE> LightSourceIntersectionVector;
135 typedef PooledSimpleVector<LightSourceEntry, LIGHTSOURCE_VECTOR_SIZE> LightSourceEntryVector;
136 
137 
138 struct TraceTicket
139 {
140     /// trace recursion level
141     unsigned int traceLevel;
142 
143     /// maximum trace recursion level allowed
144     unsigned int maxAllowedTraceLevel;
145 
146     /// maximum trace recursion level found
147     unsigned int maxFoundTraceLevel;
148 
149     /// adc bailout
150     double adcBailout;
151 
152     /// whether background should be rendered all transparent
153     bool alphaBackground;
154 
155     /// something the radiosity algorithm needs
156     unsigned int radiosityRecursionDepth;
157 
158     /// something the radiosity algorithm needs
159     float radiosityImportanceQueried;
160     /// something the radiosity algorithm needs
161     float radiosityImportanceFound;
162     /// set by radiosity code according to the sample quality encountered (1.0 is ideal, 0.0 really sucks)
163     float radiosityQuality;
164 
165     /// something the subsurface scattering algorithm needs
166     unsigned int subsurfaceRecursionDepth;
167 
168     TraceTicket(unsigned int mtl, double adcb, bool ab = true, unsigned int rrd = 0, unsigned int ssrd = 0,
169                 float riq = -1.0, float rq = 1.0):
170         traceLevel(0), maxAllowedTraceLevel(mtl), maxFoundTraceLevel(0), adcBailout(adcb), alphaBackground(ab),
171         radiosityRecursionDepth(rrd), subsurfaceRecursionDepth(ssrd), radiosityImportanceQueried(riq),
172         radiosityImportanceFound(-1.0), radiosityQuality(rq)
173     {}
174 };
175 
176 
177 /// Ray tracing and shading engine.
178 ///
179 /// This class provides the fundamental functionality to trace rays and determine the effective colour of an object.
180 ///
181 class Trace
182 {
183     public:
184 
185         /// @todo This interface might also come in hand at other places,
186         /// so we should pull it out of the @ref Trace class.
187         class CooperateFunctor
188         {
189             public:
operator()190                 virtual void operator()() { }
191         };
192 
193         class MediaFunctor
194         {
195             public:
ComputeMedia(vector<Media> &,const Ray &,Intersection &,MathColour &,ColourChannel &)196                 virtual void ComputeMedia(vector<Media>&, const Ray&, Intersection&, MathColour&, ColourChannel&) { }
ComputeMedia(const RayInteriorVector &,const Ray &,Intersection &,MathColour &,ColourChannel &)197                 virtual void ComputeMedia(const RayInteriorVector&, const Ray&, Intersection&, MathColour&, ColourChannel&) { }
ComputeMedia(MediaVector &,const Ray &,Intersection &,MathColour &,ColourChannel &)198                 virtual void ComputeMedia(MediaVector&, const Ray&, Intersection&, MathColour&, ColourChannel&) { }
199         };
200 
201         class RadiosityFunctor
202         {
203             public:
ComputeAmbient(const Vector3d & ipoint,const Vector3d & raw_normal,const Vector3d & layer_normal,double brilliance,MathColour & ambient_colour,double weight,TraceTicket & ticket)204                 virtual void ComputeAmbient(const Vector3d& ipoint, const Vector3d& raw_normal, const Vector3d& layer_normal, double brilliance, MathColour& ambient_colour, double weight, TraceTicket& ticket) { }
CheckRadiosityTraceLevel(const TraceTicket & ticket)205                 virtual bool CheckRadiosityTraceLevel(const TraceTicket& ticket) { return false; }
206         };
207 
208         /// @todo TraceThreadData already holds a reference to SceneData.
209         Trace(shared_ptr<SceneData> sd, TraceThreadData *td, const QualityFlags& qf,
210               CooperateFunctor& cf, MediaFunctor& mf, RadiosityFunctor& af);
211 
212         virtual ~Trace();
213 
214         /// Trace a ray.
215         ///
216         /// Call this if transmittance matters.
217         ///
218         /// @param[in,out]  ray             Ray and associated information.
219         /// @param[out]     colour          Computed colour.
220         /// @param[out]     transm          Computed transmittance.
221         /// @param[in]      weight          Importance of this computation.
222         /// @param[in]      continuedRay    Set to true when tracing a ray after it went through some surface
223         ///                                 without a change in direction; this governs trace level handling.
224         /// @param[in]      maxDepth        Objects at or beyond this distance won't be hit by the ray (ignored if
225         ///                                 < EPSILON).
226         /// @return                         The distance to the nearest object hit.
227         ///
228         virtual double TraceRay(Ray& ray, MathColour& colour, ColourChannel& transm, COLC weight, bool continuedRay, DBL maxDepth = 0.0);
229 /*
230         /// Trace a ray.
231         ///
232         /// Call this if transmittance will be ignored anyway.
233         ///
234         /// @param[in,out]  ray             Ray and associated information.
235         /// @param[out]     colour          Computed colour.
236         /// @param[in]      weight          Importance of this computation.
237         /// @param[in]      continuedRay    Set to true when tracing a ray after it went through some surface
238         ///                                 without a change in direction; this governs trace level handling.
239         /// @param[in]      maxDepth        Objects at or beyond this distance won't be hit by the ray (ignored if
240         ///                                 < EPSILON).
241         /// @return                         The distance to the nearest object hit.
242         ///
243         virtual double TraceRay(Ray& ray, MathColour& colour, COLC weight, bool continuedRay, DBL maxDepth = 0.0);
244 */
245         bool FindIntersection(Intersection& isect, const Ray& ray);
246         bool FindIntersection(Intersection& isect, const Ray& ray, const RayObjectCondition& precondition, const RayObjectCondition& postcondition);
247         bool FindIntersection(ObjectPtr object, Intersection& isect, const Ray& ray, double closest = HUGE_VAL);
248         bool FindIntersection(ObjectPtr object, Intersection& isect, const Ray& ray, const RayObjectCondition& postcondition, double closest = HUGE_VAL);
249 
250         unsigned int GetHighestTraceLevel();
251 
252         bool TestShadow(const LightSource &light, double& depth, Ray& light_source_ray, const Vector3d& p, MathColour& colour); // TODO FIXME - this should not be exposed here
253 
254     protected: // TODO FIXME - should be private
255 
256         /// Structure used to cache reflection information for multi-layered textures.
257         struct WNRX
258         {
259             double weight;
260             Vector3d normal;
261             MathColour reflec;
262             SNGL reflex;
263 
WNRXWNRX264             WNRX(DBL w, const Vector3d& n, const MathColour& r, SNGL x) :
265                 weight(w), normal(n), reflec(r), reflex(x) { }
266         };
267 
268         typedef vector<const TEXTURE *> TextureVectorData;
269         typedef RefPool<TextureVectorData> TextureVectorPool;
270         typedef Ref<TextureVectorData, RefClearContainer<TextureVectorData> > TextureVector;
271 
272         typedef vector<WNRX> WNRXVectorData;
273         typedef RefPool<WNRXVectorData> WNRXVectorPool;
274         typedef Ref<WNRXVectorData, RefClearContainer<WNRXVectorData> > WNRXVector;
275 
276         /// Structure used to cache shadow test results for complex textures.
277         struct LightColorCache
278         {
279             bool        tested;
280             MathColour  colour;
281         };
282 
283         typedef vector<LightColorCache> LightColorCacheList;
284         typedef vector<LightColorCacheList> LightColorCacheListList;
285 
286         /// List (well really vector) of lists of LightColorCaches.
287         /// Each list is expected to have as many elements as there are global light sources.
288         /// The number of lists should be at least that of max trace level.
289         LightColorCacheListList lightColorCache;
290 
291         /// Current index into lightColorCaches.
292         int lightColorCacheIndex;
293 
294         /// Scene data.
295         shared_ptr<SceneData> sceneData;
296 
297         /// Maximum trace recursion level found.
298         unsigned int maxFoundTraceLevel;
299         /// Various quality-related flags.
300         QualityFlags qualityFlags;
301 
302         /// Bounding slabs priority queue.
303         BBoxPriorityQueue priorityQueue;
304         /// BSP tree mailbox.
305         BSPTree::Mailbox mailbox;
306         /// Area light grid buffer.
307         vector<MathColour> lightGrid;
308         /// Fast stack pool.
309         IStackPool stackPool;
310         /// Fast texture list pool.
311         TextureVectorPool texturePool;
312         /// Fast WNRX list pool.
313         WNRXVectorPool wnrxPool;
314         /// Light source shadow cache for shadow tests of first trace level intersections.
315         vector<ObjectPtr> lightSourceLevel1ShadowCache;
316         /// Light source shadow cache for shadow tests of higher trace level intersections.
317         vector<ObjectPtr> lightSourceOtherShadowCache;
318         /// `crand` random number generator.
319         unsigned int crandRandomNumberGenerator;
320         /// Pseudo-random number sequence.
321         RandomDoubleSequence randomNumbers;
322         /// Pseudo-random number generator based on random number sequence.
323         RandomDoubleSequence::Generator randomNumberGenerator;
324         /// Sub-random uniform 3d points on sphere sequence.
325         vector<SequentialVectorGeneratorPtr> ssltUniformDirectionGenerator;
326         /// Sub-random uniform numbers sequence.
327         vector<SequentialDoubleGeneratorPtr> ssltUniformNumberGenerator;
328         /// Sub-random cos-weighted 3d points on hemisphere sequence.
329         vector<SequentialVectorGeneratorPtr> ssltCosWeightedDirectionGenerator;
330         /// Thread data.
331         TraceThreadData *threadData;
332 
333         CooperateFunctor& cooperate;
334         MediaFunctor& media;
335         RadiosityFunctor& radiosity;
336 
337     ///
338     //*****************************************************************************
339     ///
340     /// @name Texture Computations
341     ///
342     /// The following methods compute the effective colour of a given, possibly complex, texture.
343     ///
344     /// @{
345     ///
346 
347         /// Compute the effective contribution of an intersection point as seen from the ray's origin, or deposits
348         /// photons.
349         ///
350         /// Computations include any media effects between the ray's origin and the point of intersection.
351         ///
352         /// @remark         The computed contribution is _added_ to the value passed in `colour` (does not apply to
353         ///                 photon pass).
354         ///
355         /// @todo           Some input parameters are non-const references.
356         ///
357         /// @param[in]      isect           Intersection information.
358         /// @param[in,out]  resultColour    Computed colour [in,out]; during photon pass: light colour [in].
359         /// @param[in,out]  resultTransm    Computed transparency; not used during photon pass.
360         /// @param[in,out]  ray             Ray and associated information.
361         /// @param[in]      weight          Importance of this computation.
362         /// @param[in]      photonpass      Whether to deposit photons instead of computing a colour
363         ///
364         void ComputeTextureColour(Intersection& isect, MathColour& resultColour, ColourChannel& resultTransm, Ray& ray, COLC weight, bool photonpass);
365 
366         /// Compute the effective colour of an arbitrarily complex texture, or deposits photons.
367         ///
368         /// @remark         The computed contribution _overwrites_ any value passed in `colour` (does not apply to
369         ///                 photon pass).
370         ///
371         /// @remark         Computations do _not_ include media effects between the ray's origin and the point of
372         ///                 intersection any longer.
373         ///
374         /// @todo           Some input parameters are non-const references or pointers.
375         ///
376         /// @param[in,out]  resultColour    Computed colour [out]; during photon pass: light colour [in].
377         /// @param[out]     resultTransm    Computed transparency; not used during photon pass.
378         /// @param[in]      texture         Texture.
379         /// @param[in]      warps           Stack of warps to be applied.
380         /// @param[in]      ipoint          Intersection point (possibly with earlier warps already applied).
381         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
382         /// @param[in,out]  ray             Ray and associated information.
383         /// @param[in]      weight          Importance of this computation.
384         /// @param[in]      isect           Intersection information.
385         /// @param[in]      shadowflag      Whether to perform only computations necessary for shadow testing.
386         /// @param[in]      photonpass      Whether to deposit photons instead of computing a colour.
387         ///
388         void ComputeOneTextureColour(MathColour& resultColour, ColourChannel& resultTransm, const TEXTURE *texture, vector<const TEXTURE *>& warps,
389                                      const Vector3d& ipoint, const Vector3d& rawnormal, Ray& ray, COLC weight,
390                                      Intersection& isect, bool shadowflag, bool photonpass);
391 
392         /// Compute the effective colour of an averaged texture, or deposits photons.
393         ///
394         /// @remark         The computed contribution _overwrites_ any value passed in `colour` (does not apply to
395         ///                 photon pass).
396         ///
397         /// @remark         Computations do _not_ include media effects between the ray's origin and the point of
398         ///                 intersection any longer.
399         ///
400         /// @todo           Some input parameters are non-const references or pointers.
401         ///
402         /// @param[in,out]  resultColour    Computed colour [out]; during photon pass: light colour [in].
403         /// @param[out]     resultTransm    Computed transparency; not used during photon pass.
404         /// @param[in]      texture         Texture.
405         /// @param[in]      warps           Stack of warps to be applied.
406         /// @param[in]      ipoint          Intersection point (possibly with earlier warps already applied).
407         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
408         /// @param[in,out]  ray             Ray and associated information.
409         /// @param[in]      weight          Importance of this computation.
410         /// @param[in]      isect           Intersection information.
411         /// @param[in]      shadowflag      Whether to perform only computations necessary for shadow testing.
412         /// @param[in]      photonpass      Whether to deposit photons instead of computing a colour.
413         ///
414         void ComputeAverageTextureColours(MathColour& resultColour, ColourChannel& resultTransm, const TEXTURE *texture, vector<const TEXTURE *>& warps,
415                                           const Vector3d& ipoint, const Vector3d& rawnormal, Ray& ray, COLC weight,
416                                           Intersection& isect, bool shadowflag, bool photonpass);
417 
418         /// Compute the effective colour of a simple or layered texture.
419         ///
420         /// Computations include secondary rays.
421         ///
422         /// @remark         The computed contribution _overwrites_ any value passed in `colour`.
423         ///
424         /// @remark         Computations do _not_ include media effects between the ray's origin and the point of
425         ///                 intersection any longer.
426         ///
427         /// @remark         pov::PhotonTrace overrides this method to deposit photons instead.
428         ///
429         /// @todo           Some input parameters are non-const references or pointers.
430         ///
431         /// @param[in,out]  resultColour    Computed colour [out]; during photon pass: light colour [in].
432         /// @param[out]     resultTransm    Computed transparency; not used during photon pass.
433         /// @param[in]      texture         Texture.
434         /// @param[in]      warps           Stack of warps to be applied.
435         /// @param[in]      ipoint          Intersection point (possibly with earlier warps already applied).
436         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
437         /// @param[in,out]  ray             Ray and associated information.
438         /// @param[in]      weight          Importance of this computation.
439         /// @param[in]      isect           Intersection information.
440         ///
441         virtual void ComputeLightedTexture(MathColour& resultColour, ColourChannel& resultTransm, const TEXTURE *texture, vector<const TEXTURE *>& warps,
442                                            const Vector3d& ipoint, const Vector3d& rawnormal, Ray& ray, COLC weight,
443                                            Intersection& isect);
444 
445         /// Compute the effective filtering effect of a simple or layered texture.
446         ///
447         /// @remark         The computed contribution _overwrites_ any value passed in `colour`.
448         ///
449         /// @remark         Computations do _not_ include media effects between the ray's origin and the point of
450         ///                 intersection any longer.
451         ///
452         /// @todo           Some input parameters are non-const references or pointers.
453         ///
454         /// @param[out]     filtercolour    Computed filter colour.
455         /// @param[in]      texture         Texture.
456         /// @param[in]      warps           Stack of warps to be applied.
457         /// @param[in]      ipoint          Intersection point (possibly with earlier warps already applied).
458         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
459         /// @param[in,out]  ray             Ray and associated information.
460         /// @param[in]      isect           Intersection information.
461         ///
462         void ComputeShadowTexture(MathColour& filtercolour, const TEXTURE *texture, vector<const TEXTURE *>& warps,
463                                   const Vector3d& ipoint, const Vector3d& rawnormal, const Ray& ray,
464                                   Intersection& isect);
465 
466     ///
467     /// @}
468     ///
469     //*****************************************************************************
470     ///
471     /// @name Reflection and Refraction Computations
472     ///
473     /// The following methods compute the contribution of secondary (reflected and refracted) rays.
474     ///
475     /// @{
476     ///
477 
478         /// Compute the refraction contribution.
479         ///
480         /// @remark         The computed contribution _overwrites_ any value passed in `colour`.
481         ///
482         /// @param[in]      finish          Object's finish.
483         /// @param[in]      ipoint          Intersection point.
484         /// @param[in,out]  ray             Ray and associated information.
485         /// @param[in]      normal          Effective (possibly pertubed) surface normal.
486         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
487         /// @param[out]     colour          Computed colour.
488         /// @param[in]      weight          Importance of this computation.
489         ///
490         void ComputeReflection(const FINISH* finish, const Vector3d& ipoint, Ray& ray, const Vector3d& normal,
491                                const Vector3d& rawnormal, MathColour& colour, COLC weight);
492 
493         /// Compute the refraction contribution.
494         ///
495         /// @remark         The computed contribution _overwrites_ any value passed in `colour`.
496         ///
497         /// @param[in]      finish          Object's finish.
498         /// @param[in]      interior        Stack of currently effective interiors.
499         /// @param[in]      ipoint          Intersection point.
500         /// @param[in,out]  ray             Ray and associated information.
501         /// @param[in]      normal          Effective (possibly pertubed) surface normal.
502         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
503         /// @param[out]     colour          Computed colour.
504         /// @param[out]     transm          Computed transmittance.
505         /// @param[in]      weight          Importance of this computation.
506         /// @return                         `true` if total internal reflection _did_ occur.
507         ///
508         bool ComputeRefraction(const FINISH* finish, Interior *interior, const Vector3d& ipoint, Ray& ray,
509                                const Vector3d& normal, const Vector3d& rawnormal, MathColour& colour, ColourChannel& transm, COLC weight);
510 
511         /// Compute the contribution of a single refracted ray.
512         ///
513         /// @remark         The computed contribution _overwrites_ any value passed in `colour`.
514         ///
515         /// @param[in]      finish          object's finish.
516         /// @param[in]      ipoint          Intersection point.
517         /// @param[in,out]  ray             Original ray and associated information.
518         /// @param[in,out]  nray            Refracted ray [out] and associated information [in,out].
519         /// @param[in]      ior             Relative index of refraction.
520         /// @param[in]      n               Cosine of angle of incidence.
521         /// @param[in]      normal          Effective (possibly pertubed) surface normal.
522         /// @param[in]      rawnormal       Geometric (possibly smoothed) surface normal.
523         /// @param[in]      localnormal     Effective surface normal, possibly flipped to match ray.
524         /// @param[out]     colour          Computed colour.
525         /// @param[out]     transm          Computed transmittance.
526         /// @param[in]      weight          Importance of this computation.
527         /// @return                         `true` if total internal reflection _did_ occur.
528         ///
529         bool TraceRefractionRay(const FINISH* finish, const Vector3d& ipoint, Ray& ray, Ray& nray, double ior, double n,
530                                 const Vector3d& normal, const Vector3d& rawnormal, const Vector3d& localnormal,
531                                 MathColour& colour, ColourChannel& transm, COLC weight);
532 
533     ///
534     /// @}
535     ///
536     //*****************************************************************************
537     ///
538     /// @name Classic Light Source Computations
539     ///
540     /// The following methods compute the (additional) contribution of classic lighting.
541     ///
542     /// @{
543     ///
544 
545         /// @todo The name is misleading, as it computes all contributions of classic lighting, including highlights.
546         void ComputeDiffuseLight(const FINISH *finish, const Vector3d& ipoint, const  Ray& eye, const Vector3d& layer_normal, const MathColour& layer_pigment_colour,
547                                  MathColour& colour, double attenuation, ObjectPtr object, double relativeIor);
548         /// @todo The name is misleading, as it computes all contributions of classic lighting, including highlights.
549         void ComputeOneDiffuseLight(const LightSource &lightsource, const Vector3d& reye, const FINISH *finish, const Vector3d& ipoint, const Ray& eye,
550                                     const Vector3d& layer_normal, const MathColour& Layer_Pigment_Colour, MathColour& colour, double Attenuation, ConstObjectPtr Object, double relativeIor, int light_index = -1);
551         /// @todo The name is misleading, as it computes all contributions of classic lighting, including highlights.
552         void ComputeFullAreaDiffuseLight(const LightSource &lightsource, const Vector3d& reye, const FINISH *finish, const Vector3d& ipoint, const Ray& eye,
553                                          const Vector3d& layer_normal, const MathColour& layer_pigment_colour, MathColour& colour, double attenuation,
554                                          double lightsourcedepth, Ray& lightsourceray, const MathColour& lightcolour,
555                                          ConstObjectPtr object, double relativeIor); // JN2007: Full area lighting
556 
557         /// Compute the direction, distance and unshadowed brightness of an unshadowed light source.
558         ///
559         /// Computations include spotlight falloff and distance-based attenuation.
560         ///
561         /// @param[in]      lightsource         Light source.
562         /// @param[out]     lightsourcedepth    Distance to the light source.
563         /// @param[in,out]  lightsourceray      Ray to the light source.
564         /// @param[in]      ipoint              Intersection point.
565         /// @param[out]     lightcolour         Effective brightness.
566         /// @param[in]      forceAttenuate      `true` to immediately apply distance-based attenuation even for full
567         ///                                     area lights.
568         ///
569         void ComputeOneLightRay(const LightSource &lightsource, double& lightsourcedepth, Ray& lightsourceray,
570                                 const Vector3d& ipoint, MathColour& lightcolour, bool forceAttenuate = false);
571 
572         void TraceShadowRay(const LightSource &light, double depth, Ray& lightsourceray, const Vector3d& point, MathColour& colour);
573         void TracePointLightShadowRay(const LightSource &lightsource, double& lightsourcedepth, Ray& lightsourceray, MathColour& lightcolour);
574         void TraceAreaLightShadowRay(const LightSource &lightsource, double& lightsourcedepth, Ray& lightsourceray,
575                                      const Vector3d& ipoint, MathColour& lightcolour);
576         void TraceAreaLightSubsetShadowRay(const LightSource &lightsource, double& lightsourcedepth, Ray& lightsourceray,
577                                            const Vector3d& ipoint, MathColour& lightcolour, int u1, int  v1, int  u2, int  v2, int level, const Vector3d& axis1, const Vector3d& axis2);
578 
579         /// Compute the filtering effect of an object on incident light from a particular light source.
580         ///
581         /// Computations include any media effects between the ray's origin and the point of intersection.
582         ///
583         /// @todo           Some input parameters are non-const references.
584         ///
585         /// @param[in]      lightsource     Light source.
586         /// @param[in]      isect           Intersection information.
587         /// @param[in,out]  lightsourceray  Ray to the light source.
588         /// @param[in,out]  colour          Computed effect on the incident light.
589         ///
590         void ComputeShadowColour(const LightSource &lightsource, Intersection& isect, Ray& lightsourceray,
591                                  MathColour& colour);
592 
593         /// Compute the direction and distance of a single light source to a given intersection
594         /// point.
595         ///
596         /// @remark         The `Origin` and `Direction` member of `lightsourceray` are updated, all other members are
597         ///                 left unchanged; the distance is returned in a separate parameter. For cylindrical light
598         ///                 sources, the values are set accordingly.
599         ///
600         /// @todo           The name is misleading, as it just computes direction and distance.
601         ///
602         /// @param[in]      lightsource         Light source.
603         /// @param[out]     lightsourcedepth    Distance to the light source.
604         /// @param[in,out]  lightsourceray      Ray to the light source.
605         /// @param[in]      ipoint              Intersection point.
606         /// @param[in]      jitter              Jitter to apply to the light source.
607         ///
608         void ComputeOneWhiteLightRay(const LightSource &lightsource, double& lightsourcedepth, Ray& lightsourceray,
609                                      const Vector3d& ipoint, const Vector3d& jitter = Vector3d());
610 
611     ///
612     /// @}
613     ///
614     //*****************************************************************************
615     ///
616     /// @name Photon Light Source Computations
617     ///
618     /// The following methods compute the (additional) contribution of photon-based lighting.
619     ///
620     /// @{
621     ///
622 
623         /// @todo The name is misleading, as it computes all contributions of classic lighting, including highlights.
624         void ComputePhotonDiffuseLight(const FINISH *Finish, const Vector3d& IPoint, const Ray& Eye, const Vector3d& Layer_Normal, const Vector3d& Raw_Normal,
625                                        const MathColour& Layer_Pigment_Colour, MathColour& colour, double Attenuation,
626                                        ConstObjectPtr Object, double relativeIor, PhotonGatherer& renderer);
627 
628     ///
629     /// @}
630     ///
631     //*****************************************************************************
632     ///
633     /// @name Material Finish Computations
634     ///
635     /// The following methods compute the contribution of a finish illuminated by light from a given direction.
636     ///
637     /// @{
638     ///
639 
640         /// Compute the diffuse contribution of a finish illuminated by light from a given direction.
641         ///
642         /// @remark         The computed contribution is _added_ to the value passed in `colour`.
643         ///
644         /// @param[in]      finish                  Finish.
645         /// @param[in]      lightDirection          Direction of incoming light.
646         /// @param[in]      eyeDirection            Direction from observer.
647         /// @param[in]      layer_normal            Effective (possibly pertubed) surface normal.
648         /// @param[in,out]  colour                  Effective surface colour.
649         /// @param[in]      light_colour            Effective light colour.
650         /// @param[in]      layer_pigment_colour    Nominal pigment colour.
651         /// @param[in]      attenuation             Attenuation factor to account for partial transparency.
652         /// @param[in]      backside                Whether to use backside instead of frontside diffuse brightness
653         ///                                         factor.
654         ///
655         void ComputeDiffuseColour(const FINISH *finish, const Vector3d& lightDirection, const Vector3d& eyeDirection, const Vector3d& layer_normal,
656                                   MathColour& colour, const MathColour& light_colour,
657                                   const MathColour& layer_pigment_colour, double relativeIor, double attenuation, bool backside);
658 
659         /// Compute the iridescence contribution of a finish illuminated by light from a given direction.
660         ///
661         /// @remark         The computed contribution is _added_ to the value passed in `colour`.
662         ///
663         /// @param[in]      finish          Finish.
664         /// @param[in]      lightDirection  Direction of incoming light.
665         /// @param[in]      eyeDirection    Direction from observer.
666         /// @param[in]      layer_normal    Effective (possibly pertubed) surface normal.
667         /// @param[in]      ipoint          Intersection point (possibly with earlier warps already applied).
668         /// @param[in,out]  colour          Effective surface colour.
669         ///
670         void ComputeIridColour(const FINISH *finish, const Vector3d& lightDirection, const Vector3d& eyeDirection,
671                                const Vector3d& layer_normal, const Vector3d& ipoint, MathColour& colour);
672 
673         /// Compute the Phong highlight contribution of a finish illuminated by light from a given direction.
674         ///
675         /// Computation uses the classic Phong highlight model.
676         ///
677         /// @remark         The model used is _not_ energy-conserving.
678         ///
679         /// @remark         The computed contribution is _added_ to the value passed in `colour`.
680         ///
681         /// @param[in]      finish                  Finish.
682         /// @param[in]      lightDirection          Direction of ray from light source.
683         /// @param[in]      eyeDirection            Direction from observer.
684         /// @param[in]      layer_normal            Effective (possibly pertubed) surface normal.
685         /// @param[in,out]  colour                  Effective surface colour.
686         /// @param[in]      light_colour            Effective light colour.
687         /// @param[in]      layer_pigment_colour    Nominal pigment colour.
688         /// @param[in]      fresnel                 Whether to apply fresnel-based attenuation.
689         ///
690         void ComputePhongColour(const FINISH *finish, const Vector3d& lightDirection, const Vector3d& eyeDirection,
691                                 const Vector3d& layer_normal, MathColour& colour, const MathColour& light_colour,
692                                 const MathColour& layer_pigment_colour, double relativeIor);
693 
694         /// Compute the specular highlight contribution of a finish illuminated by light from a given direction.
695         ///
696         /// Computation uses the Blinn-Phong highlight model
697         ///
698         /// @remark     The model used is _not_ energy-conserving.
699         ///
700         /// @remark     The computed contribution is _added_ to the value passed in `colour`.
701         ///
702         /// @param[in]      finish                  Finish.
703         /// @param[in]      lightDirection          Direction of ray from light source.
704         /// @param[in]      eyeDirection            Direction from observer.
705         /// @param[in]      layer_normal            Effective (possibly pertubed) surface normal.
706         /// @param[in,out]  colour                  Effective surface colour.
707         /// @param[in]      light_colour            Effective light colour.
708         /// @param[in]      layer_pigment_colour    Nominal pigment colour.
709         /// @param[in]      fresnel                 Whether to apply fresnel-based attenuation.
710         ///
711         void ComputeSpecularColour(const FINISH *finish, const Vector3d& lightDirection, const Vector3d& eyeDirection,
712                                    const Vector3d& layer_normal, MathColour& colour, const MathColour& light_colour,
713                                    const MathColour& layer_pigment_colour, double relativeIor);
714 
715     ///
716     /// @}
717     ///
718     //*****************************************************************************
719     ///
720 
721         /// Compute relative index of refraction.
722         void ComputeRelativeIOR(const Ray& ray, const Interior* interior, double& ior);
723 
724         /// Compute Reflectivity.
725         ///
726         /// @remark         In Fresnel mode, light is presumed to be unpolarized on average, using
727         ///                 @f$ R = \frac{1}{2} \left( R_s + R_p \right) @f$.
728         ///
729         void ComputeReflectivity(double& weight, MathColour& reflectivity, const MathColour& reflection_max,
730                                  const MathColour& reflection_min, bool fresnel, double reflection_falloff,
731                                  double cos_angle, double relativeIor);
732 
733         /// Compute metallic attenuation
734         void ComputeMetallic(MathColour& colour, double metallic, const MathColour& metallicColour, double cosAngle);
735 
736         /// Compute fresnel-based reflectivity.
737         void ComputeFresnel(MathColour& colour, const MathColour& rMax, const MathColour& rMin, double cos_angle, double relativeIor);
738 
739         /// Compute Fresnel reflectance term.
740         ///
741         /// This function computes the reflectance term _R_ of the Fresnel equations for the special
742         /// case of a dielectric material and unpolarized light. The transmittance term _T_ can
743         /// trivially be computed as _T=1-R_.
744         ///
745         /// @param[in]      cosTi           Cosine of angle between incident ray and surface normal.
746         /// @param[in]      n               Relative refractive index of the material entered.
747         ///
748         static double FresnelR(double cosTi, double n);
749 
750         /// Compute Sky & Background Colour.
751         ///
752         /// @remark         The computed colour _overwrites_ any value passed in `colour` and `transm`.
753         ///
754         /// @param[in]      ray             Ray.
755         /// @param[out]     colour          Computed sky/background colour.
756         /// @param[out]     transm          Computed transmittance.
757         ///
758         void ComputeSky(const Ray& ray, MathColour& colour, ColourChannel& transm);
759 
760         void ComputeFog(const Ray& ray, const Intersection& isect, MathColour& colour, ColourChannel& transm);
761         double ComputeConstantFogDepth(const Ray &ray, double depth, double width, const FOG *fog);
762         double ComputeGroundFogDepth(const Ray& ray, double depth, double width, const FOG *fog);
763         void ComputeRainbow(const Ray& ray, const Intersection& isect, MathColour& colour, ColourChannel& transm);
764 
765         /// Compute media effect on traversing light rays.
766         ///
767         /// @note           This computes two things:
768         ///                   - media and fog attenuation of the shadow ray (optional)
769         ///                   - entry/exit of interiors
770         ///                   .
771         ///                 In other words, you can't skip this whole thing, because the entry/exit is important.
772         ///
773         void ComputeShadowMedia(Ray& light_source_ray, Intersection& isect, MathColour& resultcolour,
774                                 bool media_attenuation_and_interaction);
775 
776         /// Test whether an object is part of (or identical to) a given other object.
777         ///
778         /// @todo           The name is misleading, as the object to test against (`parent`) does not necessarily have
779         ///                 to be a CSG compound object, but can actually be of any type. In that case, the function
780         ///                 serves to test for identity.
781         ///
782         /// @param[in]      object          The object to test.
783         /// @param[in]      parent          The object to test against.
784         /// @return                         True if `object` is part of, or identical to, `parent`.
785         ///
786         bool IsObjectInCSG(ConstObjectPtr object, ConstObjectPtr parent);
787 
788 
789     ///
790     //*****************************************************************************
791     ///
792     /// @name Subsurface Light Transport
793     ///
794     /// The following methods implement the BSSRDF approximation as outlined by Jensen et al.
795     ///
796     /// @{
797     ///
798 
799         double ComputeFt(double phi, double eta);
800         void ComputeSurfaceTangents(const Vector3d& normal, Vector3d& u, Vector3d& v);
801         void ComputeSSLTNormal (Intersection& Ray_Intersection);
802         bool IsSameSSLTObject(ConstObjectPtr obj1, ConstObjectPtr obj2);
803         void ComputeDiffuseSampleBase(Vector3d& basePoint, const Intersection& out, const Vector3d& vOut, double avgFreeDist, TraceTicket& ticket);
804         void ComputeDiffuseSamplePoint(const Vector3d& basePoint, Intersection& in, double& sampleArea, TraceTicket& ticket);
805         void ComputeDiffuseContribution(const Intersection& out, const Vector3d& vOut, const Vector3d& pIn, const Vector3d& nIn, const Vector3d& vIn, double& sd, double sigma_prime_s, double sigma_a, double eta);
806         void ComputeDiffuseContribution1(const LightSource& lightsource, const Intersection& out, const Vector3d& vOut, const Intersection& in, MathColour& Total_Colour, const PreciseMathColour& sigma_prime_s, const PreciseMathColour& sigma_a, double eta, double weight, TraceTicket& ticket);
807         void ComputeDiffuseAmbientContribution1(const Intersection& out, const Vector3d& vOut, const Intersection& in, MathColour& Total_Colour, const PreciseMathColour& sigma_prime_s, const PreciseMathColour& sigma_a, double eta, double weight, TraceTicket& ticket);
808         void ComputeOneSingleScatteringContribution(const LightSource& lightsource, const Intersection& out, double sigma_t_xo, double sigma_s, double s_prime_out, MathColour& Lo, double eta, const Vector3d& bend_point, double phi_out, double cos_out_prime, TraceTicket& ticket);
809         void ComputeSingleScatteringContribution(const Intersection& out, double dist, double theta_out, double cos_out_prime, const Vector3d& refractedREye, double sigma_t_xo, double sigma_s, MathColour& Lo, double eta, TraceTicket& ticket);
810         void ComputeSubsurfaceScattering (const FINISH *Finish, const MathColour& layer_pigment_colour, const Intersection& isect, Ray& Eye, const Vector3d& Layer_Normal, MathColour& colour, double Attenuation);
811         bool SSLTComputeRefractedDirection(const Vector3d& v, const Vector3d& n, double eta, Vector3d& refracted);
812 
813     ///
814     /// @}
815     ///
816     //*****************************************************************************
817     ///
818 
819 };
820 
821 /// @}
822 ///
823 //##############################################################################
824 
825 }
826 
827 #endif // POVRAY_CORE_TRACE_H
828