SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLRay Class Reference

Ray class with ray and intersection properties. More...

#include <SLRay.h>

Public Member Functions

 SLRay (SLSceneView *sv=nullptr)
 default ctor More...
 
 SLRay (const SLVec3f &Origin, const SLVec3f &Dir, SLfloat X, SLfloat Y, const SLCol4f &backColor, SLSceneView *sv)
 ctor for primary rays More...
 
 SLRay (SLfloat distToLight, const SLVec3f &dirToLight, SLRay *rayFromHitPoint)
 ctor for shadow rays More...
 
void reflect (SLRay *reflected) const
 
void refract (SLRay *refracted)
 
bool reflectMC (SLRay *reflected, const SLMat3f &rotMat) const
 
bool refractMC (SLRay *refracted, const SLMat3f &rotMat) const
 
void diffuseMC (SLRay *scattered) const
 
void print () const
 
void setDir (const SLVec3f &Dir)
 Setter for the rays direction in world space also setting the inverse direction. More...
 
void setDirOS (const SLVec3f &Dir)
 Setter for the rays direction in object space also setting the inverse direction. More...
 
void normalizeNormal ()
 
SLbool isShaded () const
 Returns true if a shadow ray hits an object on the ray to the light. More...
 
SLbool hitMatIsReflective () const
 Returns true if the hit material specular color is not black. More...
 
SLbool hitMatIsTransparent () const
 Returns true if the hit material transmission color is not black. More...
 
SLbool hitMatIsDiffuse () const
 Returns true if the hit material diffuse color is not black. More...
 

Static Public Member Functions

static SLMat3f lobeToWorld (const SLVec3f &lobeAxis)
 Rotation matrix that maps a sample drawn around +z onto lobeAxis. More...
 
static SLuint totalNumRays ()
 Total NO. of rays shot during RT. More...
 

Public Attributes

SLVec3f origin
 Vector to the origin of ray in WS. More...
 
SLVec3f dir
 Direction vector of ray in WS. More...
 
SLfloat length
 length from origin to an intersection More...
 
SLint depth
 Recursion depth for ray tracing. More...
 
SLfloat contrib
 Current contribution of ray to color. More...
 
SLVec3f originOS
 Vector to the origin of ray in OS. More...
 
SLVec3f dirOS
 Direction vector of ray in OS. More...
 
SLRayType type
 PRIMARY, REFLECTED, REFRACTED, SHADOW. More...
 
SLfloat lightDist
 Distance to light for shadow rays. More...
 
SLfloat x
 
SLfloat y
 Pixel position for primary rays. More...
 
SLbool isOutside
 Flag if ray is inside of a material. More...
 
SLbool isInsideVolume
 Flag if ray is in Volume. More...
 
SLNodesrcNode
 Points to the node at ray origin. More...
 
SLMeshsrcMesh
 Points to the mesh at ray origin. More...
 
SLint srcTriangle
 Points to the triangle at ray origin. More...
 
SLCol4f backgroundColor
 Background color at pixel x,y. More...
 
SLSceneViewsv
 Pointer to the sceneview. More...
 
SLfloat hitU
 
SLfloat hitV
 barycentric coords in hit triangle More...
 
SLNodehitNode
 Points to the intersected node. More...
 
SLMeshhitMesh
 Points to the intersected mesh. More...
 
SLint hitTriangle
 Points to the intersected triangle. More...
 
SLVec3f hitPoint
 Point of intersection. More...
 
SLVec3f hitNormal
 Surface normal at intersection point. More...
 
SLCol4f hitTexColor
 Color at intersection for texture or color attributes. More...
 
SLfloat hitAO
 Ambient occlusion factor at intersection point. More...
 
SLVec3f invDir
 Inverse ray dir for fast AABB hit in WS. More...
 
SLVec3f invDirOS
 Inverse ray dir for fast AABB hit in OS. More...
 
SLint sign [3]
 Sign of invDir for fast AABB hit in WS. More...
 
SLint signOS [3]
 Sign of invDir for fast AABB hit in OS. More...
 
SLfloat tmin
 min. dist. of last AABB intersection More...
 
SLfloat tmax
 max. dist. of last AABB intersection More...
 

Static Public Attributes

static SLint maxDepth = 0
 Max. recursion depth. More...
 
static SLfloat minContrib = 1.0 / 256.0
 Min. contibution to color (1/256) More...
 
static SLuint primaryRays = 0
 NO. of primary rays shot. More...
 
static SLuint reflectedRays = 0
 NO. of reflected rays. More...
 
static SLuint refractedRays = 0
 NO. of refracted rays. More...
 
static SLuint ignoredRays = 0
 NO. of ignore refraction rays. More...
 
static SLuint shadowRays = 0
 NO. of shadow rays. More...
 
static SLuint tirRays = 0
 NO. of TIR refraction rays. More...
 
static SLuint tests = 0
 NO. of intersection tests. More...
 
static SLuint intersections = 0
 NO. of intersection. More...
 
static SLint depthReached = 1
 depth reached for a primary ray More...
 
static SLint maxDepthReached = 0
 max. depth reached for all rays More...
 
static SLfloat avgDepth = 0
 average depth reached More...
 
static SLuint subsampledRays = 0
 NO. of of subsampled rays. More...
 
