11 using namespace std::placeholders;
24 name(
"myCoolRaytracer");
28 _doDistributed =
true;
29 _doContinuous =
false;
34 _resolutionFactor = 0.5f;
44 _raysPerMS.init(1, 0.0f);
47 _min_filter = GL_NEAREST;
48 _mag_filter = GL_NEAREST;
49 _wrap_s = GL_CLAMP_TO_EDGE;
50 _wrap_t = GL_CLAMP_TO_EDGE;
51 _resizeToPow2 =
false;
56 SL_LOG(
"Destructor : ~SLRaytracer");
80 for (
SLuint y = 0; y < _images[0]->height(); ++y)
82 for (
SLuint x = 0; x < _images[0]->width(); ++x)
84 SLRay primaryRay(_sv);
88 SLCol4f color = trace(&primaryRay);
93 _images[0]->setPixeliRGB((
SLint)x,
110 renderUIBeforeUpdate();
125 printStats(_renderSec);
142 initStats(_maxDepth);
149 sampleAAPixelsAsync = [
this](
bool isMainThread,
SLuint threadNum)
151 sampleAAPixels(isMainThread, threadNum);
155 if (_cam->lensSamples()->samples() == 1)
157 renderSlicesAsync = [
this](
bool isMainThread,
SLuint threadNum)
159 renderSlices(isMainThread, threadNum);
164 renderSlicesAsync = [
this](
bool isMainThread,
SLuint threadNum)
166 renderSlicesMS(isMainThread, threadNum);
172 vector<thread> threads1;
177 threads1.emplace_back(renderSlicesAsync,
false, t);
180 renderSlicesAsync(
true, 0);
183 for (
auto& thread : threads1)
187 if (_aaSamples > 1 && _cam->lensSamples()->samples() == 1)
192 vector<thread> threads2;
197 threads2.emplace_back(sampleAAPixelsAsync,
false, t);
200 sampleAAPixelsAsync(
true, 0);
203 for (
auto& thread : threads2)
216 printStats(_renderSec);
241 while (_nextLine < (
SLint)_images[0]->height())
246 SLint minY = _nextLine;
250 for (
SLint y = minY; y < minY + 4; ++y)
252 for (
SLuint x = 0; x < _images[0]->width(); ++x)
254 SLRay primaryRay(_sv);
258 SLCol4f color = trace(&primaryRay);
264 _images[0]->setPixeliRGB((
SLint)x,
278 if (_sv->onWndUpdate && isMainThread && !_doContinuous)
283 (
SLfloat)_images[0]->height() * 100);
284 if (_aaSamples > 0) _progressPC /= 2;
285 renderUIBeforeUpdate();
316 SLVec3f lensRadiusX = _lr * (_cam->lensDiameter() * 0.5f);
317 SLVec3f lensRadiusY = _lu * (_cam->lensDiameter() * 0.5f);
319 while (_nextLine < (
SLint)_images[0]->width())
324 SLint minY = _nextLine;
328 for (
SLint y = minY; y < minY + 4; ++y)
330 for (
SLuint x = 0; x < _images[0]->width(); ++x)
334 SLVec3f FP = _eye + primaryDir;
338 for (
SLint iR = (
SLint)_cam->lensSamples()->samplesX() - 1; iR >= 0; --iR)
340 for (
SLint iPhi = (
SLint)_cam->lensSamples()->samplesY() - 1; iPhi >= 0; --iPhi)
345 SLVec3f lensPos(_eye + discPos.
x * lensRadiusX + discPos.
y * lensRadiusY);
346 SLVec3f lensToFP(FP - lensPos);
350 if (_sv->s()->skybox())
351 backColor = _sv->s()->skybox()->colorAtDir(lensToFP);
353 backColor = _sv->camera()->background().colorAtPos((
SLfloat)x,
356 (
SLfloat)_images[0]->height());
361 color += trace(&primaryRay);
369 color /= (
SLfloat)_cam->lensSamples()->samples();
374 _images[0]->setPixeliRGB((
SLint)x, y,
CVVec4f(color.
r, color.
g, color.
b, color.
a));
381 if (_sv->onWndUpdate && isMainThread && !_doContinuous)
385 renderUIBeforeUpdate();
406 SLNode* root = _sv->s()->root3D();
407 if (root) root->
hitRec(ray);
423 SLRay refracted(_sv);
425 color += kt * trace(&refracted);
429 SLRay reflected(_sv);
431 color += kr * trace(&reflected);
439 SLRay refracted(_sv), reflected(_sv);
442 SLCol4f refrCol = trace(&refracted);
443 SLCol4f reflCol = trace(&reflected);
449 color += refrCol * (1 - F_theta) + reflCol * F_theta;
455 SLRay reflected(_sv);
457 color += kr * trace(&reflected);
465 color = fogBlend(ray->
length, color);
476 primaryRay->
sv = _sv;
488 primaryRay->
setDir(primaryDir);
489 primaryRay->
origin = _eye;
492 if (_sv->s()->skybox())
495 primaryRay->
backgroundColor = _sv->camera()->background().colorAtPos(x,
498 (
SLfloat)_images[0]->height());
516 SLfloat lightDist, LdotN, NdotH, df, sf, spotEffect, att, lighted;
524 for (
auto* light :
s->
lights())
526 if (light && light->isOn())
532 SLVec4f lightPos = light->positionWS();
535 if (lightPos.
w == 0.0f)
553 lighted = (LdotN > 0) ? light->shadowTest(ray, L, lightDist,
s->
root3D()) : 0;
560 if (lighted > 0.0f && light->spotCutOffDEG() < 180.0f)
562 SLfloat LdS = std::max(-L.
dot(light->spotDirWS()), 0.0f);
565 if (LdS > light->spotCosCut())
566 spotEffect = pow(LdS, (
SLfloat)light->spotExponent());
581 df = std::max(LdotN, 0.0f);
582 NdotH = std::max(N.
dot(H), 0.0f);
585 diff += lighted * df * light->diffuse() & mat->
diffuse();
586 spec = lighted * sf * light->specular() & mat->
specular();
590 att = light->attenuation(lightDist);
591 localColor += att * ambi;
592 localColor += att * spotEffect * diff;
593 localSpec += att * spotEffect * spec;
597 if (!texture.empty() || !ray->
hitMesh->
C.empty())
600 localColor += localSpec;
603 localColor += localSpec;
615 SLCol4f color, colorLeft, colorUp;
617 gotSampled.resize(_images[0]->width());
621 for (
SLuint x = 0; x < _images[0]->width(); ++x)
622 gotSampled[x] =
false;
626 for (
SLuint y = 0; y < _images[0]->height(); ++y)
628 for (
SLuint x = 0; x < _images[0]->width(); ++x)
631 color.
set(c4f[0], c4f[1], c4f[2], c4f[3]);
633 isSubsampled =
false;
637 colorLeft.
set(colL[0], colL[1], colL[2], colL[3]);
638 if (color.
diffRGB(colorLeft) > _aaThreshold)
640 if (!gotSampled[x - 1])
643 gotSampled[x - 1] =
true;
652 colorUp.
set(colU[0], colU[1], colU[2], colU[3]);
653 if (color.
diffRGB(colorUp) > _aaThreshold)
664 gotSampled[x] = isSubsampled;
688 assert(_aaSamples % 2 == 1 &&
"subSample: maskSize must be uneven");
691 while (_nextLine < (
SLint)_aaPixels.size())
700 for (
SLuint i = mini; i < mini + 4 && i < _aaPixels.size(); ++i)
702 SLuint x = _aaPixels[i].x;
703 SLuint y = _aaPixels[i].y;
705 SLCol4f centerColor(c4f[0], c4f[1], c4f[2], c4f[3]);
706 SLint centerIndex = _aaSamples >> 1;
715 for (
SLint sy = 0; sy < _aaSamples; ++sy)
717 for (
SLint sx = 0; sx < _aaSamples; ++sx)
719 if (sx == centerIndex && sy == centerIndex)
720 color += centerColor;
723 SLRay primaryRay(_sv);
724 setPrimaryRay(xpos + (
SLfloat)sx * f,
727 color += trace(&primaryRay);
738 _images[0]->setPixeliRGB((
SLint)x,
747 if (_sv->onWndUpdate && isMainThread && !_doContinuous)
753 renderUIBeforeUpdate();
769 if (z > _sv->_camera->clipFar())
770 z = _sv->_camera->clipFar();
772 switch (_cam->fogMode())
775 f = (_cam->fogDistEnd() - z) /
776 (_cam->fogDistEnd() - _cam->fogDistStart());
779 f = exp(-_cam->fogDensity() * z);
782 f = exp(-_cam->fogDensity() * z * _cam->fogDensity() * z);
785 color = f * color + (1 - f) * _cam->fogColor();
814 SL_LOG(
"\nRender time : %10.2f sec.", sec);
815 SL_LOG(
"Image size : %10d x %d", _images[0]->width(), _images[0]->height());
819 SLuint primarys = (
SLuint)(_sv->viewportRect().width * _sv->viewportRect().height);
828 SL_LOG(
"AA threshold : %10.1f", _aaThreshold);
829 SL_LOG(
"AA subsampling : %8dx%d\n", _aaSamples, _aaSamples);
831 SL_LOG(
"Primary rays : %10u, %4.1f%% of total", primarys, (
SLfloat)primarys / total * 100.0f);
838 SL_LOG(
"Total rays : %10u,100.0%%\n", total);
840 SL_LOG(
"Rays per second : %10u", (
SLuint)(total / sec));
859 _cam->updateAndGetVM().lookAt(&_eye, &_la, &_lu, &_lr);
868 SLVec3f pos(_cam->updateAndGetVM().translation());
870 SLfloat hw = hh * _sv->viewportWdivH();
873 _pxSize = hw * 2 / ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor));
875 _bl = _eye - hw * _lr - hh * _lu + _pxSize / 2 * _lr - _pxSize / 2 * _lu;
887 SLfloat hw = hh * _sv->viewportWdivH();
890 _pxSize = hw * 2 / ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor));
893 SLVec3f C = _la * _cam->focalDist();
894 _bl = C - hw * _lr - hh * _lu + _pxSize / 2 * _lr + _pxSize / 2 * _lu;
905 if ((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor) != (
SLint)_images[0]->width() ||
906 (
SLint)((
SLfloat)_sv->viewportH() * _resolutionFactor) != (
SLint)_images[0]->height())
911 glDeleteTextures(1, &_texID);
915 _vaoSprite.clearAttribs();
916 _images[0]->allocate((
SLint)((
SLfloat)_sv->viewportW() * _resolutionFactor),
920 _width = (
SLint)_images[0]->width();
921 _height = (
SLint)_images[0]->height();
922 _depth = (
SLint)_images.size();
926 if (!_doContinuous) _images[0]->fill(0, 0, 0);
936 SLRecti vpRect = _sv->viewportRect();
951 drawSprite(updateTextureGL, 0.0f, 0.0f, w, h);
964 "Raytraced_%d_%d.png",
967 _images[0]->savePNG(filename, 9,
true,
true);
978 _sv->gui()->onPaint(_sv->viewportRect());
#define PROFILE_SCOPE(name)
#define PROFILE_FUNCTION()
#define PROFILE_THREAD(name)
float SLfloat
analog to GLfloat
#define SL_LOG(...)
Some debugging and error handling macros.
unsigned int SLuint
analog to GLuint
char SLchar
analog to GLchar (char is signed [-128 ... 127]!)
bool SLbool
analog to GLbool
unsigned short SLushort
analog to GLushort
vector< SLbool > SLVbool
All 1D vectors begin with SLV*.
int SLsizei
analog to GLsizei
@ 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.
static SLint maxDepth
Max. recursion depth.
static SLuint shadowRays
NO. of shadow rays.
static SLuint tirRays
NO. of TIR refraction rays.
SLVec3f origin
Vector to the origin of ray in WS.
static SLuint primaryRays
NO. of primary rays shot.
static SLuint intersections
NO. of intersection.
SLCol4f backgroundColor
Background color at pixel x,y.
static SLint depthReached
depth reached for a primary ray
static SLfloat minContrib
Min. contibution to color (1/256)
SLMesh * hitMesh
Points to the intersected mesh.
static SLint maxDepthReached
max. depth reached for all 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)
SLfloat length
length from origin to an intersection
static SLuint ignoredRays
NO. of ignore refraction rays.
SLfloat contrib
Current contribution of ray to color.
SLVec3f hitPoint
Point of intersection.
static SLuint subsampledPixels
NO. of of subsampled pixels.
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 SLuint tests
NO. of intersection tests.
void reflect(SLRay *reflected) const
static SLuint reflectedRays
NO. of reflected rays.
SLCol4f hitTexColor
Color at intersection for texture or color attributes.
SLfloat y
Pixel position for primary rays.
SLVec3f hitNormal
Surface normal at intersection point.
SLSceneView * sv
Pointer to the sceneview.
static SLfloat avgDepth
average depth reached
static SLuint refractedRays
NO. of refracted rays.
static SLuint subsampledRays
NO. of of subsampled rays.
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.