44 assert(light &&
"SLShadowMap::SLShadowMap: No light passed");
46 "SLShadowMap::SLShadowMap: Invalid clip distances passed");
57 SL_EXIT_MSG(
"SLShadowMap::SLShadowMap: Unknown light type");
86 assert(light &&
"SLShadowMap::SLShadowMap: No light passed");
87 assert(
camera &&
"SLShadowMap::SLShadowMap: No camera passed");
89 "SLShadowMap::SLShadowMap: Invalid NO.of cascades (0-5)");
96 SL_EXIT_MSG(
"Auto sized shadow maps only exist for directional lights yet.");
128 {-1, 1, -1}, { 1, 1, -1},
129 {-1, 1, -1}, {-1, 1, 1},
130 { 1, 1, 1}, {-1, 1, 1},
131 { 1, 1, 1}, { 1, 1, -1},
133 {-1, -1, -1}, { 1, -1, -1},
134 {-1, -1, -1}, {-1, -1, 1},
135 { 1, -1, 1}, {-1, -1, 1},
136 { 1, -1, 1}, { 1, -1, -1},
138 {-1, -1, -1}, {-1, 1, -1},
139 { 1, -1, -1}, { 1, 1, -1},
140 {-1, -1, 1}, {-1, 1, 1},
141 { 1, -1, 1}, { 1, 1, 1},
195 if (w == 0 || h == 0)
return;
206 for (
SLint x = 0; x < w; ++x)
208 for (
SLint y = 0; y < h; ++y)
210 SLint pixelX = (
SLint)(pixelWidth * (x + 0.5f));
211 SLint pixelY = (
SLint)(pixelHeight * (y + 0.5f));
217 P.push_back(
SLVec3f(viewSpaceX, viewSpaceY, -1.0f));
218 P.push_back(
SLVec3f(viewSpaceX, viewSpaceY, depth));
224 if (P.empty())
return;
317 "SLShadowMap::lightCullingAdaptiveRec: No node passed.");
319 "SLShadowMap::lightCullingAdaptiveRec: No lightFrustumPlanes passed.");
329 if (node->
parent()->children().size() < levelForSM)
331 SL_EXIT_MSG(
"SLShadowMap::lightCullingAdaptiveRec: levelForSM > num. LOD Nodes.");
333 SLNode* nodeForSM = node->
parent()->children()[levelForSM - 1];
334 if (nodeForSM != node)
349 if (distance < -node->aabb()->radiusWS())
353 for (
int i = 0; i < 4; i++)
356 if (distance < -node->aabb()->radiusWS())
364 if (distance < node->aabb()->radiusWS())
366 float a = lightProj.
m(10);
367 float b = lightProj.
m(14);
368 float n = (b + 1.f) / a;
369 float f = (b - 1.f) / a;
371 lightProj.
m(10, -2.f / (f - n));
372 lightProj.
m(14, -(f + n) / (f - n));
379 visibleNodes.push_back(node);
403 for (
SLNode* node : visibleNodes)
405 if (node->castsShadows() &&
407 node->mesh()->primitive() >= GL_TRIANGLES)
411 node->mesh()->drawIntoDepthBuffer(
sv, node,
_material);
426 assert(node &&
"SLShadowMap::drawNodesIntoDepthBufferRec: No node passed.");
452 assert(root &&
"SLShadowMap::render: No root node passed.");
474 static SLfloat borderColor[] = {1.0, 1.0, 1.0, 1.0};
482 SLint wrapMode = GL_CLAMP_TO_EDGE;
484 SLint wrapMode = GL_CLAMP_TO_BORDER;
502 ? GL_TEXTURE_CUBE_MAP
511 _depthBuffers[0]->bindFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
542 float ni, fi = camClipNear;
552 cascades.push_back(
SLVec2f(ni, fi));
564 assert(root &&
"LShadowMap::renderDirectionalLightCascaded: no root node");
567 static SLfloat borderColor[] = {1.0, 1.0, 1.0, 1.0};
598 SLint wrapMode = GL_CLAMP_TO_EDGE;
600 SLint wrapMode = GL_CLAMP_TO_BORDER;
606 for (
int i = 0; i < cascades.size(); i++)
616 for (
int i = 0; i < cascades.size(); i++)
619 float cn = cascades[i].x;
620 float cf = cascades[i].y;
638 float minx = FLT_MAX, maxx = FLT_MIN;
639 float miny = FLT_MAX, maxy = FLT_MIN;
640 float minz = FLT_MAX, maxz = FLT_MIN;
641 for (
int j = 0; j < 8; j++)
643 SLVec3f fp = lightViewMat * camWM * camFrustumPoints[j];
644 if (fp.
x < minx) minx = fp.
x;
645 if (fp.
y < miny) miny = fp.
y;
646 if (fp.
x > maxx) maxx = fp.
x;
647 if (fp.
y > maxy) maxy = fp.
y;
648 if (fp.
z < minz) minz = fp.
z;
649 if (fp.
z > maxz) maxz = fp.
z;
651 float sx = 2.f / (maxx - minx);
652 float sy = 2.f / (maxy - miny);
653 float sz = -2.f / (maxz - minz);
655 -0.5f * (maxy + miny),
656 -0.5f * (maxz + minz));
660 lightProjMat.
scale(sx, sy, sz);
#define PROFILE_FUNCTION()
#define SL_EXIT_MSG(message)
#define SL_DB_HIDDEN
Flags an object as hidden.
@ P_monoPerspective
standard mono pinhole perspective projection
@ P_monoOrthographic
standard mono orthographic projection
Uses an OpenGL framebuffer object as a depth-buffer.
std::vector< SLGLDepthBuffer * > SLGLVDepthBuffer
Singleton class for global render state.
Extension class with functions for quick line & point drawing.
deque< SLNode * > SLVNode
SLVNode typedef for a vector of SLNodes.
vector< SLVec2f > SLVVec2f
SLVec2< SLfloat > SLVec2f
vector< SLVec3f > SLVVec3f
SLVec3< SLfloat > SLVec3f
Active or visible camera node class.
SLfloat fovV() const
Vertical field of view.
void clipFar(const SLfloat cFar)
void clipNear(const SLfloat cNear)
static void viewToFrustumPlanes(SLPlane *planes, const SLMat4f &projectionMat, const SLMat4f &viewMat)
static void getPointsInViewSpace(SLVec3f *points, float fovV, float ratio, float clipNear, float clipFar)
Returns frustum points in view space.
static SLGLProgramGeneric * get(SLStdShaderProg id)
Get program reference for given id.
Singleton class holding all OpenGL states.
void clearColor(const SLCol4f &c)
SLMat4f modelMatrix
Init all states.
void viewport(SLint x, SLint y, SLsizei width, SLsizei height)
static SLGLState * instance()
Public static instance getter for singleton pattern.
SLMat4f viewMatrix
matrix for the active cameras view transform
SLMat4f projectionMatrix
matrix for projection transform
void clearColorDepthBuffer()
SLGLVertexArray adds Helper Functions for quick Line & Point Drawing.
void generateVertexPos(SLVVec2f *p)
Adds or updates & generates a position vertex attribute for colored line or point drawing.
void drawArrayAsColored(SLGLPrimitiveType primitiveType, SLCol4f color, SLfloat lineOrPointSize=1.0f, SLuint indexFirstVertex=0, SLuint countVertices=0)
Draws the array as the specified primitive with the color.
SLLightDirect class for a directional light source.
Abstract Light class for OpenGL light sources.
virtual SLVec4f positionWS() const =0
void spotCutOffDEG(SLfloat cutOffAngleDEG)
Light node class for a rectangular light source.
SLLightSpot class for a spot light source.
SLVec3< T > translation() const
void lookAt(T EyeX, T EyeY, T EyeZ, T AtX=0, T AtY=0, T AtZ=0, T UpX=0, T UpY=0, T UpZ=0)
Defines the a view matrix as the corresponding gluLookAt function.
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.
SLMat4< T > inverted() const
Computes the inverse of a 4x4 non-singular matrix.
SLVec3< T > axisZ() const
void perspective(T fov, T aspect, T n, T f)
Defines a perspective projection matrix with a field of view angle.
void translate(T tx, T ty, T tz=0)
Defines a standard CG material with textures and a shader program.
SLGLPrimitiveType primitive() const
void drawIntoDepthBuffer(SLSceneView *sv, SLNode *node, SLMaterial *depthMat)
Simplified drawing method for shadow map creation.
SLNode represents a node in a hierarchical scene graph.
SLbool drawBit(SLuint bit)
const SLMat4f & updateAndGetWM() const
void castsShadows(SLbool castsShadows)
void levelForSM(SLubyte lfsm)
SLVec3f forwardWS() const
Level of detail (LOD) group node based on screen space coverage.
Defines a plane in 3D space with the equation ax + by + cy + d = 0.
SLfloat distToPoint(const SLVec3f &p)
Returns distance between a point P and the plane.
The SLScene class represents the top level instance holding the scene structure.
SceneView class represents a dynamic real time 3D view onto the scene.
SLGLVDepthBuffer _depthBuffers
Vector of framebuffers with texture.
SLShadowMap(SLLight *light, const SLfloat lightClipNear=0.1f, const SLfloat lightClipFar=20.0f, const SLVec2f &size=SLVec2f(8, 8), const SLVec2i &texSize=SLVec2i(1024, 1024))
Ctor for standard fixed sized shadow mapping without cascades.
SLProjType _projection
Projection to use to create shadow map.
SLbool _useCascaded
Flag if cascaded shadow maps should be used.
void renderDirectionalLightCascaded(SLSceneView *sv, SLNode *root)
SLMat4f _lightView[6]
Light view matrices.
SLint _numCascades
Number of cascades for directional light shadow mapping.
SLVec2i _rayCount
Amount of rays drawn by drawRays()
SLCamera * _camera
Camera to witch the light frustums are adapted.
void drawNodesIntoDepthBufferRec(SLNode *node, SLSceneView *sv, SLMat4f &lightView)
SLMaterial * _material
Material used to render the shadow map.
void updateLightSpaces()
SLShadowMap::updateLightSpaces updates a light view projection matrix.
SLint _maxCascades
Max. number of cascades for for which the shader gets generated.
static SLuint drawCalls
NO. of draw calls for shadow mapping.
SLMat4f _lightProj[6]
Light projection matrices.
SLGLVertexArrayExt * _frustumVAO
Visualization of light-space-frustum.
void drawFrustum()
SLShadowMap::drawFrustum draws the volume affected by the shadow map.
SLfloat _lightClipNear
Light frustum near clipping plane.
SLVec2f _halfSize
_size divided by two (only for SLLightDirect non cascaded)
SLVec2i _textureSize
Size of the shadow map texture.
SLMat4f _lightSpace[6]
Light space matrices (= _lightProj * _lightView)
SLfloat _cascadesFactor
Factor that determines the cascades distribution.
SLVec2f _size
Height and width of the frustum (only for SLLightDirect non cascaded)
void lightCullingAdaptiveRec(SLNode *node, SLMat4f &lightProj, SLMat4f &lightView, SLPlane *lightFrustumPlanes, SLVNode &visibleNodes)
void renderShadows(SLSceneView *sv, SLNode *root)
SLLight * _light
The light which uses this shadow map.
SLfloat _lightClipFar
Light frustum far clipping plane.
SLVVec2f getShadowMapCascades(int numCascades, float camClipNear, float camClipFar)
void drawNodesDirectionalCulling(SLVNode visibleNodes, SLSceneView *sv, SLMat4f &lightView)
SLbool _useCubemap
Flag if cubemap should be used for perspective projections.
SLVec3 normalized() const