static SLuint subsampledPixels = 0
 NO. of of subsampled pixels. More...
 

Detailed Description

Ray class with ray and intersection properties.

Ray class for Ray Tracing. It not only holds informations about the ray itself but also about the node hit by the ray. With that information the method reflect calculates a reflected ray and the method transmit calculates a REFRACTED ray.

Definition at line 39 of file SLRay.h.

Constructor & Destructor Documentation

◆ SLRay() [1/3]

SLRay::SLRay ( SLSceneView sceneView = nullptr)
explicit

default ctor

SLRay::SLRay default constructor

Definition at line 65 of file SLRay.cpp.

66 {
69  type = PRIMARY;
70  length = FLT_MAX;
71  depth = 1;
72  hitTriangle = -1;
76  hitAO = 1.0f;
77  hitNode = nullptr;
78  hitMesh = nullptr;
79  srcNode = nullptr;
80  srcMesh = nullptr;
81  srcTriangle = -1;
82  x = -1;
83  y = -1;
84  contrib = 1.0f;
85  isOutside = true;
86  isInsideVolume = false;
87  sv = sceneView;
88 }
@ PRIMARY
Definition: SLRay.h:23
SLint hitTriangle
Points to the intersected triangle.
Definition: SLRay.h:110
SLVec3f origin
Vector to the origin of ray in WS.
Definition: SLRay.h:78
SLRayType type
PRIMARY, REFLECTED, REFRACTED, SHADOW.
Definition: SLRay.h:95
SLint srcTriangle
Points to the triangle at ray origin.
Definition: SLRay.h:102
SLMesh * hitMesh
Points to the intersected mesh.
Definition: SLRay.h:109
SLbool isOutside
Flag if ray is inside of a material.
Definition: SLRay.h:98
SLint depth
Recursion depth for ray tracing.
Definition: SLRay.h:81
SLfloat hitAO
Ambient occlusion factor at intersection point.
Definition: SLRay.h:116
SLMesh * srcMesh
Points to the mesh at ray origin.
Definition: SLRay.h:101
SLfloat length
length from origin to an intersection
Definition: SLRay.h:80
SLNode * hitNode
Points to the intersected node.
Definition: SLRay.h:108
SLfloat contrib
Current contribution of ray to color.
Definition: SLRay.h:82
SLbool isInsideVolume
Flag if ray is in Volume.
Definition: SLRay.h:99
SLVec3f hitPoint
Point of intersection.
Definition: SLRay.h:113
SLNode * srcNode
Points to the node at ray origin.
Definition: SLRay.h:100
void setDir(const SLVec3f &Dir)
Setter for the rays direction in world space also setting the inverse direction.
Definition: SLRay.h:149
SLCol4f hitTexColor
Color at intersection for texture or color attributes.
Definition: SLRay.h:115
SLfloat y
Pixel position for primary rays.
Definition: SLRay.h:97
SLfloat x
Definition: SLRay.h:97
SLVec3f hitNormal
Surface normal at intersection point.
Definition: SLRay.h:114
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
static SLVec3 ZERO
Definition: SLVec3.h:285
static SLVec4 WHITE
Definition: SLVec4.h:215

◆ SLRay() [2/3]

SLRay::SLRay ( const SLVec3f Origin,
const SLVec3f Dir,
SLfloat  X,
SLfloat  Y,
const SLCol4f backColor,
SLSceneView sceneView 
)

ctor for primary rays

SLRay::SLRay constructor for primary rays

Definition at line 93 of file SLRay.cpp.

99 {
100  origin = Origin;
101  setDir(Dir);
102  type = PRIMARY;
103  length = FLT_MAX;
104  depth = 1;
105  hitTriangle = -1;
109  hitAO = 1.0f;
110  hitNode = nullptr;
111  hitMesh = nullptr;
112  srcNode = nullptr;
113  srcMesh = nullptr;
114  srcTriangle = -1;
115  x = (SLfloat)X;
116  y = (SLfloat)Y;
117  contrib = 1.0f;
118  isOutside = true;
119  isInsideVolume = false;
120  backgroundColor = backColor;
121  sv = sceneView;
122 }
float SLfloat
analog to GLfloat
Definition: SL.h:200
SLCol4f backgroundColor
Background color at pixel x,y.
Definition: SLRay.h:103

◆ SLRay() [3/3]

SLRay::SLRay ( SLfloat  distToLight,
const SLVec3f dirToLight,
SLRay rayFromHitPoint 
)

ctor for shadow rays

SLRay::SLRay constructor for shadow rays

Definition at line 127 of file SLRay.cpp.

130 {
131  origin = rayFromHitPoint->hitPoint;
132  setDir(dirToLight);
133  type = SHADOW;
134  length = distToLight;
135  lightDist = distToLight;
136  depth = rayFromHitPoint->depth;
140  hitAO = 1.0f;
141  hitTriangle = -1;
142  hitNode = nullptr;
143  hitMesh = nullptr;
144  srcNode = rayFromHitPoint->hitNode;
145  srcMesh = rayFromHitPoint->hitMesh;
146  srcTriangle = rayFromHitPoint->hitTriangle;
147  x = rayFromHitPoint->x;
148  y = rayFromHitPoint->y;
149  backgroundColor = rayFromHitPoint->backgroundColor;
150  sv = rayFromHitPoint->sv;
151  contrib = 0.0f;
152  isOutside = rayFromHitPoint->isOutside;
153  shadowRays++;
154 }
@ SHADOW
Definition: SLRay.h:26
static SLuint shadowRays
NO. of shadow rays.
Definition: SLRay.h:133
SLfloat lightDist
Distance to light for shadow rays.
Definition: SLRay.h:96
SLSceneView * sv
Pointer to the sceneview.
Definition: SLRay.h:104

