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.