![]() |
SLProject
4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
|
Classic Monte Carlo Pathtracing algorithm for real global illumination. More...
#include <SLPathtracer.h>
Public Member Functions | |
| SLPathtracer () | |
| ~SLPathtracer () | |
| SLbool | render (SLSceneView *sv) |
| void | renderSlices (bool isMainThread, SLint currentSample, SLuint threadNum) |
| SLCol4f | trace (SLRay *ray, SLfloat bsdfPdf) |
| Traces one ray. bsdfPdf is the solid angle density with which the. More... | |
| SLCol4f | shade (SLRay *ray, SLCol4f *mat) |
| void | saveImage () |
| Saves the current PT image as PNG image. More... | |
| void | computeNoise () |
| void | calcDirect (SLbool di) |
| void | calcIndirect (SLbool ii) |
| void | sampleClamp (SLfloat max) |
| SLbool | calcDirect () const |
| SLbool | calcIndirect () const |
| SLfloat | sampleClamp () const |
| SLfloat | noiseRSE () const |
| Mean relative standard error of the pixels of the last render. More... | |
| SLfloat | noiseRSE999 () const |
| Relative standard error of the noisiest 0.1% of the pixels. More... | |
| SLfloat | efficiency () const |
| Monte Carlo efficiency, the inverse of variance times time. More... | |
Public Member Functions inherited from SLRaytracer | |
| SLRaytracer () | |
| ~SLRaytracer () override | |
| SLbool | renderClassic (SLSceneView *sv) |
| SLbool | renderDistrib (SLSceneView *sv) |
| void | renderSlices (bool isMainThread, SLuint threadNum) |
| void | renderSlicesMS (bool isMainThread, SLuint threadNum) |
| SLCol4f | trace (SLRay *ray) |
| SLCol4f | shade (SLRay *ray) |
| void | sampleAAPixels (bool isMainThread, SLuint threadNum) |
| void | renderUIBeforeUpdate () |
| Must be called before an inbetween frame updateRec. More... | |
| void | setPrimaryRay (SLfloat x, SLfloat y, SLRay *primaryRay) |
| Set the parameters of a primary ray for a pixel position at x, y. More... | |
| void | getAAPixels () |
| SLCol4f | fogBlend (SLfloat z, SLCol4f color) |
| virtual void | printStats (SLfloat sec) |
| virtual void | initStats (SLint depth) |
| void | state (SLRTState state) |
| void | maxDepth (SLint depth) |
| void | resolutionFactor (SLfloat rf) |
| void | doDistributed (SLbool distrib) |
| void | doContinuous (SLbool cont) |
| void | doFresnel (SLbool fresnel) |
| void | aaSamples (SLint samples) |
| void | gamma (SLfloat g) |
| SLRTState | state () const |
| SLint | maxDepth () const |
| SLbool | doDistributed () const |
| SLbool | doContinuous () const |
| SLbool | doFresnel () const |
| SLint | aaSamples () const |
| SLint | progressPC () const |
| SLfloat | aaThreshold () const |
| SLfloat | renderSec () const |
| SLfloat | gamma () const |
| SLfloat | oneOverGamma () const |
| SLfloat | resolutionFactor () const |
| SLint | resolutionFactorPC () const |
| SLfloat | raysPerMS () |
| Rays per ms of the last completed render, for comparing machines. More... | |
| virtual void | prepareImage () |
| virtual void | renderImage (bool updateTextureGL) |
Public Member Functions inherited from SLGLTexture | |
| SLGLTexture () | |
| Default ctor for all stack instances (not created with new) More... | |
| SLGLTexture (SLAssetManager *assetMgr, const SLVCol4f &colors, SLint min_filter=GL_LINEAR, SLint mag_filter=GL_LINEAR, SLint wrapS=GL_REPEAT, const SLstring &name="2D-Texture") | |
| ctor for 1D texture with internal image allocation More... | |
| SLGLTexture (SLAssetManager *assetMgr, SLint min_filter, SLint mag_filter, SLint wrapS, SLint wrapT, SLenum target=GL_TEXTURE_2D) | |
| ctor for empty 2D textures More... | |
| SLGLTexture (SLAssetManager *assetMgr, unsigned char *data, int width, int height, int cvtype, SLint min_filter, SLint mag_filter, SLTextureType type, SLint wrapS, SLint wrapT) | |
| ctor for 2D textures from byte pointer More... | |
| SLGLTexture (SLAssetManager *assetMgr, const SLstring &imageFilename, SLint min_filter=GL_LINEAR_MIPMAP_LINEAR, SLint mag_filter=GL_LINEAR, SLTextureType type=TT_unknown, SLint wrapS=GL_REPEAT, SLint wrapT=GL_REPEAT) | |
| ctor for 2D textures with internal image allocation More... | |
| SLGLTexture (SLAssetManager *assetMgr, const SLVstring &imageFilenames, SLint min_filter=GL_LINEAR, SLint mag_filter=GL_LINEAR, SLint wrapS=GL_REPEAT, SLint wrapT=GL_REPEAT, const SLstring &name="3D-Texture", SLbool loadGrayscaleIntoAlpha=false) | |
| ctor for 3D texture with internal image allocation More... | |
| SLGLTexture (SLAssetManager *assetMgr, SLint depth, const SLstring &imageFilename, SLint min_filter=GL_LINEAR, SLint mag_filter=GL_LINEAR, SLint wrapS=GL_REPEAT, SLint wrapT=GL_REPEAT, const SLstring &name="3D-Texture", SLbool loadGrayscaleIntoAlpha=false) | |
| ctor for 3D texture from a single file with depth as 3rd dimension More... | |
| SLGLTexture (SLAssetManager *assetMgr, const SLstring &imageFilenameXPos, const SLstring &imageFilenameXNeg, const SLstring &imageFilenameYPos, const SLstring &imageFilenameYNeg, const SLstring &imageFilenameZPos, const SLstring &imageFilenameZNeg, SLint min_filter=GL_LINEAR, SLint mag_filter=GL_LINEAR, SLTextureType type=TT_unknown) | |
| ctor for cube mapping with internal image allocation More... | |
| ~SLGLTexture () override | |
| virtual void | build (SLint texUnit) |
| void | deleteData (SLbool deleteAlsoOnGPU) |
| Delete all data (CVImages and GPU textures) More... | |
| void | deleteDataGpu () |
| Deletes the OpenGL texture objects and releases the memory on the GPU. More... | |
| void | deleteImages () |
| Deletes the CVImages in _images. No more texture mapping in ray tracing. More... | |
| void | bindActive (SLuint texUnit=0) |
| void | fullUpdate () |
| void | drawSprite (SLbool doUpdate, SLfloat x, SLfloat y, SLfloat w, SLfloat h) |
| Draws the texture as 2D sprite with OpenGL buffers. More... | |
| void | cubeUV2XYZ (SLint index, SLfloat u, SLfloat v, SLfloat &x, SLfloat &y, SLfloat &z) |
| Computes the unnormalised vector x,y,z from tex. coords. uv with cubemap index. More... | |
| void | cubeXYZ2UV (SLfloat x, SLfloat y, SLfloat z, SLint &index, SLfloat &u, SLfloat &v) |
| Computes the uv and cubemap image index from a unnormalised vector x,y,z. More... | |
| SLstring | filterString (SLint glFilter) |
| Returns OpenGL texture filter as string. More... | |
| void | texType (SLTextureType bt) |
| void | uvIndex (SLbyte i) |
| void | bumpScale (SLfloat bs) |
| void | minFiler (SLint minF) |
| void | magFiler (SLint magF) |
| void | needsUpdate (SLbool update) |
| void | textureSize (int width, int height) |
| void | deleteImageAfterBuild (SLbool delImg) |
| If deleteImageAfterBuild is set to true you won't be able to ray trace the scene. More... | |
| SLuint | width () |
| SLuint | height () |
| SLuint | depth () |
| SLbyte | uvIndex () |
| SLint | bytesPerPixel () |
| SLint | bytesOnGPU () |
| SLint | bytesInFile () |
| CVVImage & | images () |
| SLenum | target () const |
| SLuint | texID () const |
| SLTextureType | texType () |
| SLfloat | bumpScale () const |
| SLCol4f | getTexelf (SLfloat u, SLfloat v, SLuint imgIndex=0) |
| SLGLTexture::getTexelf returns a pixel color from u & v texture coordinates. More... | |
| SLCol4f | getTexelf (const SLVec3f &cubemapDir) |
| SLGLTexture::getTexelf returns a pixel color at the specified cubemap direction. More... | |
| SLbool | hasAlpha () |
| SLMat4f | tm () |
| SLbool | autoCalcTM3D () const |
| SLbool | needsUpdate () |
| SLstring | typeName () |
| Returns the texture type as string. More... | |
| SLstring | typeShortName () |
| Returns the texture type short. More... | |
| bool | isTexture () |
| SLstring | minificationFilterName () |
| SLstring | magnificationFilterName () |
| void | build2DMipmaps (SLint target, SLuint index) |
| SLbool | copyVideoImage (SLint camWidth, SLint camHeight, CVPixelFormatGL glFormat, SLuchar *data, SLbool isContinuous, SLbool isTopLeft) |
| Copies the image data from a video camera into the current video image. More... | |
| SLbool | copyVideoImage (SLint camWidth, SLint camHeight, CVPixelFormatGL srcFormat, CVPixelFormatGL dstFormat, SLuchar *data, SLbool isContinuous, SLbool isTopLeft) |
| void | calc3DGradients (SLint sampleRadius, const function< void(int)> &onUpdateProgress=nullptr) |
| void | smooth3DGradients (SLint smoothRadius, function< void(int)> onUpdateProgress=nullptr) |
| SLVec2f | dudv (SLfloat u, SLfloat v) |
Public Member Functions inherited from SLObject | |
| SLObject (const SLstring &Name="", const SLstring &url="") | |
| virtual | ~SLObject () |
| void | name (const SLstring &Name) |
| void | url (const SLstring &url) |
| const SLstring & | name () const |
| const SLstring & | url () const |
Private Attributes | |
| function< void(bool, int, SLuint)> | renderSlicesPTAsync |
| SLbool | _calcDirect |
| flag to calculate direct illumination More... | |
| SLbool | _calcIndirect |
| flag to calculate indirect illumination More... | |
| SLfloat | _sampleClamp |
| Upper limit on the radiance of a single sample, 0 to switch it off. More... | |
| vector< SLCol4f > | _radianceSum |
| Linear, unclamped sum of all radiance samples taken so far per pixel. More... | |
| vector< SLdouble > | _lumSum |
| Sum and sum of squares of the luminance of every sample, per pixel. More... | |
| vector< SLdouble > | _lumSumSq |
| SLfloat | _noiseRSE |
| mean relative standard error, see noiseRSE() More... | |
| SLfloat | _noiseRSE999 |
| the same for the worst 0.1%, see noiseRSE999() More... | |
Additional Inherited Members | |
Static Public Member Functions inherited from SLRaytracer | |
| static SLuint | numThreads () |
Static Public Member Functions inherited from SLGLTexture | |
| static SLTextureType | detectType (const SLstring &filename) |
| Detects the texture type from the filename appendix (See SLTexType def.) More... | |
| static string | internalFormatStr (int internalFormat) |
| Returns the internal pixel format from OpenGL. More... | |
Static Public Attributes inherited from SLGLTexture | |
| static SLfloat | maxAnisotropy = -1.0f |
| Returns the derivation as [s,t]. More... | |
| static SLuint | totalNumBytesOnGPU = 0 |
| Total NO. of bytes used for textures on GPU. More... | |
Protected Member Functions inherited from SLGLTexture | |
| void | load (const SLstring &filename, SLbool flipVertical=true, SLbool loadGrayscaleIntoAlpha=false) |
| Loads the texture, converts color depth & applies vertical mirroring. More... | |
| void | load (const SLVCol4f &colors) |
| Loads the 1D color data into an image of height 1. More... | |
Protected Attributes inherited from SLRaytracer | |
| function< void(bool, SLuint)> | renderSlicesAsync |
| function< void(bool, SLuint)> | sampleAAPixelsAsync |
| SLSceneView * | _sv |
| Parent sceneview. More... | |
| SLRTState | _state |
| RT state;. More... | |
| SLCamera * | _cam |
| shortcut to the camera More... | |
| SLfloat | _resolutionFactor |
| screen to RT image size factor (default 1.0) More... | |
| SLint | _maxDepth |
| Max. allowed recursion depth. More... | |
| SLbool | _doContinuous |
| if true state goes into ready again More... | |
| SLbool | _doDistributed |
| Flag for parallel distributed RT. More... | |
| SLbool | _doFresnel |
| Flag for Fresnel reflection. More... | |
| SLint | _progressPC |
| progress in % More... | |
| SLfloat | _renderSec |
| Rendering time in seconds. More... | |
| AvgFloat | _raysPerMS |
| Rays per ms of the last completed render. More... | |
| SLfloat | _pxSize |
| Pixel size. More... | |
| SLVec3f | _eye |
| Camera position. More... | |
| SLVec3f | _la |
| SLVec3f | _lu |
| SLVec3f | _lr |
| Camera lookat, lookup, lookright. More... | |
| SLVec3f | _bl |
| Bottom left vector. More... | |
| SLint | _nextLine |
| next line index to render RT in a thread More... | |
| SLVPixel | _aaPixels |
| Vector for antialiasing pixels. More... | |
| SLfloat | _gamma |
| gamma correction value More... | |
| SLfloat | _oneOverGamma |
| one over gamma correction value More... | |
| SLfloat | _aaThreshold |
| threshold for anti aliasing More... | |
| SLint | _aaSamples |
| SQRT of uneven num. of AA samples. More... | |
Protected Attributes inherited from SLGLTexture | |
| CVVImage | _images |
| Vector of CVImage pointers. More... | |
| SLuint | _texID |
| OpenGL texture ID. More... | |
| SLTextureType | _texType |
| See SLTextureType. More... | |
| SLint | _width |
| Texture image width in pixels (images exist either in _images or on the GPU or on both) More... | |
| SLint | _height |
| Texture image height in pixels (images exist either in _images or on the GPU or on both) More... | |
| SLint | _depth |
| 3D Texture image depth (images exist either in _images or on the GPU or on both) More... | |
| SLbyte | _uvIndex |
| Texture coordinate index in SLMesh (0 = default) More... | |
| SLint | _internalFormat |
| Internal OpenGL format. More... | |
| SLint | _bytesPerPixel |
| Bytes per texture image pixel (images exist either in _images or on the GPU or on both) More... | |
| SLint | _min_filter |
| Minification filter. More... | |
| SLint | _mag_filter |
| Magnification filter. More... | |
| SLint | _wrap_s |
| Wrapping in s direction. More... | |
| SLint | _wrap_t |
| Wrapping in t direction. More... | |
| SLenum | _target |
| texture target More... | |
| SLMat4f | _tm |
| texture matrix More... | |
| SLuint | _bytesOnGPU |
| NO. of bytes on GPU. More... | |
| SLuint | _bytesInFile |
| NO. of bytes in file. More... | |
| SLbool | _autoCalcTM3D |
| Flag if texture matrix should be calculated from AABB for 3D mapping. More... | |
| SLfloat | _bumpScale |
| Bump mapping scale factor. More... | |
| SLbool | _resizeToPow2 |
| Flag if image should be resized to n^2. More... | |
| SLGLVertexArray | _vaoSprite |
| Vertex array object for sprite rendering. More... | |
| std::atomic< bool > | _needsUpdate {} |
| Flag if image needs an single update. More... | |
| std::mutex | _mutex |
| Mutex to protect parallel access (used in ray tracing) More... | |
| SLbool | _deleteImageAfterBuild |
| Flag if images should be deleted after build on GPU. More... | |
| SLbool | _compressedTexture = false |
| True for compressed texture format on GPU. More... | |
Protected Attributes inherited from SLObject | |
| SLstring | _name |
| name of an object More... | |
| SLstring | _url |
| uniform resource locator More... | |
Classic Monte Carlo Pathtracing algorithm for real global illumination.
Definition at line 17 of file SLPathtracer.h.
| SLPathtracer::SLPathtracer | ( | ) |
Definition at line 184 of file SLPathtracer.cpp.
|
inline |
Definition at line 21 of file SLPathtracer.h.
|
inline |
Definition at line 44 of file SLPathtracer.h.
Definition at line 39 of file SLPathtracer.h.
|
inline |
Definition at line 45 of file SLPathtracer.h.
Definition at line 40 of file SLPathtracer.h.
| void SLPathtracer::computeNoise | ( | ) |
Turns the two luminance moments that renderSlices accumulated into the noise figures of the Timing panel. Called once, after the last sample pass.
For a pixel that received N samples with luminances x_i, from the sums
S1 = sum(x_i) and S2 = sum(x_i^2)
the variance of one sample and the standard error of the pixel, which is the mean of those samples, are
s^2 = (S2 - S1^2 / N) / (N - 1) SE = sqrt(s^2 / N)
SE is in the units of the pixel, so it is divided by the pixel to give a relative standard error that can be compared between scenes, exposures and resolutions. noiseRSE is the mean of that over the image, noiseRSE999 the 99.9th percentile, which is the figure fireflies move.
A Monte Carlo estimator converges with 1/sqrt(N), so noiseRSE has to fall by half when the samples per pixel are quadrupled. That makes it a check on the estimators in trace() and shade() as much as a readout: if it does not halve, something upstream is wrong.
Definition at line 822 of file SLPathtracer.cpp.
|
inline |
Monte Carlo efficiency, the inverse of variance times time.
The figure to compare two renderers or two settings with, because it is the only one that stays fair when a change alters what a sample costs, as Russian roulette does. It does not depend on the sample count: the variance of a pixel falls as 1/N while the render time grows as N, so their product is constant in N and two renders at different samples per pixel can be compared directly. Higher is better.
Definition at line 84 of file SLPathtracer.h.
|
inline |
Mean relative standard error of the pixels of the last render.
How far the average pixel is expected to sit from the value this estimator converges to, as a fraction of the pixel itself. It is a measure of the noise only: it says nothing about the bias that sampleClamp adds, and it falls monotonically as the clamp tightens. See computeNoise.
Definition at line 53 of file SLPathtracer.h.
|
inline |
Relative standard error of the noisiest 0.1% of the pixels.
The figure to watch for fireflies. A firefly covers a handful of pixels out of hundreds of thousands, so it barely moves noiseRSE, but it dominates this one.
It has a floor that comes straight from its definition: it reports the pixel at rank 99.9%, so it only moves once the fireflies reach more than 0.1% of the image. Measured on synthetic fireflies at 640x360 and 1000 spp, with the outliers 3000 times an ordinary sample:
firefly pixels noiseRSE noiseRSE999 0.010% 0.00320 0.00338 0.100% 0.00370 0.00342 still an ordinary pixel 0.200% 0.00421 0.60547 5.000% 0.02910 0.75061
Below that threshold this figure reads as if the image were clean and only noiseRSE moves, by very little. It is the right figure for the Muttenzer Box, whose fireflies cover about 4% of the far wall (see _sampleClamp), but a scene with rarer ones needs a higher percentile or the maximum.
Definition at line 75 of file SLPathtracer.h.
| SLbool SLPathtracer::render | ( | SLSceneView * | sv | ) |
Main render function. The Path Tracing algorithm starts from here
Definition at line 198 of file SLPathtracer.cpp.
Renders a slice of 4px width.
Definition at line 275 of file SLPathtracer.cpp.
|
inline |
Definition at line 46 of file SLPathtracer.h.
Definition at line 41 of file SLPathtracer.h.
|
virtual |
Saves the current PT image as PNG image.
Reimplemented from SLRaytracer.
Definition at line 876 of file SLPathtracer.cpp.
Calculates the direct illumination at the hit point of the ray by sampling the light sources explicitly (next event estimation).
A rectangular light is an AREA light and is estimated with a Monte Carlo area estimator: one point is sampled uniformly on the rectangle (pdf = 1/area) and the radiance reflected towards the ray is
Lo = albedo/PI * Le * cosSurface * cosLight / dist^2 * area
with the direction, the distance and both cosines taken at the SAMPLED point.
The previous version took all of them at the light CENTRE while it tested the visibility at a random point, and it replaced the geometric term by the OpenGL attenuation and the spot cone exponent. That is the Blinn-Phong rasteriser model, not an estimator of the area light integral. It missed the area factor completely, which made the direct light 1/area too bright (1.54x for the 1.0 x 0.65 light of the Muttenzer Box), and it broke down for surfaces close to a large light. Above all it put the direct illumination on a different scale than the emissive material of the light mesh that the paths see when they hit the light through the mirror or the glass sphere, so the two estimates of the same illumination did not agree.
All other light types are point or directional (delta) lights without any area. For those the classic attenuation and spot cone model is kept.
Definition at line 696 of file SLPathtracer.cpp.
Traces one ray. bsdfPdf is the solid angle density with which the.
scattering at the previous vertex produced this ray, or the negative sentinel PDF_NO_MIS if next event estimation cannot generate the same path (the primary ray, and every specular or transmissive bounce). It is what lets a light hit be weighted against the light sampling in shade().
Recursively traces ray in scene.
Definition at line 395 of file SLPathtracer.cpp.
|
private |
flag to calculate direct illumination
Definition at line 94 of file SLPathtracer.h.
|
private |
flag to calculate indirect illumination
Definition at line 95 of file SLPathtracer.h.
|
private |
Sum and sum of squares of the luminance of every sample, per pixel.
The two moments that the variance of a pixel is computed from, in computeNoise. Luminance rather than colour, because the noise of a pixel is one number and not three, and it is linear, so summing the luminance of the samples and taking the luminance of _radianceSum come to the same thing.
They are double and not float, although _radianceSum is float, because the variance is the small difference of two large sums, S2 - S1*S1/N. In a quiet region those two agree to several digits and a float would leave almost none of the result. A firefly makes it worse from the other side: 1e4 squared is 1e8, and adding an ordinary 1e-4 to that is lost entirely in float. Double carries both ends. The cost is 16 bytes per pixel, 3.7 MB at 640x480.
Indexed like _radianceSum, with y * width + x.
Definition at line 152 of file SLPathtracer.h.
|
private |
Definition at line 153 of file SLPathtracer.h.
|
private |
mean relative standard error, see noiseRSE()
Definition at line 155 of file SLPathtracer.h.
|
private |
the same for the worst 0.1%, see noiseRSE999()
Definition at line 156 of file SLPathtracer.h.
|
private |
Linear, unclamped sum of all radiance samples taken so far per pixel.
The progressive mean of a path tracer must never be kept in an 8 bit image. Rounding the running mean to 1/255 after every sample stops the convergence as soon as the correction of one sample, which is |sample - mean| / sampleNo, falls below half a quantisation step, i.e. as soon as sampleNo > 510 * |sample - mean|. A bright outlier (a firefly) then freezes at a wrong value and never averages out again, no matter how many samples are rendered. That is why this buffer holds the raw sum in full float precision and is divided by the sample number for the display only. Its size is _images[0]->width() * _images[0]->height() and it is indexed with y * width + x.
Definition at line 136 of file SLPathtracer.h.
|
private |
Upper limit on the radiance of a single sample, 0 to switch it off.
A firefly is a path that carries far more energy than the pixel it lands in, most often a caustic: light that reaches a diffuse surface through the mirror or the glass sphere. The estimator is right about it, but such a path is found so seldom that the average is still visibly lumpy after a thousand samples. Capping what one sample may contribute removes it at once.
This is a deliberate bias, and the only one left in the renderer: it discards the part of a caustic above the limit and makes it darker than it is. Measured on the Muttenzer Box at 100 spp, against no clamp:
limit fireflies, far wall mean radiance of the caustic off 4.35% 1.000 30 4.75% 0.985 10 4.08% 0.938 3 0.02% 0.695
The fireflies of this scene sit between 3 and 10, so 30 does nothing and 10 barely helps. 3 removes them almost entirely and costs 2 to 5% on ordinary surfaces, 15% on the ceiling below the light and 30% on the caustic under the glass sphere. That is the trade, and it is why this is a menu item that can be switched off rather than a constant.
Note that it caps the SAMPLE and never the running mean. Clamping the mean is the defect that the float accumulation buffer removed: it froze the fireflies at a wrong value instead of averaging them away.
Definition at line 123 of file SLPathtracer.h.
Definition at line 92 of file SLPathtracer.h.