From b5f1557bd60c3c0853f4d5180ecf3535db90dec9 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sat, 25 Jul 2015 23:28:27 +0000 Subject: [PATCH] Continue working on shadow mapping for the testbed application --- testbed/common/Box.cpp | 5 +++-- testbed/shaders/depth.vert | 5 +++-- testbed/shaders/phong.frag | 15 ++++++++++++++- testbed/shaders/phong.vert | 11 +++++++++-- testbed/src/SceneDemo.cpp | 36 +++++++++++++++++++++--------------- testbed/src/SceneDemo.h | 3 --- 6 files changed, 50 insertions(+), 25 deletions(-) diff --git a/testbed/common/Box.cpp b/testbed/common/Box.cpp index e3fc397a..3a1659aa 100644 --- a/testbed/common/Box.cpp +++ b/testbed/common/Box.cpp @@ -182,11 +182,12 @@ void Box::render(openglframework::Shader& shader, mVBOVertices.bind(); // Set the model to camera matrix - const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; - shader.setMatrix4x4Uniform("localToCameraMatrix", localToCameraMatrix); + shader.setMatrix4x4Uniform("localToWorldMatrix", mTransformMatrix); + shader.setMatrix4x4Uniform("worldToCameraMatrix", worldToCameraMatrix); // Set the normal matrix (inverse transpose of the 3x3 upper-left sub matrix of the // model-view matrix) + const openglframework::Matrix4 localToCameraMatrix = worldToCameraMatrix * mTransformMatrix; const openglframework::Matrix3 normalMatrix = localToCameraMatrix.getUpperLeft3x3Matrix().getInverse().getTranspose(); shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false); diff --git a/testbed/shaders/depth.vert b/testbed/shaders/depth.vert index ec0c0705..c4af178a 100644 --- a/testbed/shaders/depth.vert +++ b/testbed/shaders/depth.vert @@ -26,7 +26,8 @@ ********************************************************************************/ // Uniform variables -uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix +uniform mat4 localToWorldMatrix; // Local-space to world-space matrix +uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix uniform mat4 projectionMatrix; // Projection matrix // In variables @@ -35,5 +36,5 @@ in vec4 vertexPosition; void main() { // Compute the clip-space vertex coordinates - gl_Position = projectionMatrix * localToCameraMatrix * vertexPosition; + gl_Position = projectionMatrix * worldToCameraMatrix * localToWorldMatrix * vertexPosition; } diff --git a/testbed/shaders/phong.frag b/testbed/shaders/phong.frag index 2f5777f1..677b289a 100644 --- a/testbed/shaders/phong.frag +++ b/testbed/shaders/phong.frag @@ -32,6 +32,7 @@ uniform vec3 light0DiffuseColor; // Light 0 diffuse color uniform vec3 light0SpecularColor; // Light 0 specular color uniform float shininess; // Shininess uniform sampler2D textureSampler; // Texture +uniform sampler2D shadowMapSampler; // Shadow map texture sampler uniform bool isTexture; // True if we need to use the texture uniform vec4 vertexColor; // Vertex color @@ -39,6 +40,7 @@ uniform vec4 vertexColor; // Vertex color in vec3 vertexPosCameraSpace; // Camera-space position of the vertex in vec3 vertexNormalCameraSpace; // Vertex normal in camera-space in vec2 texCoords; // Texture coordinates +in vec4 shadowMapCoords; // Shadow map texture coords // Out variable out vec4 color; // Output color @@ -67,6 +69,17 @@ void main() { if (diffuseFactor < 0.0) specularFactor = 0.0; vec3 specular = light0SpecularColor * specularFactor; + // 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; + float shadow = 0.0; + if (shadowMapCoords.w > 0) { + shadow = distanceInShadowMap < shadowMapCoordsOverW.z ? 0.0 : 1.0; + } + // Compute the final color - color = vec4(ambient + diffuse + specular, 1.0); + color = vec4(ambient + shadow * vertexColor.rgb, 1.0); + //color = vec4(distanceInShadowMap, distanceInShadowMap, distanceInShadowMap, 1.0); } diff --git a/testbed/shaders/phong.vert b/testbed/shaders/phong.vert index 3e9a5398..491558fb 100644 --- a/testbed/shaders/phong.vert +++ b/testbed/shaders/phong.vert @@ -26,9 +26,12 @@ ********************************************************************************/ // Uniform variables -uniform mat4 localToCameraMatrix; // Local-space to camera-space matrix +uniform mat4 localToWorldMatrix; // Local-space to world-space matrix +uniform mat4 worldToCameraMatrix; // World-space to camera-space matrix +uniform mat4 worldToLight0CameraMatrix; // World-space to light0 camera-space matrix (for shadow mapping) uniform mat4 projectionMatrix; // Projection matrix uniform mat3 normalMatrix; // Normal matrix +uniform mat4 shadowMapProjectionMatrix; // Shadow map projection matrix // In variables in vec4 vertexPosition; @@ -39,11 +42,12 @@ in vec2 textureCoords; out vec3 vertexPosCameraSpace; // Camera-space position of the vertex out vec3 vertexNormalCameraSpace; // Vertex normal in camera-space out vec2 texCoords; // Texture coordinates +out vec4 shadowMapCoords; // Shadow map texture coords void main() { // Compute the vertex position - vec4 positionCameraSpace = localToCameraMatrix * vertexPosition; + vec4 positionCameraSpace = worldToCameraMatrix * localToWorldMatrix * vertexPosition; vertexPosCameraSpace = positionCameraSpace.xyz; // Compute the world surface normal @@ -52,6 +56,9 @@ void main() { // Get the texture coordinates texCoords = textureCoords; + // Compute the texture coords of the vertex in the shadow map + shadowMapCoords = shadowMapProjectionMatrix * worldToLight0CameraMatrix * localToWorldMatrix * vertexPosition; + // Compute the clip-space vertex coordinates gl_Position = projectionMatrix * positionCameraSpace; } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index e48f1090..69ab76db 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -37,20 +37,15 @@ SceneDemo::SceneDemo(const std::string& name, float sceneRadius) : Scene(name), mVBOQuad(GL_ARRAY_BUFFER) { // Move the light0 - mLight0.translateWorld(Vector3(20, 20, 20)); + mLight0.translateWorld(Vector3(0, 60, 00)); // Camera at light0 postion for the shadow map mShadowMapLightCamera.translateWorld(mLight0.getOrigin()); + mShadowMapLightCamera.rotateLocal(Vector3(1, 0, 0), -PI / 2.0f); mShadowMapLightCamera.setDimensions(SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); - mShadowMapLightCamera.setFieldOfView(45.0f); - mShadowMapLightCamera.setSceneRadius(sceneRadius); - mShadowMapLightCamera.setZoom(1.0); - - // Bias matrix for the shadow map - mShadowMapBiasMatrix.setAllValues(0.5f, 0.0f, 0.0f, 0.5f, - 0.0f, 0.5f, 0.5f, 0.5f, - 0.0f, 0.0f, 0.0f, 0.5f, - 0.0f, 0.0f, 0.0f, 1.0f); + mShadowMapLightCamera.setFieldOfView(70.0f); + mShadowMapLightCamera.setSceneRadius(200); + //mShadowMapLightCamera.setZoom(1.0); // Create the Shadow map FBO and texture createShadowMapFBOAndTexture(); @@ -73,6 +68,11 @@ void SceneDemo::render() { // ---------- Render the scene to generate the shadow map (first pass) ----------- // + // Culling switching, rendering only backface, this is done to avoid self-shadowing + glCullFace(GL_FRONT); + + Matrix4 shadowMapProjMatrix = mShadowMapLightCamera.getProjectionMatrix(); + // Get the world-space to camera-space matrix const openglframework::Matrix4 worldToLightCameraMatrix = mShadowMapLightCamera.getTransformMatrix().getInverse(); @@ -82,7 +82,7 @@ void SceneDemo::render() { mDepthShader.bind(); // Set the variables of the shader - mDepthShader.setMatrix4x4Uniform("projectionMatrix", mShadowMapBiasMatrix * mShadowMapLightCamera.getProjectionMatrix()); + mDepthShader.setMatrix4x4Uniform("projectionMatrix", shadowMapProjMatrix); // Set the viewport to render into the shadow map texture glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_HEIGHT); @@ -104,21 +104,27 @@ void SceneDemo::render() { // ---------- Render the scene for final rendering (second pass) ----------- // + glCullFace(GL_BACK); + // Get the world-space to camera-space matrix const openglframework::Matrix4 worldToCameraMatrix = mCamera.getTransformMatrix().getInverse(); - mPhongShader.bind(); + mShadowMapTexture.bind(); + // Set the variables of the shader mPhongShader.setMatrix4x4Uniform("projectionMatrix", mCamera.getProjectionMatrix()); - mPhongShader.setVector3Uniform("light0PosCameraSpace",worldToCameraMatrix * mLight0.getOrigin()); + mPhongShader.setMatrix4x4Uniform("shadowMapProjectionMatrix", shadowMapProjMatrix); + mPhongShader.setMatrix4x4Uniform("worldToLight0CameraMatrix", worldToLightCameraMatrix); + mPhongShader.setVector3Uniform("light0PosCameraSpace", worldToCameraMatrix * mLight0.getOrigin()); mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f)); const Color& diffCol = mLight0.getDiffuseColor(); const Color& specCol = mLight0.getSpecularColor(); mPhongShader.setVector3Uniform("light0DiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b)); mPhongShader.setVector3Uniform("light0SpecularColor", Vector3(specCol.r, specCol.g, specCol.b)); mPhongShader.setFloatUniform("shininess", 60.0f); + mPhongShader.setIntUniform("shadowMapSampler", mShadowMapTexture.getID()); // Set the viewport to render the scene glViewport(mViewportX, mViewportY, mViewportWidth, mViewportHeight); @@ -132,10 +138,10 @@ void SceneDemo::render() { // Render the objects of the scene renderSinglePass(mPhongShader, worldToCameraMatrix); + mShadowMapTexture.unbind(); mPhongShader.unbind(); - - // drawTextureQuad(); + //drawTextureQuad(); } // Create the Shadow map FBO and texture diff --git a/testbed/src/SceneDemo.h b/testbed/src/SceneDemo.h index 87b5f989..28d571a9 100644 --- a/testbed/src/SceneDemo.h +++ b/testbed/src/SceneDemo.h @@ -54,9 +54,6 @@ class SceneDemo : public Scene { /// Camera at light0 position for the shadow map openglframework::Camera mShadowMapLightCamera; - /// Bias matrix for the shadow map - openglframework::Matrix4 mShadowMapBiasMatrix; - /// Depth shader to render the shadow map openglframework::Shader mDepthShader;