Member Function Documentation

◆ diffuseMC()

void SLRay::diffuseMC ( SLRay scattered) const

SLRay::diffuseMC scatters a ray around the hit normal with a cosine distribution, which is the importance sampling of the Lambertian BRDF: the density is cos(theta)/PI, so it cancels the cosine of the rendering equation and every sample carries the same weight. SLPathtracer::trace is its only caller in this repository.

The random direction lies around the z-Axis and is then transformed by a rotation matrix to lie along the normal. The direction is calculated according to MCCABE.

Remarks
The comment here used to read "This is only used for photonmapping(russian roulette)". Both halves were wrong. Cosine distributed scattering is importance sampling and has nothing to do with Russian roulette, which is the unrelated technique that terminates the recursion in SLPathtracer::trace (see plan point 13), and there is no photon mapper in this repository.

Definition at line 542 of file SLRay.cpp.

543 {
544  SLVec3f randVec;
545  SLfloat eta1, eta2, eta1sqrt;
546 
547  scattered->setDir(hitNormal);
548  scattered->origin = hitPoint;
549  scattered->depth = depth + 1;
550  depthReached = scattered->depth;
551 
552  // for reflectance the start material stays the same
553  scattered->srcNode = hitNode;
554  scattered->srcMesh = hitMesh;
555  scattered->type = REFLECTED;
556 
557  // Rotation matrix that takes the +z lobe onto the hit normal. See
558  // SLRay::lobeToWorld for why this is not built from an axis and an angle.
559  SLMat3f rotMat = lobeToWorld(scattered->dir);
560 
561  // cosine distribution
562  eta1 = rnd01();
563  eta2 = Utils::TWOPI * rnd01();
564  eta1sqrt = sqrt(1 - eta1);
565 
566  // transform to cartesian
567  randVec.set(eta1sqrt * cos(eta2),
568  eta1sqrt * sin(eta2),
569  sqrt(eta1));
570 
571  // Apply rotation
572  scattered->setDir(rotMat * randVec);
573 
574  // Set pixel and background
575  scattered->x = x;
576  scattered->y = y;
577  scattered->sv = sv;
578  if (sv->s()->skybox())
579  scattered->backgroundColor = sv->s()->skybox()->colorAtDir(scattered->dir);
580  else
581  scattered->backgroundColor = backgroundColor;
582 }
SLfloat rnd01()
Definition: SLRay.cpp:50
@ REFLECTED
Definition: SLRay.h:24
static SLint depthReached
depth reached for a primary ray
Definition: SLRay.h:137
SLVec3f dir
Direction vector of ray in WS.
Definition: SLRay.h:79
static SLMat3f lobeToWorld(const SLVec3f &lobeAxis)
Rotation matrix that maps a sample drawn around +z onto lobeAxis.
Definition: SLRay.cpp:372
void skybox(SLSkybox *skybox)
Definition: SLScene.h:91
SLScene * s()
Definition: SLSceneView.h:171
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
static const float TWOPI
Definition: Utils.h:240

◆ hitMatIsDiffuse()

SLbool SLRay::hitMatIsDiffuse ( ) const
inline

Returns true if the hit material diffuse color is not black.

Definition at line 219 of file SLRay.h.

220 {
221  if (!hitMesh) return false;
222  SLMaterial* mat = hitMesh->mat();
223  return ((mat->diffuse().r > 0.0f) ||
224  (mat->diffuse().g > 0.0f) ||
225  (mat->diffuse().b > 0.0f));
226 }
Defines a standard CG material with textures and a shader program.
Definition: SLMaterial.h:56
void diffuse(const SLCol4f &diff)
Definition: SLMaterial.h:171
SLMaterial * mat() const
Definition: SLMesh.h:177

◆ hitMatIsReflective()

SLbool SLRay::hitMatIsReflective ( ) const
inline

Returns true if the hit material specular color is not black.

Definition at line 197 of file SLRay.h.

198 {
199  if (!hitMesh) return false;
200  SLMaterial* mat = hitMesh->mat();
201  return ((mat->specular().r > 0.0f) ||
202  (mat->specular().g > 0.0f) ||
203  (mat->specular().b > 0.0f));
204 }
void specular(const SLCol4f &spec)
Definition: SLMaterial.h:173

◆ hitMatIsTransparent()

SLbool SLRay::hitMatIsTransparent ( ) const
inline

Returns true if the hit material transmission color is not black.

Definition at line 208 of file SLRay.h.

209 {
210  if (!hitMesh) return false;
211  SLMaterial* mat = hitMesh->mat();
212  return ((mat->transmissive().r > 0.0f) ||
213  (mat->transmissive().g > 0.0f) ||
214  (mat->transmissive().b > 0.0f));
215 }
void transmissive(const SLCol4f &transm)
Definition: SLMaterial.h:175

