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