11 using namespace std::placeholders;
 
   24     name(
"myCoolRaytracer");
 
   28     _doDistributed    = 
true;
 
   29     _doContinuous     = 
false;
 
   34     _resolutionFactor = 0.5f;
 
   36     _raysPerMS.init(60, 0.0f);
 
   39     _min_filter   = GL_NEAREST;
 
   40     _mag_filter   = GL_NEAREST;
 
   41     _wrap_s       = GL_CLAMP_TO_EDGE;
 
   42     _wrap_t       = GL_CLAMP_TO_EDGE;
 
   43     _resizeToPow2 = 
false;
 
   48     SL_LOG(
"Destructor       : ~SLRaytracer");
 
   72     for (
SLuint y = 0; y < _images[0]->height(); ++y)
 
   74         for (
SLuint x = 0; x < _images[0]->width(); ++x)
 
   76             SLRay primaryRay(_sv);
 
   80             SLCol4f color = trace(&primaryRay);
 
   85             _images[0]->setPixeliRGB((
SLint)x,
 
  102             renderUIBeforeUpdate();
 
  117         printStats(_renderSec);
 
  134     initStats(_maxDepth); 
 
  141     sampleAAPixelsAsync = [
this](
bool isMainThread, 
SLuint threadNum)
 
  143         sampleAAPixels(isMainThread, threadNum);
 
  147     if (_cam->lensSamples()->samples() == 1)
 
  149         renderSlicesAsync = [
this](
bool isMainThread, 
SLuint threadNum)
 
  151             renderSlices(isMainThread, threadNum);
 
  156         renderSlicesAsync = [
this](
bool isMainThread, 
SLuint threadNum)
 
  158             renderSlicesMS(isMainThread, threadNum);
 
  164     vector<thread> threads1; 
 
  169         threads1.emplace_back(renderSlicesAsync, 
false, t);
 
  172     renderSlicesAsync(
true, 0);
 
  175     for (
auto& thread : threads1)
 
  179     if (_aaSamples > 1 && _cam->lensSamples()->samples() == 1)
 
  184         vector<thread> threads2; 
 
  189             threads2.emplace_back(sampleAAPixelsAsync, 
false, t);
 
  192         sampleAAPixelsAsync(
true, 0);
 
  195         for (
auto& thread : threads2)
 
  208         printStats(_renderSec);
 
  233     while (_nextLine < (
SLint)_images[0]->height())
 
  238         SLint minY = _nextLine;
 
  242         for (
SLint y = minY; y < minY + 4; ++y)
 
  244             for (
SLuint x = 0; x < _images[0]->width(); ++x)
 
  246                 SLRay primaryRay(_sv);
 
  250                 SLCol4f color = trace(&primaryRay);
 
  256                 _images[0]->setPixeliRGB((
SLint)x,
 
  270             if (_sv->onWndUpdate && isMainThread && !_doContinuous)
 
  275                                           (
SLfloat)_images[0]->height() * 100);
 
  276                     if (_aaSamples > 0) _progressPC /= 2;
 
  277                     renderUIBeforeUpdate();
 
  308     SLVec3f lensRadiusX = _lr * (_cam->lensDiameter() * 0.5f);
 
  309     SLVec3f lensRadiusY = _lu * (_cam->lensDiameter() * 0.5f);
 
  311     while (_nextLine < (
SLint)_images[0]->width())
 
  316         SLint minY = _nextLine;
 
  320         for (
SLint y = minY; y < minY + 4; ++y)
 
  322             for (
SLuint x = 0; x < _images[0]->width(); ++x)
 
  326                 SLVec3f FP = _eye + primaryDir;
 
  330                 for (
SLint iR = (
SLint)_cam->lensSamples()->samplesX() - 1; iR >= 0; --iR)
 
  332                     for (
SLint iPhi = (
SLint)_cam->lensSamples()->samplesY() - 1; iPhi >= 0; --iPhi)
 
  337                         SLVec3f lensPos(_eye + discPos.
x * lensRadiusX + discPos.
y * lensRadiusY);
 
  338                         SLVec3f lensToFP(FP - lensPos);
 
  342                         if (_sv->s()->skybox())
 
  343                             backColor = _sv->s()->skybox()->colorAtDir(lensToFP);
 
  345                             backColor = _sv->camera()->background().colorAtPos((
SLfloat)x,
 
  348                                                                                (
SLfloat)_images[0]->height());
 
  353                         color += trace(&primaryRay);
 
  361                 color /= (
SLfloat)_cam->lensSamples()->samples();
 
  366                 _images[0]->setPixeliRGB((
SLint)x, y, 
CVVec4f(color.
r, color.
g, color.
b, color.
a));
 
  373             if (_sv->onWndUpdate && isMainThread && !_doContinuous)
 
  377                     renderUIBeforeUpdate();
 
  398     SLNode* root = _sv->s()->root3D();
 
  399     if (root) root->
hitRec(ray);
 
  415                     SLRay refracted(_sv);
 
  417                     color += kt * trace(&refracted);
 
  421                     SLRay reflected(_sv);
 
  423                     color += kr * trace(&reflected);
 
  431                     SLRay refracted(_sv), reflected(_sv);
 
  434                     SLCol4f refrCol = trace(&refracted);
 
  435                     SLCol4f reflCol = trace(&reflected);
 
  441                     color += refrCol * (1 - F_theta) + reflCol * F_theta;
 
  447                         SLRay reflected(_sv);
 
  449                         color += kr * trace(&reflected);
 
  457         color = fogBlend(ray->
length, color);
 
  468     primaryRay->
sv = _sv;
 
  480         primaryRay->
setDir(primaryDir);
 
  481         primaryRay->
origin = _eye;
 
  484     if (_sv->s()->skybox())
 
  487         primaryRay->
backgroundColor = _sv->camera()->background().colorAtPos(x,
 
  490                                                                              (
SLfloat)_images[0]->height());
 
  508     SLfloat       lightDist, LdotN, NdotH, df, sf, spotEffect, att, lighted;
 
  516     for (
auto* light : 
s->
lights())
 
  518         if (light && light->isOn())
 
  524             SLVec4f lightPos = light->positionWS();
 
  527             if (lightPos.
w == 0.0f)
 
  545             lighted = (LdotN > 0) ? light->shadowTest(ray, L, lightDist, 
s->
root3D()) : 0;
 
  552             if (lighted > 0.0f && light->spotCutOffDEG() < 180.0f)
 
  554                 SLfloat LdS = std::max(-L.
dot(light->spotDirWS()), 0.0f);
 
  557                 if (LdS > light->spotCosCut())
 
  558                     spotEffect = pow(LdS, (
SLfloat)light->spotExponent());
 
  573                 df    = std::max(LdotN, 0.0f); 
 
  574                 NdotH = std::max(N.
dot(H), 0.0f);
 
  577                 diff += lighted * df * light->diffuse() & mat->
diffuse();
 
  578                 spec = lighted * sf * light->specular() & mat->
specular();
 
  582             att = light->attenuation(lightDist);
 
  583             localColor += att * ambi;
 
  584             localColor += att * spotEffect * diff;
 
  585             localSpec += att * spotEffect * spec;
 
  589     if (!texture.empty() || !ray->
hitMesh->
C.empty())
 
  592         localColor += localSpec;        
 
  595         localColor += localSpec;
 
  607     SLCol4f color, colorLeft, colorUp; 
 
  609     gotSampled.resize(_images[0]->width()); 
 
  613     for (
SLuint x = 0; x < _images[0]->width(); ++x)
 
  614         gotSampled[x] = 
false;
 
  618     for (
SLuint y = 0; y < _images[0]->height(); ++y)
 
  620         for (
SLuint x = 0; x < _images[0]->width(); ++x)
 
  623             color.
set(c4f[0], c4f[1], c4f[2], c4f[3]);
 
  625             isSubsampled = 
false;
 
  629                 colorLeft.
set(colL[0], colL[1], colL[2], colL[3]);
 
  630                 if (color.
diffRGB(colorLeft) > _aaThreshold)
 
  632                     if (!gotSampled[x - 1])
 
  635                         gotSampled[x - 1] = 
true;
 
  644                 colorUp.
set(colU[0], colU[1], colU[2], colU[3]);
 
  645                 if (color.
diffRGB(colorUp) > _aaThreshold)
 
  656             gotSampled[x] = isSubsampled;
 
  680     assert(_aaSamples % 2 == 1 && 
"subSample: maskSize must be uneven");
 
  683     while (_nextLine < (
SLint)_aaPixels.size())
 
  692         for (
SLuint i = mini; i < mini + 4 && i < _aaPixels.size(); ++i)
 
  694             SLuint  x   = _aaPixels[i].x;
 
  695             SLuint  y   = _aaPixels[i].y;
 
  697             SLCol4f centerColor(c4f[0], c4f[1], c4f[2], c4f[3]);
 
  698             SLint   centerIndex = _aaSamples >> 1;
 
  707             for (
SLint sy = 0; sy < _aaSamples; ++sy)
 
  709                 for (
SLint sx = 0; sx < _aaSamples; ++sx)
 
  711                     if (sx == centerIndex && sy == centerIndex)
 
  712                         color += centerColor; 
 
  715                         SLRay primaryRay(_sv);
 
  716                         setPrimaryRay(xpos + (
SLfloat)sx * f,
 
  719                         color += trace(&primaryRay);
 
  730             _images[0]->setPixeliRGB((
SLint)x,
 
  739         if (_sv->onWndUpdate && isMainThread && !_doContinuous)
 
  745                 renderUIBeforeUpdate();
 
  761     if (z > _sv->_camera->clipFar())
 
  762         z = _sv->_camera->clipFar();
 
  764     switch (_cam->fogMode())
 
  767             f = (_cam->fogDistEnd() - z) /
 
  768                 (_cam->fogDistEnd() - _cam->fogDistStart());
 
  771             f = exp(-_cam->fogDensity() * z);
 
  774             f = exp(-_cam->fogDensity() * z * _cam->fogDensity() * z);
 
  777     color = f * color + (1 - f) * _cam->fogColor();
 
  806     SL_LOG(
"\nRender time       : %10.2f sec.", sec);
 
  807     SL_LOG(
"Image size        : %10d x %d", _images[0]->width(), _images[0]->height());
 
  811     SLuint primarys = (
SLuint)(_sv->viewportRect().width * _sv->viewportRect().height);
 
  820     SL_LOG(
"AA threshold      : %10.1f", _aaThreshold);
 
  821     SL_LOG(
"AA subsampling    : %8dx%d\n", _aaSamples, _aaSamples);
 
  823     SL_LOG(
"Primary rays      : %10u, %4.1f%% of total", primarys, (
SLfloat)primarys / total * 100.0f);
 
  830     SL_LOG(
"Total rays        : %10u,100.0%%\n", total);
 
  832     SL_LOG(
"Rays per second   : %10u", (
SLuint)(total / sec));
 
  851     _cam->updateAndGetVM().lookAt(&_eye, &_la, &_lu, &_lr);
 
  860         SLVec3f pos(_cam->updateAndGetVM().translation());
 
  862         SLfloat hw = hh * _sv->viewportWdivH();
 
  865         _pxSize = hw * 2 / ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor));
 
  867         _bl = _eye - hw * _lr - hh * _lu + _pxSize / 2 * _lr - _pxSize / 2 * _lu;
 
  879         SLfloat hw = hh * _sv->viewportWdivH();
 
  882         _pxSize = hw * 2 / ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor));
 
  885         SLVec3f C = _la * _cam->focalDist();
 
  886         _bl       = C - hw * _lr - hh * _lu + _pxSize / 2 * _lr + _pxSize / 2 * _lu;
 
  897     if ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor) != (
SLint)_images[0]->width() ||
 
  898         (
SLint)((
SLfloat)_sv->viewportH() * _resolutionFactor) != (
SLint)_images[0]->height())
 
  903             glDeleteTextures(1, &_texID);
 
  907         _vaoSprite.clearAttribs();
 
  908         _images[0]->allocate((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor),
 
  912         _width  = (
SLint)_images[0]->width();
 
  913         _height = (
SLint)_images[0]->height();
 
  914         _depth  = (
SLint)_images.size();
 
  918     if (!_doContinuous) _images[0]->fill(0, 0, 0);
 
  928     SLRecti vpRect = _sv->viewportRect();
 
  943     drawSprite(updateTextureGL, 0.0f, 0.0f, w, h);
 
  956              "Raytraced_%d_%d.png",
 
  959     _images[0]->savePNG(filename, 9, 
true, 
true);
 
  970     _sv->gui()->onPaint(_sv->viewportRect());
 
#define PROFILE_SCOPE(name)
 
#define PROFILE_FUNCTION()
 
#define PROFILE_THREAD(name)
 
@ P_monoOrthographic
standard mono orthographic projection
 
vector< SLGLTexture * > SLVGLTexture
STL vector of SLGLTexture pointers.
 
#define SL_MAXTRACE
Ray tracing constant for max. allowed recursion depth.
 
OpenCV image class with the same interface as the former SLImage class.
 
Singleton class holding all OpenGL states.
 
SLMat4f modelMatrix
Init all states.
 
void viewport(SLint x, SLint y, SLsizei width, SLsizei height)
 
void multiSample(SLbool state)
 
static SLGLState * instance()
Public static instance getter for singleton pattern.
 
SLMat4f viewMatrix
matrix for the active cameras view transform
 
void unbindAnythingAndFlush()
finishes all GL commands
 
SLMat4f projectionMatrix
matrix for projection transform
 
void polygonLine(SLbool state)
 
void depthTest(SLbool state)
 
static SLCol4f globalAmbient
static global ambient light intensity
 
void ortho(T l, T r, T b, T t, T n, T f)
Defines a orthographic projection matrix with a field of view angle.
 
void identity()
Sets the identity matrix.
 
Defines a standard CG material with textures and a shader program.
 
void specular(const SLCol4f &spec)
 
void diffuse(const SLCol4f &diff)
 
void shininess(SLfloat shin)
 
void ambient(const SLCol4f &ambi)
 
SLVGLTexture & textures(SLTextureType type)
 
void emissive(const SLCol4f &emis)
 
SLGLPrimitiveType primitive() const
 
SLVCol4f C
Vector of vertex colors (opt.) layout (location = 4)
 
virtual void preShade(SLRay *ray)
 
SLNode represents a node in a hierarchical scene graph.
 
virtual bool hitRec(SLRay *ray)
 
Ray class with ray and intersection properties.
 
SLVec3f origin
Vector to the origin of ray in WS.
 
static SLint depthReached
depth reached for a primary ray
 
static SLuint intersections
NO. of intersection.
 
static SLuint primaryRays
NO. of primary rays shot.
 
static SLuint tirRays
NO. of TIR refraction rays.
 
SLCol4f backgroundColor
Background color at pixel x,y.
 
static SLuint tests
NO. of intersection tests.
 
SLMesh * hitMesh
Points to the intersected mesh.
 
static SLuint reflectedRays
NO. of reflected rays.
 
SLint depth
Recursion depth for ray tracing.
 
SLfloat hitAO
Ambient occlusion factor at intersection point.
 
SLVec3f dir
Direction vector of ray in WS.
 
void refract(SLRay *refracted)
 
static SLint maxDepthReached
max. depth reached for all rays
 
static SLuint refractedRays
NO. of refracted rays.
 
SLfloat length
length from origin to an intersection
 
static SLuint ignoredRays
NO. of ignore refraction rays.
 
SLfloat contrib
Current contribution of ray to color.
 
static SLuint subsampledPixels
NO. of of subsampled pixels.
 
SLVec3f hitPoint
Point of intersection.
 
static SLuint totalNumRays()
Total NO. of rays shot during RT.
 
void setDir(const SLVec3f &Dir)
Setter for the rays direction in world space also setting the inverse direction.
 
static SLfloat avgDepth
average depth reached
 
static SLfloat minContrib
Min. contibution to color (1/256)
 
void reflect(SLRay *reflected) const
 
static SLuint subsampledRays
NO. of of subsampled rays.
 
SLCol4f hitTexColor
Color at intersection for texture or color attributes.
 
SLfloat y
Pixel position for primary rays.
 
static SLuint shadowRays
NO. of shadow rays.
 
SLVec3f hitNormal
Surface normal at intersection point.
 
SLSceneView * sv
Pointer to the sceneview.
 
static SLint maxDepth
Max. recursion depth.
 
virtual void prepareImage()
 
SLbool renderClassic(SLSceneView *sv)
 
SLCol4f trace(SLRay *ray)
 
void renderSlices(bool isMainThread, SLuint threadNum)
 
SLCol4f fogBlend(SLfloat z, SLCol4f color)
 
virtual void printStats(SLfloat sec)
 
void renderSlicesMS(bool isMainThread, SLuint threadNum)
 
SLCol4f shade(SLRay *ray)
 
SLbool renderDistrib(SLSceneView *sv)
 
virtual void renderImage(bool updateTextureGL)
 
void renderUIBeforeUpdate()
Must be called before an inbetween frame updateRec.
 
void setPrimaryRay(SLfloat x, SLfloat y, SLRay *primaryRay)
Set the parameters of a primary ray for a pixel position at x, y.
 
virtual void initStats(SLint depth)
 
void sampleAAPixels(bool isMainThread, SLuint threadNum)
 
virtual void saveImage()
Saves the current RT image as PNG image.
 
The SLScene class represents the top level instance holding the scene structure.
 
void root3D(SLNode *root3D)
 
SceneView class represents a dynamic real time 3D view onto the scene.
 
SLVec3 normalized() const
 
void set(const T X, const T Y, const T Z)
 
T dot(const SLVec3 &v) const
 
void sub(const SLVec3 &a, const SLVec3 &b)
 
void set(const T X, const T Y, const T Z, const T W=1)
 
T diffRGB(const SLVec4 &v)
 
void gammaCorrect(T oneOverGamma)
Gamma correction.
 
void clampMinMax(const T min, const T max)
 
static const float DEG2RAD
 
unsigned int maxThreads()
Returns in release config the max. NO. of threads otherwise 1.
 
Pixel index struct used in anti aliasing in ray tracing.