◆ isShaded()

SLbool SLRay::isShaded ( ) const
inline

Returns true if a shadow ray hits an object on the ray to the light.

Definition at line 190 of file SLRay.h.

191 {
192  return type == SHADOW && length < lightDist;
193 }

◆ lobeToWorld()

SLMat3f SLRay::lobeToWorld ( const SLVec3f lobeAxis)
static

Rotation matrix that maps a sample drawn around +z onto lobeAxis.

SLRay::lobeToWorld returns the rotation matrix that maps a direction sampled around the +z axis onto lobeAxis. Its columns are an orthonormal basis whose third vector is lobeAxis, so that rotMat * v = v.x*t + v.y*b + v.z*lobeAxis.

This replaces the axis-angle construction that the scattering functions used to do themselves:

SLVec3f rotAxis((SLVec3f(0,0,1) ^ dir).normalize());
rotMat.rotation(acos(dir.z) * 180 * ONEOVERPI, rotAxis);

which fails exactly where it is used most. The cross product is (-dir.y, dir.x, 0) and its length is the sine of the angle, so it vanishes for a lobe axis along +-z. SLVec3::normalize guards with if (L > 0) and therefore returns the zero vector rather than a NaN, and the matrix built from a zero axis is diag(cos a, cos a, cos a) - a uniform scale, not a rotation. It happens to be usable at exactly +-z (identity and -I, and -I is fine for an azimuthally symmetric lobe) but the axis loses its precision continuously as the lobe approaches either pole, and acos(dir.z) additionally returns a NaN as soon as rounding pushes |dir.z| past 1. In the Muttenzer Box the box is axis aligned and the front and back walls face +-z, so this is the common case and not a corner one.

The basis is the branchless construction of Duff et al., "Building an Orthonormal Basis, Revisited", JCGT 6(1), 2017. It is exact and orthonormal for every unit vector including both poles, needs no trigonometry, and has no branch on a tolerance that has to be tuned.

Definition at line 372 of file SLRay.cpp.

373 {
374  SLVec3f n(lobeAxis);
375  n.normalize();
376 
377  SLfloat sign = std::copysign(1.0f, n.z);
378  SLfloat a = -1.0f / (sign + n.z);
379  SLfloat b = n.x * n.y * a;
380 
381  SLVec3f t(1.0f + sign * n.x * n.x * a, sign * b, -sign * n.x);
382  SLVec3f u(b, sign + n.y * n.y * a, -n.y);
383 
384  // The SLMat3 constructor takes the components in row order and stores them
385  // column wise, so this sets the columns to t, u and n.
386  return SLMat3f(t.x, u.x, n.x, t.y, u.y, n.y, t.z, u.z, n.z);
387 }
SLMat3< SLfloat > SLMat3f
Definition: SLMat3.h:746
SLint sign[3]
Sign of invDir for fast AABB hit in WS.
Definition: SLRay.h:121

◆ normalizeNormal()

void SLRay::normalizeNormal ( )
inline

SLRay::normalizeNormal does a careful normalization of the normal only when the squared length is > 1.0+FLT_EPSILON or < 1.0-FLT_EPSILON.

Definition at line 178 of file SLRay.h.

179 {
180  SLfloat nLenSqr = hitNormal.lengthSqr();
181  if (nLenSqr > 1.0f + FLT_EPSILON || nLenSqr < 1.0f - FLT_EPSILON)
182  {
183  SLfloat len = sqrt(nLenSqr);
184  hitNormal /= len;
185  }
186 }
T lengthSqr() const
Definition: SLVec3.h:123

◆ print()

void SLRay::print ( ) const

SLRay::prints prints the rays origin (O), direction (D) and the length to the intersection (L)

Definition at line 160 of file SLRay.cpp.

161 {
162  SL_LOG("Ray: O(%.2f, %.2f, %.2f), D(%.2f, %.2f, %.2f), L: %.2f",
163  origin.x,
164  origin.y,
165  origin.z,
166  dir.x,
167  dir.y,
168  dir.z,
169  length);
170 }
#define SL_LOG(...)
Some debugging and error handling macros.
Definition: SL.h:279
T y
Definition: SLVec3.h:43
T x
Definition: SLVec3.h:43
T z
Definition: SLVec3.h:43

◆ reflect()

void SLRay::reflect ( SLRay reflected) const

SLRay::reflect calculates a secondary ray reflected at the normal, starting at the intersection point. All vectors must be normalized vectors. R = 2(-I*N) N + I

Definition at line 177 of file SLRay.cpp.

