From cb7f06573fbea083af3c666f4185a5cadabc14a3 Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Tue, 9 Feb 2016 14:08:57 +0100 Subject: [PATCH] Shadows stage 2 WIP --- include/Engine/Rendering/DrawFinalPass.h | 4 +- include/Engine/Rendering/ShadowPass.h | 19 ++++--- resources/Shaders/ExplosionEffect.geom.glsl | 4 ++ resources/Shaders/ForwardPlus.frag.glsl | 63 ++++++++++++++++++++- resources/Shaders/ForwardPlus.vert.glsl | 22 ++++++- src/Engine/Rendering/DrawFinalPass.cpp | 20 ++++++- src/Engine/Rendering/FrameBuffer.cpp | 1 - src/Engine/Rendering/Renderer.cpp | 5 +- src/Engine/Rendering/ShadowPass.cpp | 19 +++---- 9 files changed, 128 insertions(+), 29 deletions(-) diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 74f505fe..ba65d6e7 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -8,11 +8,12 @@ #include "ShaderProgram.h" #include "Util/UnorderedMapVec2.h" #include "Texture.h" +#include "ShadowPass.h" class DrawFinalPass { public: - DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass); + DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, ShadowPass* shadowPass); ~DrawFinalPass() { } void InitializeTextures(); void InitializeFrameBuffers(); @@ -50,6 +51,7 @@ private: const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; + const ShadowPass* m_ShadowPass; ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 6a00dacd..a8f41502 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -11,7 +11,8 @@ //#include "ShadowPassState.h" // not created yet - +enum NearFar { Near = 0, Far = 1 }; +enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; class ShadowPass { @@ -28,7 +29,11 @@ public: GLuint DepthMap() const { return m_DepthMap; } - + glm::mat4 lightSpaceMatrix() const { return m_LightSpaceMatrix; } + glm::mat4 lightP() const { return m_LightProjection; } + glm::mat4 lightV() const { return m_LightView; } + //glm::mat4 lightV() const { return m_LightProjection; } //swapped m_P -> m_V + //glm::mat4 lightP() const { return m_LightView; } // swapped m_V -> m_P private: @@ -46,14 +51,12 @@ private: GLuint m_DepthFBO; - GLfloat m_NearPlane = -40.f; - GLfloat m_FarPlane = 80.f; - //GLfloat m_Left = -10.f; - //GLfloat m_Right = 10.f; - //GLfloat m_Bottom = -10.f; - //GLfloat m_Top = 10.f; + GLfloat m_NearFarPlane[2] = { -40.f, 30.f }; GLfloat m_LRBT[4] = { -40.f, 100.f, -50.f, 50.f }; + glm::mat4 m_LightProjection; + glm::mat4 m_LightView; + glm::mat4 m_LightSpaceMatrix; }; #endif \ No newline at end of file diff --git a/resources/Shaders/ExplosionEffect.geom.glsl b/resources/Shaders/ExplosionEffect.geom.glsl index 44b44aa6..3471e4f2 100644 --- a/resources/Shaders/ExplosionEffect.geom.glsl +++ b/resources/Shaders/ExplosionEffect.geom.glsl @@ -22,6 +22,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace; }Input[]; out VertexData{ @@ -32,6 +33,7 @@ out VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace; }Output; layout(triangles) in; @@ -145,6 +147,7 @@ void main() Output.TextureCoordinate = Input[i].TextureCoordinate; Output.Tangent = Input[i].Tangent; Output.BiTangent = Input[i].BiTangent; + Output.PositionLightSpace = Input[i].PositionLightSpace; // convert to model space for the gravity to always be in -y vec4 ExplodedPositionInModelSpace = M * vec4(ExplodedPosition, 1.0); @@ -186,6 +189,7 @@ void main() Output.TextureCoordinate = Input[i].TextureCoordinate; Output.Tangent = Input[i].Tangent; Output.BiTangent = Input[i].BiTangent; + Output.PositionLightSpace = Input[i].PositionLightSpace; // no change in position, pass through vertex gl_Position = gl_in[i].gl_Position; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index c09e0438..d54de713 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -13,6 +13,7 @@ layout (binding = 0) uniform sampler2D DiffuseTexture; layout (binding = 1) uniform sampler2D NormalMapTexture; layout (binding = 2) uniform sampler2D SpecularMapTexture; layout (binding = 3) uniform sampler2D GlowMapTexture; +layout (binding = 4) uniform sampler2D DepthMap; #define TILE_SIZE 16 @@ -56,6 +57,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace; }Input; out vec4 sceneColor; @@ -112,6 +114,45 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } +//float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampler2D depthTexture) +//{ +// // perform perspective divide +// //vec3 projCoords = positionLightSpace.xyz / positionLightSpace.w; +// // Transform to [0,1] range +// //projCoords = projCoords * 0.5 + 0.5; +// // Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) +// float closestDepth = texture(depthTexture, positionLightSpace.xy).r; +// // Get depth of current fragment from light's perspective +// float currentDepth = positionLightSpace.z; +// // Check whether current frag pos is in shadow +// float shadow = currentDepth > closestDepth ? 1.0 : 0.0; +// +// return shadow; +// +//} + +float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampler2D depthTexture) +{ + + //float bias = max(0.05 * (1.0 - dot(normal, -lightDir)), 0.005); + // perform perspective divide + vec3 projCoords = positionLightSpace.xyz / positionLightSpace.w; + // Transform to [0,1] range + projCoords = projCoords * 0.5 + 0.5; + // Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) + //float lightDepth = texture(depthTexture, positionLightSpace.xy).r; + float closestDepth = texture(depthTexture, projCoords.xy).r; + // Get depth of current fragment from light's perspective + //float currentDepth = positionLightSpace.z; + float currentDepth = projCoords.z; + // Check whether current frag pos is in shadow + float shadow = currentDepth /*- bias*/ > closestDepth ? 1.0 : 0.0; + // float shadow = currentDepth > closestDepth ? 1.0 : 0.0; + + return shadow; + +} + void main() { vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); @@ -134,24 +175,42 @@ void main() int start = int(LightGrids.Data[currentTile].Start); int amount = int(LightGrids.Data[currentTile].Amount); + float shadowFactor = 1.0; + for(int i = start; i < start + amount; i++) { int l = int(LightIndex[i]); LightSource light = LightSources.List[l]; - + LightResult light_result; //These if statements should be removed. if(light.Type == 1) { // point light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); } else if (light.Type == 2) { //Directional light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); + shadowFactor = CalcShadowValue(Input.PositionLightSpace, normal, light.Direction, DepthMap); } + totalLighting.Diffuse += light_result.Diffuse; - totalLighting.Specular += light_result.Specular; + totalLighting.Specular += light_result.Specular; } + totalLighting.Diffuse += (1.0 - shadowFactor); + totalLighting.Specular += (1.0 - shadowFactor); + //LightResult getInformation; + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + + //color_result = (totalLighting.Diffuse + (1.0 - shadowFactor) * (getInformation.Diffuse + (getInformation.Specular * specularTexel))) * color_result; + + + + + + + + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index 3b3e931c..21f3f370 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -3,6 +3,9 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; +uniform mat4 lightSpaceMatrix; // Shadow map PV +uniform mat4 LightV; +uniform mat4 LightP; uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; @@ -21,8 +24,17 @@ out VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace; }Output; +// N +mat4 biasMatrix = mat4( +vec4(0.5, 0.0, 0.0, 0.0), +vec4(0.0, 0.5, 0.0, 0.0), +vec4(0.0, 0.0, 0.5, 0.0), +vec4(0.5, 0.5, 0.5, 1.0) +); + void main() { @@ -34,9 +46,12 @@ void main() + BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[3] * Bones[int(BoneIndices[3])]; } - - gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + //vec4 lightPos = biasMatrix * LightP * LightV * M * vec4(Position, 1.0); // N + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + //gl_Position = lightPos; // N + Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; Output.TextureCoordinate = TextureCoords; Output.Normal = vec3(M * vec4(Normal, 0.0)); @@ -44,4 +59,7 @@ void main() Output.BiTangent = vec3(M * vec4(BiTangent, 0.0)); Output.ExplosionColor = vec4(1.0); Output.ExplosionPercentageElapsed = 0.0; + + //Output.PositionLightSpace = lightPos; // N + Output.PositionLightSpace = lightSpaceMatrix * (M * vec4(Position, 1.0)); } \ No newline at end of file diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8247797e..3e74cd1a 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -1,9 +1,10 @@ #include "Rendering/DrawFinalPass.h" -DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass) +DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, ShadowPass* shadowPass) { m_Renderer = renderer; m_LightCullingPass = lightCullingPass; + m_ShadowPass = shadowPass; InitializeTextures(); InitializeShaderPrograms(); InitializeFrameBuffers(); @@ -242,6 +243,16 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrFillPercentage); glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor)); + //Shadow + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(m_ShadowPass->lightSpaceMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), 1, GL_FALSE, glm::value_ptr(m_ShadowPass->lightP())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), 1, GL_FALSE, glm::value_ptr(m_ShadowPass->lightV())); + //GLfloat m_NearFarPlane[2] = { -40.f, 30.f }; + //GLfloat m_LRBT[4] = { -40.f, 100.f, -50.f, 50.f }; + //glm::mat4 m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + //glm::mat4 m_LightView = glm::lookAt(glm::vec3(-20.0f, 20.0f, -20.0f), glm::vec3(0.0f), glm::vec3(1.0)); + //glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); + //glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), 1, GL_FALSE, glm::value_ptr(m_LightView)); GLERROR("END"); } @@ -306,5 +317,12 @@ void DrawFinalPass::BindModelTextures(std::shared_ptr& job) } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); } + + glActiveTexture(GL_TEXTURE4); + if (m_ShadowPass->DepthMap() != NULL) { + glBindTexture(GL_TEXTURE_2D, m_ShadowPass->DepthMap()); + } else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 4f83122e..44ffb20e 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -49,7 +49,6 @@ void FrameBuffer::Generate() case GL_TEXTURE_2D: glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); GLERROR("FrameBuffer generate: glFramebufferTexture2D"); - break; case GL_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 147fed65..f8e1cd6b 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -138,7 +138,6 @@ void Renderer::Draw(RenderFrame& frame) } if (m_DebugTextureToDraw == 5) { m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); - // m_DrawScreenQuadPass->Draw(); } m_ImGuiRenderPass->Draw(); @@ -179,9 +178,9 @@ void Renderer::InitializeRenderPasses() { m_PickingPass = new PickingPass(this, m_EventBroker); m_LightCullingPass = new LightCullingPass(this); - m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass); + m_ShadowPass = new ShadowPass(this); + m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_ShadowPass); m_DrawScreenQuadPass = new DrawScreenQuadPass(this); m_DrawBloomPass = new DrawBloomPass(this); m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this); - m_ShadowPass = new ShadowPass(this); } diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 84c0de87..9855917c 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -71,23 +71,20 @@ void ShadowPass::Draw(RenderScene & scene) //} ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); + ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); for (auto &job : scene.DirectionalLightJobs) { auto directionalLightJob = std::dynamic_pointer_cast(job); if(directionalLightJob) { - glm::mat4 lightProjection = glm::ortho(m_LRBT[0], m_LRBT[1], m_LRBT[2], m_LRBT[3], m_NearPlane, m_FarPlane); + //m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + m_LightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)), glm::vec3(0.f,0.f,0.f), glm::vec3(0.f,1.f,0.f)); + //m_LightView = glm::lookAt(glm::vec3(-20.0f, 20.0f, -20.0f), glm::vec3(0.0f), glm::vec3(1.0)); + m_LightSpaceMatrix = m_LightProjection * m_LightView; - // broken? - glm::mat4 lightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)) * (float)20.0 , glm::vec3(0,0,0), glm::vec3(0,1,0)); - //glm::mat4 lightView = glm::lookAt(glm::vec3(10.f, 10.f, 50.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)); - //glm::mat4 lightSpaceMatrix = lightProjection * lightView; - - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(lightProjection)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(lightView)); - - /* glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));*/ + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView)); GLERROR("ShadowLight ERROR");