@@ -21,15 +21,15 @@ void RenderSystem::Init(const pugi::xml_node& rendererNode) {
2121std::abort ();
2222}
2323
24+ queryHardwareCaps ();
25+
2426#ifdef _DEBUG
2527std::cout << " OpenGL Version: " << glGetString (GL_VERSION) << ' \n ' ;
2628std::cout << " GLSL Version: " << glGetString (GL_SHADING_LANGUAGE_VERSION) << ' \n ' ;
2729std::cout << " OpenGL Driver Vendor: " << glGetString (GL_VENDOR) << ' \n ' ;
2830std::cout << " OpenGL Renderer: " << glGetString (GL_RENDERER) << ' \n ' ;
2931#endif
3032
31- getHardwareFeatures ();
32-
3333const auto width = rendererNode.attribute (" width" ).as_uint ();
3434const auto height = rendererNode.attribute (" height" ).as_uint ();
3535
@@ -145,7 +145,7 @@ void RenderSystem::Render(const Camera& camera, RenderListIterator renderListBeg
145145glActiveTexture (GL_TEXTURE2);
146146glBindTexture (GL_TEXTURE_2D, m_skybox.GetBRDFLUT ());
147147glActiveTexture (GL_TEXTURE7);
148- glBindTexture (GL_TEXTURE_2D, m_shadowDepthTexture );
148+ glBindTexture (GL_TEXTURE_2D, m_shadowColorTexture );
149149
150150pbrShader.Bind ();
151151pbrShader.SetUniform (" camPos" , camera.GetPosition ()).SetUniformi (" wireframe" , globalWireframe).SetUniform (" lightSpaceMatrix" , m_lightSpaceMatrix);
@@ -198,6 +198,12 @@ void RenderSystem::UpdateView(const Camera& camera) {
198198glBufferSubData (GL_UNIFORM_BUFFER, 0 , sizeof (glm::mat4), glm::value_ptr (m_projMatrix));
199199}
200200
201+ /* **********************************************************************************/
202+ void RenderSystem::queryHardwareCaps () {
203+ // Anisotropic filtering
204+ glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_caps.MaxAnisotropy );
205+ }
206+
201207/* **********************************************************************************/
202208void RenderSystem::setDefaultState () {
203209glFrontFace (GL_CCW);
@@ -289,12 +295,12 @@ void RenderSystem::renderShadowMap(const SceneBase& scene, RenderListIterator re
289295
290296glCullFace (GL_FRONT); // Solve peter-panning
291297glViewport (0 , 0 , m_shadowMapResolution, m_shadowMapResolution);
292- m_shadowDepthFBO .Bind ();
298+ m_shadowFBO .Bind ();
293299glClear (GL_DEPTH_BUFFER_BIT);
294300
295301renderModelsNoTextures (shadowDepthShader, renderListBegin, renderListEnd);
296302
297- m_shadowDepthFBO .Unbind ();
303+ m_shadowFBO .Unbind ();
298304glViewport (0 , 0 , m_width, m_height);
299305glCullFace (GL_BACK);
300306}
@@ -327,33 +333,49 @@ void RenderSystem::setupTextureSamplers() {
327333glSamplerParameteri (m_samplerPBRTextures, GL_TEXTURE_WRAP_T, GL_REPEAT);
328334glSamplerParameteri (m_samplerPBRTextures, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
329335glSamplerParameteri (m_samplerPBRTextures, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
330- glSamplerParameterf (m_samplerPBRTextures, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_features .MaxAnisotropy );
336+ glSamplerParameterf (m_samplerPBRTextures, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_caps .MaxAnisotropy );
331337
332338}
333339
334340/* **********************************************************************************/
335341void RenderSystem::setupShadowMap () {
336- m_shadowDepthFBO.Init (" Shadow Depth FBO" );
337- m_shadowDepthFBO.Bind ();
342+ const static float borderColor[] = { 1 .0f , 1 .0f , 1 .0f , 1 .0f };
338343
344+ m_shadowFBO.Init (" Shadow Depth FBO" );
345+ m_shadowFBO.Bind ();
346+
347+ // Depth texture
339348if (m_shadowDepthTexture) {
340349glDeleteTextures (1 , &m_shadowDepthTexture);
341350}
342351glGenTextures (1 , &m_shadowDepthTexture);
343352glBindTexture (GL_TEXTURE_2D, m_shadowDepthTexture);
344- glTexImage2D (GL_TEXTURE_2D, 0 , GL_DEPTH_COMPONENT24 , m_shadowMapResolution, m_shadowMapResolution, 0 , GL_DEPTH_COMPONENT, GL_FLOAT, nullptr );
353+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_DEPTH_COMPONENT32 , m_shadowMapResolution, m_shadowMapResolution, 0 , GL_DEPTH_COMPONENT, GL_FLOAT, nullptr );
345354glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
346355glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
347356glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); // Clamp to border to fix over-sampling
348357glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
349- const float borderColor[] = { 1 .0f , 1 .0f , 1 .0f , 1 .0f };
350- glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
358+ glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
359+
360+ // Colour texture for Variance Shadow Mapping (VSM)
361+ if (m_shadowColorTexture) {
362+ glDeleteTextures (1 , &m_shadowColorTexture);
363+ }
364+ glGenTextures (1 , &m_shadowColorTexture);
365+ glBindTexture (GL_TEXTURE_2D, m_shadowColorTexture);
366+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_RG32F, m_shadowMapResolution, m_shadowMapResolution, 0 , GL_RGBA, GL_FLOAT, nullptr );
367+ glGenerateMipmap (GL_TEXTURE_2D);
368+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Hardware linear filtering gives us soft shadows for free!
369+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
370+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); // Clamp to border to fix over-sampling
371+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
372+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_caps.MaxAnisotropy ); // Anisotropic filtering for sharper angles
373+ glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
351374
352- m_shadowDepthFBO.AttachTexture (m_shadowDepthTexture, GLFramebuffer::AttachmentType::DEPTH);
353- m_shadowDepthFBO.DrawBuffer (GLFramebuffer::GLBuffer::NONE);
354- m_shadowDepthFBO.ReadBuffer (GLFramebuffer::GLBuffer::NONE);
375+ m_shadowFBO.AttachTexture (m_shadowDepthTexture, GLFramebuffer::AttachmentType::DEPTH);
376+ m_shadowFBO.AttachTexture (m_shadowColorTexture, GLFramebuffer::AttachmentType::COLOR0);
355377
356- m_shadowDepthFBO .Unbind ();
378+ m_shadowFBO .Unbind ();
357379}
358380
359381/* **********************************************************************************/
0 commit comments