178 {
179 #ifdef DEBUG_RAY
180  for (SLint i = 0; i < depth; ++i)
181  cout << " ";
182  cout << "Reflect: " << hitMesh->name() << endl;
183 #endif
184 
185  SLVec3f R(dir - 2.0f * (dir * hitNormal) * hitNormal);
186 
187  reflected->setDir(R);
188  reflected->origin.set(hitPoint);
189  reflected->depth = depth + 1;
190  reflected->length = FLT_MAX;
191  reflected->contrib = contrib * hitMesh->mat()->kr();
192  reflected->srcNode = hitNode;
193  reflected->srcMesh = hitMesh;
194  reflected->srcTriangle = hitTriangle;
195  reflected->type = REFLECTED;
196  reflected->isOutside = isOutside;
197  reflected->x = x;
198  reflected->y = y;
199  reflected->sv = sv;
200  if (sv->s()->skybox())
201  reflected->backgroundColor = sv->s()->skybox()->colorAtDir(reflected->dir);
202  else
203  reflected->backgroundColor = backgroundColor;
204 
205  depthReached = reflected->depth;
206  ++reflectedRays;
207 }
int SLint
analog to GLint
Definition: SL.h:197
void kr(SLfloat kr)
Definition: SLMaterial.h:184
void name(const SLstring &Name)
Definition: SLObject.h:34
static SLuint reflectedRays
NO. of reflected rays.
Definition: SLRay.h:130

◆ reflectMC()

bool SLRay::reflectMC ( SLRay reflected,
const SLMat3f rotMat 
) const

SLRay::reflectMC scatters a ray around perfect specular direction according to shininess (for higher shininess the ray is less scattered). This is used for path tracing and distributed ray tracing as well as for photon scattering. The direction is calculated according to MCCABE. The created direction is along z-axis and then transformed to lie along specular direction with rotationMatrix rotMat, which SLRay::lobeToWorld builds from the perfect specular direction. The rotation matrix must be precalculated (stays the same for each ray sample, needs to be calculated only once).

reflected->dir must hold the perfect specular direction on entry, i.e. the caller must have run SLRay::reflect first, because it is the reference against which the sampled direction is tested.

Returns
false if the sample landed on the far side of the surface. The Phong lobe is a cone around the mirror direction and is not clipped to the hemisphere, so a wide lobe at a grazing angle puts part of its samples below the horizon. The normalised Phong BRDF is zero there, so such a sample carries no energy and the caller must not trace it. Note that the test is a comparison of signs and not "points along the normal": SLMesh::preShade does not flip the hit normal towards the ray, so a back face hit has a perfect specular direction with a negative dot product and every sample around it would otherwise be rejected.

Definition at line 413 of file SLRay.cpp.

414 {
415  SLfloat eta1, eta2;
416  SLVec3f randVec;
417  SLfloat shininess = hitMesh->mat()->shininess();
418 
419  // The side of the surface the perfect specular direction leaves on
420  SLfloat perfectCos = hitNormal.dot(reflected->dir);
421 
422  // scatter within specular lobe
423  eta1 = rnd01();
424  eta2 = Utils::TWOPI * rnd01();
425  SLfloat f1 = sqrt(1.0f - pow(eta1, 2.0f / (shininess + 1.0f)));
426 
427  // tranform to cartesian
428  randVec.set(f1 * cos(eta2),
429  f1 * sin(eta2),
430  pow(eta1, 1.0f / (shininess + 1.0f)));
431 
432  // ray needs to be reset if already hit a scene node
433  if (reflected->hitNode)
434  {
435  reflected->length = FLT_MAX;
436  reflected->hitNode = nullptr;
437  reflected->hitMesh = nullptr;
438  reflected->hitPoint = SLVec3f::ZERO;
439  reflected->hitNormal = SLVec3f::ZERO;
440  }
441 
442  // apply rotation
443  reflected->setDir(rotMat * randVec);
444 
445  // Set pixel and background
446  reflected->x = x;
447  reflected->y = y;
448  reflected->sv = sv;
449  if (sv->s()->skybox())
450  reflected->backgroundColor = sv->s()->skybox()->colorAtDir(reflected->dir);
451  else
452  reflected->backgroundColor = backgroundColor;
453 
454  // true if the sample stayed on the same side of the surface as the
455  // perfect specular direction it was scattered around
456  return (perfectCos * hitNormal.dot(reflected->dir) > 0.0f);
457 }
void shininess(SLfloat shin)
Definition: SLMaterial.h:177
T dot(const SLVec3 &v) const
Definition: SLVec3.h:117

◆ refract()

void SLRay::refract ( SLRay refracted)

SLRay::refract calculates a secondary refracted ray, starting at the intersection point. All vectors must be normalized vectors, so the refracted vector T will be a unit vector too. If total internal refraction occurs a reflected ray is calculated instead. Index of refraction eta = Kn_Source/Kn_Destination (Kn_Air = 1.0) We are using a formula by Xavier Bec that is a little faster: http://www.realtimerendering.com/resources/RTNews/html/rtnv10n1.html#art3

Definition at line 218 of file SLRay.cpp.

