From 6884adf0c2f8eeee2f05cd768d79733b932aa17c Mon Sep 17 00:00:00 2001 From: Daniel Chappuis <chappuis.daniel@gmail.com> Date: Sun, 26 Jul 2015 22:30:45 +0000 Subject: [PATCH] Fix issue with shadow mapping --- testbed/opengl-framework/src/maths/Matrix4.h | 58 +++++++++++++++++++- testbed/shaders/phong.frag | 6 +- testbed/src/SceneDemo.cpp | 10 +++- testbed/src/SceneDemo.h | 3 + 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/testbed/opengl-framework/src/maths/Matrix4.h b/testbed/opengl-framework/src/maths/Matrix4.h index bcfbcebd..f481ecc9 100644 --- a/testbed/opengl-framework/src/maths/Matrix4.h +++ b/testbed/opengl-framework/src/maths/Matrix4.h @@ -27,7 +27,7 @@ #define MATRIX4_H // Libraries -#include <math.h> +#include <cmath> #include <assert.h> #include <iostream> #include "Vector3.h" @@ -376,6 +376,15 @@ class Matrix4 { // Return a 4x4 rotation matrix static Matrix4 rotationMatrix(const Vector3& axis, float angle); + + // Return a 4x4 perspective projection matrix + static Matrix4 perspectiveProjectionMatrix(float near, float far, + int width, int height, + float fieldOfView); + + // Return a 4x4 orthographic projection matrix + static Matrix4 orthoProjectionMatrix(float near, float far, int width, + int height); }; // * operator @@ -422,6 +431,53 @@ inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) { return rotationMatrix; } +// Return a 4x4 perspective projection matrix +inline Matrix4 Matrix4::perspectiveProjectionMatrix(float near, float far, int width, int height, + float fieldOfView) { + + // Compute the aspect ratio + float aspect = float(width) / float(height); + + float top = near * tan((fieldOfView / 2.0f) * (float(M_PI) / 180.0f)); + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + + float fx = 2.0f * near / (right - left); + float fy = 2.0f * near / (top - bottom); + float fz = -(far + near) / (far - near); + float fw = -2.0f * far * near / (far - near); + + // Compute the projection matrix + return Matrix4(fx, 0, 0, 0, + 0, fy, 0, 0, + 0, 0, fz, fw, + 0, 0, -1, 0); +} + +// Return a 4x4 orthographic projection matrix +inline Matrix4 Matrix4::orthoProjectionMatrix(float near, float far, int width, int height) { + + // Compute the aspect ratio + float aspect = float(width) / float(height); + + float top = height * 0.5f; + float bottom = -top; + float left = bottom * aspect; + float right = top * aspect; + + float fx = 2.0f / (right - left); + float fy = 2.0f / (top - bottom); + float fz = -2.0f / (far - near); + float fw = -(far + near) / (far - near); + + // Compute the projection matrix + return Matrix4(fx, 0, 0, 0, + 0, fy, 0, 0, + 0, 0, fz, fw, + 0, 0, 0, 1); +} + } #endif //_MATRIX4_H diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 677b289a..498f7238 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -71,9 +71,8 @@ void main() { // Compute shadow factor vec4 shadowMapCoordsOverW = shadowMapCoords / shadowMapCoords.w ; - shadowMapCoordsOverW += 0.0005; - vec2 shadowMapCoordsWithBias = (shadowMapCoordsOverW.xy + vec2(1, 1)) * 0.5; - float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsWithBias).r; + //shadowMapCoordsOverW += 0.0005; + float distanceInShadowMap = texture(shadowMapSampler, shadowMapCoordsOverW.xy).r; float shadow = 0.0; if (shadowMapCoords.w > 0) { shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.0 : 1.0; @@ -81,5 +80,4 @@ void main() { // Compute the final color color = vec4(ambient + shadow * vertexColor.rgb, 1.0); - //color = vec4(distanceInShadowMap, distanceInShadowMap, distanceInShadowMap, 1.0); } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 69ab76db..efee5fcc 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -47,6 +47,12 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mShadowMapLightCamera.setSceneRadius(200); //mShadowMapLightCamera.setZoom(1.0); + + mShadowMapBiasMatrix.setAllValues(0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0); + // Create the Shadow map FBO and texture createShadowMapFBOAndTexture(); @@ -115,7 +121,7 @@ void SceneDemo::render() { // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", shadowMapProjMatrix); + mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", mShadowMapBiasMatrix * shadowMapProjMatrix); mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); @@ -148,7 +154,7 @@ void SceneDemo::render() { void SceneDemo::createShadowMapFBOAndTexture() { // Create the texture for the depth values - mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, + mShadowMapTexture.create(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, GL_CLAMP, GL_CLAMP, NULL); mShadowMapTexture.setLayer(1); diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 28d571a9..92e64c10 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -51,6 +51,9 @@ class SceneDemo : public Scene { /// Shadow map texture openglframework::Texture2D mShadowMapTexture; + /// Shadow map bias matrix + openglframework::Matrix4 mShadowMapBiasMatrix; + /// Camera at light0 position for the shadow map openglframework::Camera mShadowMapLightCamera;