219 {
220  assert(hitMesh && "hitMesh is null");
221 
222  SLVec3f T; // refracted direction
223  SLfloat eta; // refraction coefficient
224 
225  SLfloat c1 = hitNormal.dot(-dir);
226  SLbool hitFrontSide = c1 > 0.0f;
227 
228  SLMaterial* srcMat = srcMesh ? srcMesh->mat() : nullptr;
229  SLMaterial* hitMat = hitMesh ? hitMesh->mat() : nullptr;
230  SLMaterial* hitMatOut = hitMesh ? hitMesh->matOut() : nullptr;
231 
232 #ifdef DEBUG_RAY
233  for (SLint i = 0; i < depth; ++i)
234  cout << " ";
235  cout << "Refract: ";
236 #endif
237 
238  // Calculate index of refraction eta = Kn_Source/Kn_Destination
239  // Case 1: From air into a mesh
240  if (isOutside)
241  {
242  eta = 1.0f / hitMat->kn();
243  }
244  else
245  { // Case 2: From inside the same mesh
246  if (hitMesh == srcMesh)
247  {
248  if (hitMatOut) // Case 2a: into another material
249  eta = hitMat->kn() / hitMatOut->kn();
250  else // Case 2b: into air
251  eta = hitMat->kn(); // = hitMat / 1.0
252  }
253  else
254  { // Case 3: We hit inside another material from the front
255  if (hitFrontSide)
256  {
257  if (hitMatOut)
258  eta = hitMatOut->kn() / hitMat->kn();
259  else
260  { // Mesh hit without outside material before leaving another mesh.
261  // This should not happen, but can due to float inaccuracies
262  eta = srcMat->kn() / hitMat->kn();
263  }
264  }
265  else // Case 4: We hit inside another material from behind
266  {
267  if (hitMatOut) // Case 4a: into another material
268  eta = hitMat->kn() / hitMatOut->kn();
269  else // Case 4b: into air
270  eta = hitMat->kn(); // = hitMat / 1.0
271  }
272  }
273  }
274 
275  // Invert the hit normal if ray hit backside for correct refraction
276  if (!hitFrontSide)
277  {
278  c1 *= -1.0f;
279  hitNormal *= -1.0f;
280  }
281 
282  SLfloat w = eta * c1;
283  SLfloat c2 = 1.0f + (w - eta) * (w + eta);
284 
285  if (c2 >= 0.0f)
286  {
287  T = eta * dir + (w - sqrt(c2)) * hitNormal;
288  refracted->contrib = contrib * hitMat->kt();
289  refracted->type = REFRACTED;
290 
291  if (isOutside)
292  refracted->isOutside = false;
293  else // inside
294  {
295  if (srcMesh == hitMesh)
296  refracted->isOutside = !hitMatOut;
297  else
298  refracted->isOutside = !hitFrontSide;
299  }
300 
301  ++refractedRays;
302  }
303  else // total internal refraction results in a internal reflected ray
304  {
305  T = 2.0f * (-dir * hitNormal) * hitNormal + dir;
306  refracted->contrib = 1.0f;
307  refracted->type = REFLECTED;
308  refracted->isOutside = isOutside; // remain inside
309  ++tirRays;
310  }
311 
312  refracted->setDir(T);
313  refracted->origin.set(hitPoint);
314  refracted->length = FLT_MAX;
315  refracted->srcNode = hitNode;
316  refracted->srcMesh = hitMesh;
317  refracted->srcTriangle = hitTriangle;
318  refracted->depth = depth + 1;
319  refracted->x = x;
320  refracted->y = y;
321  refracted->sv = sv;
322  if (sv->s()->skybox())
323  refracted->backgroundColor = sv->s()->skybox()->colorAtDir(refracted->dir);
324  else
325  refracted->backgroundColor = backgroundColor;
326  depthReached = refracted->depth;
327 
328 #ifdef DEBUG_RAY
329  cout << hitMesh->name();
330  if (isOutside)
331  cout << ",out";
332  else
333  cout << ",in";
334  if (refracted->isOutside)
335  cout << ">out";
336  else
337  cout << ">in";
338  cout << ", dir: " << refracted->dir.toString();
339  cout << ", contrib: " << Utils::toString(refracted->contrib, 2);
340  cout << endl;
341 #endif
342 }
bool SLbool
analog to GLbool
Definition: SL.h:202
@ REFRACTED
Definition: SLRay.h:25
void kt(SLfloat kt)
Definition: SLMaterial.h:190
void kn(SLfloat kn)
Definition: SLMaterial.h:199
SLMaterial * matOut() const
Definition: SLMesh.h:178
static SLuint tirRays
NO. of TIR refraction rays.
Definition: SLRay.h:134
static SLuint refractedRays
NO. of refracted rays.
Definition: SLRay.h:131
SLstring toString(SLstring delimiter=", ", int decimals=2)
Conversion to string.
Definition: SLVec3.h:199
string toString(float f, int roundedDecimals)
Returns a string from a float with max. one trailing zero.
Definition: Utils.cpp:92

◆ refractMC()

bool SLRay::refractMC ( SLRay refracted,
const SLMat3f rotMat 
) const

SLRay::refractMC scatters a ray around perfect transmissive direction according to translucency (for higher translucency the ray is less scattered). This is used for path tracing and distributed ray tracing as well as for photon scattering. The direction is calculated the same as with specular scattering (see reflectMC). The created direction is along z-axis and then transformed to lie along transmissive direction with rotationMatrix rotMat, which SLRay::lobeToWorld builds from the perfect transmissive direction. The rotation matrix must be precalculated (stays the same for each ray sample, needs to be calculated only once).

refracted->dir must hold the perfect transmissive direction on entry, i.e. the caller must have run SLRay::refract first.

Returns
false if the sample landed on the near side of the surface, for the same reason as in reflectMC. Testing against the sign of the perfect direction rather than against the normal is what makes this work for total internal reflection too, where SLRay::refract returns a direction on the incident side.

Definition at line 478 of file SLRay.cpp.

479 {
480  SLfloat eta1, eta2;
481  SLVec3f randVec;
482  SLfloat translucency = hitMesh->mat()->translucency();
483 
484  // The side of the surface the perfect transmissive direction leaves on
485  SLfloat perfectCos = hitNormal.dot(refracted->dir);
486 
487  // scatter within transmissive lobe
488  eta1 = rnd01();
489  eta2 = Utils::TWOPI * rnd01();
490  SLfloat f1 = sqrt(1.0f - pow(eta1, 2.0f / (translucency + 1.0f)));
491 
492  // transform to cartesian
493  randVec.set(f1 * cos(eta2),
494  f1 * sin(eta2),
495  pow(eta1, 1.0f / (translucency + 1.0f)));
496 
497  // ray needs to be reset if already hit a scene node
498  if (refracted->hitNode)
499  {
500  refracted->length = FLT_MAX;
501  refracted->hitNode = nullptr;
502  refracted->hitMesh = nullptr;
503  refracted->hitPoint = SLVec3f::ZERO;
504  refracted->hitNormal = SLVec3f::ZERO;
505  }
506 
507  // Apply rotation
508  refracted->setDir(rotMat * randVec);
509 
510  // Set pixel and background
511  refracted->x = x;
512  refracted->y = y;
513  refracted->sv = sv;
514  if (sv->s()->skybox())
515  refracted->backgroundColor = sv->s()->skybox()->colorAtDir(refracted->dir);
516  else
517  refracted->backgroundColor = backgroundColor;
518 
519  // true if the sample stayed on the same side of the surface as the
520  // perfect transmissive direction it was scattered around
521  return (perfectCos * hitNormal.dot(refracted->dir) > 0.0f);
522 }
void translucency(SLfloat transl)
Definition: SLMaterial.h:176

◆ setDir()

void SLRay::setDir ( const SLVec3f Dir)
inline

Setter for the rays direction in world space also setting the inverse direction.

Definition at line 149 of file SLRay.h.

150 {
151  dir = Dir;
152  invDir.x = (SLfloat)(1 / dir.x);
153  invDir.y = (SLfloat)(1 / dir.y);
154  invDir.z = (SLfloat)(1 / dir.z);
155  sign[0] = (invDir.x < 0);
156  sign[1] = (invDir.y < 0);
157  sign[2] = (invDir.z < 0);
158 }
SLVec3f invDir
Inverse ray dir for fast AABB hit in WS.
Definition: SLRay.h:119

◆ setDirOS()

void SLRay::setDirOS ( const SLVec3f Dir)
inline

Setter for the rays direction in object space also setting the inverse direction.

Definition at line 162 of file SLRay.h.

163 {
164  dirOS = Dir;
165  invDirOS.x = (SLfloat)(1 / dirOS.x);
166  invDirOS.y = (SLfloat)(1 / dirOS.y);
167  invDirOS.z = (SLfloat)(1 / dirOS.z);
168  signOS[0] = (invDirOS.x < 0);
169  signOS[1] = (invDirOS.y < 0);
170  signOS[2] = (invDirOS.z < 0);
171 }
SLint signOS[3]
Sign of invDir for fast AABB hit in OS.
Definition: SLRay.h:122
SLVec3f invDirOS
Inverse ray dir for fast AABB hit in OS.
Definition: SLRay.h:120
SLVec3f dirOS
Direction vector of ray in OS.
Definition: SLRay.h:84

◆ totalNumRays()

static SLuint SLRay::totalNumRays ( )
inlinestatic

Total NO. of rays shot during RT.

Definition at line 87 of file SLRay.h.

87  { return SLRay::primaryRays +
static SLuint primaryRays
NO. of primary rays shot.
Definition: SLRay.h:129
static SLuint subsampledRays
NO. of of subsampled rays.
Definition: SLRay.h:140

Member Data Documentation

◆ avgDepth

SLfloat SLRay::avgDepth = 0
static

average depth reached

Definition at line 139 of file SLRay.h.

◆ backgroundColor

SLCol4f SLRay::backgroundColor

Background color at pixel x,y.

Definition at line 103 of file SLRay.h.

◆ contrib

SLfloat SLRay::contrib

Current contribution of ray to color.

Definition at line 82 of file SLRay.h.

◆ depth

SLint SLRay::depth

Recursion depth for ray tracing.

Definition at line 81 of file SLRay.h.

◆ depthReached

SLint SLRay::depthReached = 1
static

depth reached for a primary ray

Definition at line 137 of file SLRay.h.

◆ dir

SLVec3f SLRay::dir

Direction vector of ray in WS.

Definition at line 79 of file SLRay.h.

◆ dirOS

SLVec3f SLRay::dirOS

Direction vector of ray in OS.

Definition at line 84 of file SLRay.h.

◆ hitAO

SLfloat SLRay::hitAO

Ambient occlusion factor at intersection point.

Definition at line 116 of file SLRay.h.

◆ hitMesh

SLMesh* SLRay::hitMesh

Points to the intersected mesh.

Definition at line 109 of file SLRay.h.

◆ hitNode

SLNode* SLRay::hitNode

Points to the intersected node.

Definition at line 108 of file SLRay.h.

◆ hitNormal

SLVec3f SLRay::hitNormal

Surface normal at intersection point.

Definition at line 114 of file SLRay.h.

◆ hitPoint

SLVec3f SLRay::hitPoint

Point of intersection.

Definition at line 113 of file SLRay.h.

◆ hitTexColor

SLCol4f SLRay::hitTexColor

Color at intersection for texture or color attributes.

Definition at line 115 of file SLRay.h.

◆ hitTriangle

SLint SLRay::hitTriangle

Points to the intersected triangle.

Definition at line 110 of file SLRay.h.

◆ hitU

SLfloat SLRay::hitU

Definition at line 107 of file SLRay.h.

◆ hitV

SLfloat SLRay::hitV

barycentric coords in hit triangle

Definition at line 107 of file SLRay.h.

◆ ignoredRays

SLuint SLRay::ignoredRays = 0
static

NO. of ignore refraction rays.

Definition at line 132 of file SLRay.h.

◆ intersections

SLuint SLRay::intersections = 0
static

NO. of intersection.

Definition at line 136 of file SLRay.h.

◆ invDir

SLVec3f SLRay::invDir

Inverse ray dir for fast AABB hit in WS.

Definition at line 119 of file SLRay.h.

◆ invDirOS

SLVec3f SLRay::invDirOS

Inverse ray dir for fast AABB hit in OS.

Definition at line 120 of file SLRay.h.

◆ isInsideVolume

SLbool SLRay::isInsideVolume

Flag if ray is in Volume.

Definition at line 99 of file SLRay.h.

◆ isOutside

SLbool SLRay::isOutside

Flag if ray is inside of a material.

Definition at line 98 of file SLRay.h.

◆ length

SLfloat SLRay::length

length from origin to an intersection

Definition at line 80 of file SLRay.h.

◆ lightDist

SLfloat SLRay::lightDist

Distance to light for shadow rays.

Definition at line 96 of file SLRay.h.

◆ maxDepth

SLint SLRay::maxDepth = 0
static

Max. recursion depth.

Definition at line 127 of file SLRay.h.

◆ maxDepthReached

SLint SLRay::maxDepthReached = 0
static

max. depth reached for all rays

Definition at line 138 of file SLRay.h.

◆ minContrib

SLfloat SLRay::minContrib = 1.0 / 256.0
static

Min. contibution to color (1/256)

Definition at line 128 of file SLRay.h.

◆ origin

SLVec3f SLRay::origin

Vector to the origin of ray in WS.

Definition at line 78 of file SLRay.h.

◆ originOS

SLVec3f SLRay::originOS

Vector to the origin of ray in OS.

Definition at line 83 of file SLRay.h.

◆ primaryRays

SLuint SLRay::primaryRays = 0
static

NO. of primary rays shot.

Definition at line 129 of file SLRay.h.

◆ reflectedRays

SLuint SLRay::reflectedRays = 0
static

NO. of reflected rays.

Definition at line 130 of file SLRay.h.

◆ refractedRays

SLuint SLRay::refractedRays = 0
static

NO. of refracted rays.

Definition at line 131 of file SLRay.h.

◆ shadowRays

SLuint SLRay::shadowRays = 0
static

NO. of shadow rays.

Definition at line 133 of file SLRay.h.

◆ sign

SLint SLRay::sign[3]

Sign of invDir for fast AABB hit in WS.

Definition at line 121 of file SLRay.h.

◆ signOS

SLint SLRay::signOS[3]

Sign of invDir for fast AABB hit in OS.

Definition at line 122 of file SLRay.h.

◆ srcMesh

SLMesh* SLRay::srcMesh

Points to the mesh at ray origin.

Definition at line 101 of file SLRay.h.

◆ srcNode

SLNode* SLRay::srcNode

Points to the node at ray origin.

Definition at line 100 of file SLRay.h.

◆ srcTriangle

SLint SLRay::srcTriangle

Points to the triangle at ray origin.

Definition at line 102 of file SLRay.h.

◆ subsampledPixels

SLuint SLRay::subsampledPixels = 0
static

NO. of of subsampled pixels.

Definition at line 141 of file SLRay.h.

◆ subsampledRays

SLuint SLRay::subsampledRays = 0
static

NO. of of subsampled rays.

Definition at line 140 of file SLRay.h.

◆ sv

SLSceneView* SLRay::sv

Pointer to the sceneview.

Definition at line 104 of file SLRay.h.

◆ tests

SLuint SLRay::tests = 0
static

NO. of intersection tests.

Definition at line 135 of file SLRay.h.

◆ tirRays

SLuint SLRay::tirRays = 0
static

NO. of TIR refraction rays.

Definition at line 134 of file SLRay.h.

◆ tmax

SLfloat SLRay::tmax

max. dist. of last AABB intersection

Definition at line 124 of file SLRay.h.

◆ tmin

SLfloat SLRay::tmin

min. dist. of last AABB intersection

Definition at line 123 of file SLRay.h.

◆ type

SLRayType SLRay::type

PRIMARY, REFLECTED, REFRACTED, SHADOW.

Definition at line 95 of file SLRay.h.

◆ x

SLfloat SLRay::x

Definition at line 97 of file SLRay.h.

◆ y

SLfloat SLRay::y

Pixel position for primary rays.

Definition at line 97 of file SLRay.h.


The documentation for this class was generated from the following files: