From 7f1016476b80878d0374da7e79d948a787fa636c Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Fri, 5 Feb 2016 15:08:56 +0100 Subject: [PATCH 01/35] Shadows WIP - create 2D texture (depthmap) --- .../Engine/Rendering/DirectionalLightJob.h | 5 +- include/Engine/Rendering/Renderer.h | 2 + include/Engine/Rendering/ShadowPass.cpp | 124 ++ include/Engine/Rendering/ShadowPass.h | 50 + include/Engine/Rendering/ShadowPassState.h | 15 + resources/Schema/Entities/OliviaTestWorld.xml | 1558 +++++++++++++++++ resources/Shaders/Shadow.frag.glsl | 18 + resources/Shaders/Shadow.vert.glsl | 17 + src/Engine/Rendering/FrameBuffer.cpp | 2 +- src/Engine/Rendering/Renderer.cpp | 9 +- src/Engine/Rendering/ShadowPassState.cpp | 16 + 11 files changed, 1812 insertions(+), 4 deletions(-) create mode 100644 include/Engine/Rendering/ShadowPass.cpp create mode 100644 include/Engine/Rendering/ShadowPass.h create mode 100644 include/Engine/Rendering/ShadowPassState.h create mode 100644 resources/Schema/Entities/OliviaTestWorld.xml create mode 100644 resources/Shaders/Shadow.frag.glsl create mode 100644 resources/Shaders/Shadow.vert.glsl create mode 100644 src/Engine/Rendering/ShadowPassState.cpp diff --git a/include/Engine/Rendering/DirectionalLightJob.h b/include/Engine/Rendering/DirectionalLightJob.h index 5f104ca5..0fcfaf84 100644 --- a/include/Engine/Rendering/DirectionalLightJob.h +++ b/include/Engine/Rendering/DirectionalLightJob.h @@ -15,13 +15,14 @@ struct DirectionalLightJob : RenderJob DirectionalLightJob(ComponentWrapper transformComponent, ComponentWrapper directionalLightComponent, World* m_World) : RenderJob() { - - Direction = glm::vec4(0,0,-1,0) * glm::inverse(Transform::AbsoluteOrientation(m_World, transformComponent.EntityID)); + Orientation = Transform::AbsoluteOrientation(m_World, transformComponent.EntityID); + Direction = glm::vec4(0,0,-1,0) * glm::inverse(Orientation); //Direction = glm::vec4((glm::vec3)directionalLightComponent["Direction"], 0.f); Color = (glm::vec4)directionalLightComponent["Color"]; Intensity = (double)directionalLightComponent["Intensity"]; }; + glm::quat Orientation; glm::vec4 Direction; glm::vec4 Color; float Intensity; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 33a61edf..74338e40 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -22,6 +22,7 @@ #include "../Core/Transform.h" #include "imgui/imgui.h" #include "TextPass.h" +#include "ShadowPass.h" class Renderer : public IRenderer { @@ -57,6 +58,7 @@ private: DrawScreenQuadPass* m_DrawScreenQuadPass; DrawBloomPass* m_DrawBloomPass; DrawColorCorrectionPass* m_DrawColorCorrectionPass; + ShadowPass* m_ShadowPass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/include/Engine/Rendering/ShadowPass.cpp b/include/Engine/Rendering/ShadowPass.cpp new file mode 100644 index 00000000..94844d1f --- /dev/null +++ b/include/Engine/Rendering/ShadowPass.cpp @@ -0,0 +1,124 @@ +#include "ShadowPass.h" + +ShadowPass::ShadowPass(IRenderer * renderer) +{ + m_Renderer = renderer; + + //InitializeTextures(); + InitializeFrameBuffers(); + InitializeShaderPrograms(); +} + +ShadowPass::~ShadowPass() +{ + +} + + +void ShadowPass::InitializeFrameBuffers() +{ + +// glGenRenderbuffers(1, &m_DepthFBO); +// glBindRenderbuffer(GL_RENDERBUFFER, m_DepthFBO); +// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + + // Depth texture + glGenTextures(1, &m_DepthMap); + glBindTexture(GL_TEXTURE_2D, m_DepthMap); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); + //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); + m_DepthBuffer.Generate(); + + GLERROR("depthMap failed"); + +} + +void ShadowPass::InitializeShaderPrograms() +{ + m_ShadowProgram = ResourceManager::Load("#ShadowProgram"); + m_ShadowProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Shadow.vert.glsl"))); + m_ShadowProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Shadow.frag.glsl"))); + m_ShadowProgram->Compile(); + m_ShadowProgram->BindFragDataLocation(0, "ShadowMap"); + m_ShadowProgram->Link(); +} + +void ShadowPass::ClearBuffer() +{ + m_DepthBuffer.Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_DepthBuffer.Unbind(); +} + +void ShadowPass::Draw(RenderScene & scene) +{ + ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); + + GLuint shaderHandle = m_ShadowProgram->GetHandle(); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + m_ShadowProgram->Bind(); + + //if (scene.ClearDepth) { + // glClear(GL_COLOR_BUFFER_BIT); + //} + + for (auto &job : scene.DirectionalLightJobs) { + auto directionalLightJob = std::dynamic_pointer_cast(job); + + if(directionalLightJob) { + + GLfloat near_plane = 1.0f, far_plane = 200.5f; + glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); + + // broken? + //glm::mat4 lightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)), glm::vec3(0,0,0), glm::vec3(0,1,0)); + glm::mat4 lightView = glm::lookAt(glm::vec3(50.f, 50.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(scene.Camera->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + + GLERROR("ShadowLight ERROR"); + + for (auto &objectJob : scene.OpaqueObjects) { + auto modelJob = std::dynamic_pointer_cast(objectJob); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + + GLERROR("Shadow Draw ERROR"); + + } + + } + + m_DepthBuffer.Unbind(); + + delete state; + + + } + + + + + //m_ShadowProgram->Unbind(); + + + + + +} diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h new file mode 100644 index 00000000..c578339e --- /dev/null +++ b/include/Engine/Rendering/ShadowPass.h @@ -0,0 +1,50 @@ +#ifndef ShadowPass_h_ +#define ShadowPass_h_ + +#include "IRenderer.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "../Core/EventBroker.h" +#include "../Core/World.h" +#include "ShadowPassState.h" + +//#include "ShadowPassState.h" // not created yet + + + +class ShadowPass +{ +public: + + ShadowPass(IRenderer* renderer); + ~ShadowPass(); + + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + void ClearBuffer(); + void Draw(RenderScene& scene); + + + + GLuint DepthMap() const { return m_DepthMap; } + + +private: + + + + EventBroker* m_EventBroker; + + const IRenderer* m_Renderer; + + GLuint m_DepthMap; + + FrameBuffer m_DepthBuffer; + + ShaderProgram* m_ShadowProgram; + + GLuint m_DepthFBO; + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/ShadowPassState.h b/include/Engine/Rendering/ShadowPassState.h new file mode 100644 index 00000000..ec08a77c --- /dev/null +++ b/include/Engine/Rendering/ShadowPassState.h @@ -0,0 +1,15 @@ +#ifndef ShadowPassState_h_ +#define ShadowPassState_h_ + +#include "Rendering/RenderState.h" + +class ShadowPassState : public RenderState +{ +public: + ShadowPassState(GLuint frameBuffer); + ~ShadowPassState(); + +private: +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Entities/OliviaTestWorld.xml b/resources/Schema/Entities/OliviaTestWorld.xml new file mode 100644 index 00000000..23c2b283 --- /dev/null +++ b/resources/Schema/Entities/OliviaTestWorld.xml @@ -0,0 +1,1558 @@ + + + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + 90 + + + + + + + + + + + + 1 + + + + + + + + + + + Audio/crosscounter.wav + true + + + + + + + + + + SoundEmitter + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + Sound Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + 0.80000001192092896 + + + Models/DirectionalLightWidget.mesh + + + 1 + + + + + + + + + + + + + + + + + + + + + Run + + 1 + + + models/AssaultAnimated.mesh + + + + + + + + + + + Walk + + 1 + + + models/AssaultAnimated.mesh + + + + + + + + + Animation test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Run + + 1 + + + Models/AssaultAnimated.mesh + + + + + + + + + + + + + + + + + + + + + + + + models/NormSpecIncdMapSphere.mesh + + + + + + + + + 1 + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 3 + 1.1399998664855957 + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 5.0100002288818359 + 0.69999998807907104 + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 4 + 0.80000001192092896 + + + + + + + + + + + + + + 1 + + + + + + + + + + + Models/NormalMapSphere.mesh + + + + + + + + + + + Models/SpecularMapSphere.mesh + + + + + + + + + + 1 + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + 3 + 1.1399998664855957 + + + + + + + + + + + + + + + + Models/IncandescenceMapSphere.mesh + + + + + + + + + + + + + TextureMap's Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + 1.3999999761581421 + + + + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + Models/Assault.mesh + + + + + + + + + + + + + + Spawn Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + true + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + Models/Core/UnitRaptor.mesh + + true + + + + + + + + + + + Models/Assault.mesh + + true + + + + + + + + + + + + Models/Core/UnitCube.mesh + + true + + + + + + + + + + + + + Transparency Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/AssaultBlueWeapon.mesh + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/AssaultRedWeapon.mesh + + + + + + + + + + + + + + + + Asset Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/SecondaryWeapon.mesh + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/AssualtSoft.mesh + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/DefenderGunBlue.mesh + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/DefenderGunRed.mesh + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Models/Assualt.mesh + + + + + + + + + + + + + + + + + + + + + + + + CapturePoint Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Models/CapturePoint.mesh + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + true + + + + + + + + + + + + + + + + + + Red team home point + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + Models/CapturePoint.mesh + + + + + + + + + + + 1 + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + RedMiddle Point + Fonts/DroidSans.ttf + + + + + + + + + + + + + + + Models/CapturePoint.mesh + + + + + + + + + 2 + + + Models/Core/UnitCube.mesh + true + + + + + + + + + + + + + + Middle Point + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + Models/CapturePoint.mesh + + + + + + + + + + + -12.033302729641917 + 3 + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + BlueMiddle Point + Fonts/DroidSans.ttf + + + + + + + + + + + + + + + Models/CapturePoint.mesh + + + + + + + + + + + + + + 4 + + + Models/Core/UnitCube.mesh + + true + + + + + + + + + + + + + + + + + + Blue team home point + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Test/ObstacleCourse.mesh + + + + + + + + + + + Collision Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + true + + 2.3331127968986038 + 3.7999999523162842 + + true + + + Models/AssaultWeaponBlue.mesh + true + + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + + + 0.28322599621543532 + + + Models/Assault.mesh + true + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + Walk + + 1 + + + true + + + 1.8831113377486872 + + true + + + Models/AssaultAnimated.mesh + true + + + + + + + + + + + + + + + ExplosionEffect Test + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + Remember to pick random entities. + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl new file mode 100644 index 00000000..04cc05df --- /dev/null +++ b/resources/Shaders/Shadow.frag.glsl @@ -0,0 +1,18 @@ +#version 430 + + + +in VertexData{ + vec3 Position; +}Input; + +//layout(location = 0 ) out vec4 ShadowMap; +layout(location = 0 ) out float ShadowMap; + +void main() +{ + //ShadowMap = vec4(vec3(gl_FragCoord.z), 1.0); + //ShadowMap = gl_FragCoord.z; +} + + diff --git a/resources/Shaders/Shadow.vert.glsl b/resources/Shaders/Shadow.vert.glsl new file mode 100644 index 00000000..cc1ee0a9 --- /dev/null +++ b/resources/Shaders/Shadow.vert.glsl @@ -0,0 +1,17 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + Output.Position = Position; + gl_Position = P * V * M * vec4(Position, 1.0); +} \ No newline at end of file diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 9677f50e..4f83122e 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -58,7 +58,7 @@ void FrameBuffer::Generate() } - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { + if ((*it)->m_ResourceType == GL_TEXTURE_2D) { attachments.push_back((*it)->m_Attachment); } } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a63e02a0..147fed65 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -93,7 +93,7 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& frame) { - ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking"); + ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Shadow"); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -102,11 +102,13 @@ void Renderer::Draw(RenderFrame& frame) m_PickingPass->ClearPicking(); m_DrawFinalPass->ClearBuffer(); m_DrawBloomPass->ClearBuffer(); + m_ShadowPass->ClearBuffer(); for (auto scene : frame.RenderScenes){ SortRenderJobsByDepth(*scene); m_PickingPass->Draw(*scene); + m_ShadowPass->Draw(*scene); m_LightCullingPass->GenerateNewFrustum(*scene); m_LightCullingPass->FillLightList(*scene); m_LightCullingPass->CullLights(*scene); @@ -133,6 +135,10 @@ void Renderer::Draw(RenderFrame& frame) } if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); + } + if (m_DebugTextureToDraw == 5) { + m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); + // m_DrawScreenQuadPass->Draw(); } m_ImGuiRenderPass->Draw(); @@ -177,4 +183,5 @@ void Renderer::InitializeRenderPasses() 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/ShadowPassState.cpp b/src/Engine/Rendering/ShadowPassState.cpp new file mode 100644 index 00000000..caa09b9f --- /dev/null +++ b/src/Engine/Rendering/ShadowPassState.cpp @@ -0,0 +1,16 @@ +#include "Rendering/ShadowPassState.h" + +ShadowPassState::ShadowPassState(GLuint frameBuffer) +{ + GLERROR("---2"); + BindFramebuffer(frameBuffer); + GLERROR("---3"); + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + Disable(GL_BLEND); +} + +ShadowPassState::~ShadowPassState() +{ + +} \ No newline at end of file From c912cd7a428492c0b659a88a1611a3adb8c1490e Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Fri, 5 Feb 2016 15:12:17 +0100 Subject: [PATCH 02/35] Shadows wip --- include/Engine/Rendering/ShadowPass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.cpp b/include/Engine/Rendering/ShadowPass.cpp index 94844d1f..2fe14238 100644 --- a/include/Engine/Rendering/ShadowPass.cpp +++ b/include/Engine/Rendering/ShadowPass.cpp @@ -62,10 +62,10 @@ void ShadowPass::ClearBuffer() void ShadowPass::Draw(RenderScene & scene) { ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); - - GLuint shaderHandle = m_ShadowProgram->GetHandle(); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); + + GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); //if (scene.ClearDepth) { From 0e51ae7dc91e6cb8a85d369a550cff6ba811166d Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Fri, 5 Feb 2016 15:31:20 +0100 Subject: [PATCH 03/35] shadow wip --- assets | 2 +- include/Engine/Rendering/ShadowPass.cpp | 2 -- resources/Shaders/Shadow.frag.glsl | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assets b/assets index c4898d82..091ad5c0 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c4898d8281b5584d89b1caf14dab8e5fac120321 +Subproject commit 091ad5c01bf7b6ef5501fc907fc610576a4a45ea diff --git a/include/Engine/Rendering/ShadowPass.cpp b/include/Engine/Rendering/ShadowPass.cpp index 2fe14238..33549d03 100644 --- a/include/Engine/Rendering/ShadowPass.cpp +++ b/include/Engine/Rendering/ShadowPass.cpp @@ -62,8 +62,6 @@ void ShadowPass::ClearBuffer() void ShadowPass::Draw(RenderScene & scene) { ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index 04cc05df..b2f7115b 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -12,7 +12,7 @@ layout(location = 0 ) out float ShadowMap; void main() { //ShadowMap = vec4(vec3(gl_FragCoord.z), 1.0); - //ShadowMap = gl_FragCoord.z; + ShadowMap = (glgl_FragCoord.x, glgl_FragCoord.y, glgl_FragCoord.z); } From bbf6058c17d904873710c41e53bd1b6c1a2c49fb Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Fri, 5 Feb 2016 16:13:46 +0100 Subject: [PATCH 04/35] Shadow WIP - fixed file placing of ShadowPass.cpp --- resources/Shaders/Shadow.frag.glsl | 2 +- .../Engine/Rendering/ShadowPass.cpp | 23 +++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) rename {include => src}/Engine/Rendering/ShadowPass.cpp (78%) diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index b2f7115b..983cc828 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -12,7 +12,7 @@ layout(location = 0 ) out float ShadowMap; void main() { //ShadowMap = vec4(vec3(gl_FragCoord.z), 1.0); - ShadowMap = (glgl_FragCoord.x, glgl_FragCoord.y, glgl_FragCoord.z); + ShadowMap = (gl_FragCoord.z); } diff --git a/include/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp similarity index 78% rename from include/Engine/Rendering/ShadowPass.cpp rename to src/Engine/Rendering/ShadowPass.cpp index 33549d03..56fcbe7a 100644 --- a/include/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -1,4 +1,4 @@ -#include "ShadowPass.h" +#include "Rendering/ShadowPass.h" ShadowPass::ShadowPass(IRenderer * renderer) { @@ -26,15 +26,15 @@ void ShadowPass::InitializeFrameBuffers() glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); - //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); + //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); m_DepthBuffer.Generate(); GLERROR("depthMap failed"); @@ -75,16 +75,19 @@ void ShadowPass::Draw(RenderScene & scene) if(directionalLightJob) { - GLfloat near_plane = 1.0f, far_plane = 200.5f; + GLfloat near_plane = 1.0f, far_plane = 75.5f; glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); // broken? - //glm::mat4 lightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)), glm::vec3(0,0,0), glm::vec3(0,1,0)); - glm::mat4 lightView = glm::lookAt(glm::vec3(50.f, 50.f, 50.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)); + glm::mat4 lightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)) * (float)50.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(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(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()));*/ GLERROR("ShadowLight ERROR"); From 6542d1b44445458651cb9f96dbc9b1458eca29c9 Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Fri, 5 Feb 2016 17:29:53 +0100 Subject: [PATCH 05/35] Shadow WIP - DepthTexture working --- include/Engine/Rendering/ShadowPass.h | 9 +++++++++ resources/Shaders/Shadow.frag.glsl | 8 ++++---- resources/Shaders/Shadow.vert.glsl | 8 ++++---- src/Engine/Rendering/ShadowPass.cpp | 16 ++++++++-------- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index c578339e..6a00dacd 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -7,6 +7,7 @@ #include "../Core/EventBroker.h" #include "../Core/World.h" #include "ShadowPassState.h" +#include "imgui/imgui.h" //#include "ShadowPassState.h" // not created yet @@ -45,6 +46,14 @@ 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_LRBT[4] = { -40.f, 100.f, -50.f, 50.f }; + }; #endif \ No newline at end of file diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index 983cc828..798d1cda 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -2,9 +2,9 @@ -in VertexData{ - vec3 Position; -}Input; +//in VertexData{ +// vec3 Position; +//}Input; //layout(location = 0 ) out vec4 ShadowMap; layout(location = 0 ) out float ShadowMap; @@ -12,7 +12,7 @@ layout(location = 0 ) out float ShadowMap; void main() { //ShadowMap = vec4(vec3(gl_FragCoord.z), 1.0); - ShadowMap = (gl_FragCoord.z); + //ShadowMap = (gl_FragCoord.z); } diff --git a/resources/Shaders/Shadow.vert.glsl b/resources/Shaders/Shadow.vert.glsl index cc1ee0a9..16c0b26e 100644 --- a/resources/Shaders/Shadow.vert.glsl +++ b/resources/Shaders/Shadow.vert.glsl @@ -6,12 +6,12 @@ uniform mat4 P; layout(location = 0) in vec3 Position; -out VertexData{ - vec3 Position; -}Output; +//out VertexData{ +// vec3 Position; +//}Output; void main() { - Output.Position = Position; +// Output.Position = Position; gl_Position = P * V * M * vec4(Position, 1.0); } \ No newline at end of file diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 56fcbe7a..84c0de87 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -26,15 +26,15 @@ void ShadowPass::InitializeFrameBuffers() glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); - m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); + //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); m_DepthBuffer.Generate(); GLERROR("depthMap failed"); @@ -70,16 +70,16 @@ void ShadowPass::Draw(RenderScene & scene) // glClear(GL_COLOR_BUFFER_BIT); //} + ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); + for (auto &job : scene.DirectionalLightJobs) { auto directionalLightJob = std::dynamic_pointer_cast(job); if(directionalLightJob) { - - GLfloat near_plane = 1.0f, far_plane = 75.5f; - glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); + glm::mat4 lightProjection = glm::ortho(m_LRBT[0], m_LRBT[1], m_LRBT[2], m_LRBT[3], m_NearPlane, m_FarPlane); // broken? - glm::mat4 lightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)) * (float)50.0 , glm::vec3(0,0,0), glm::vec3(0,1,0)); + 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; From cb7f06573fbea083af3c666f4185a5cadabc14a3 Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Tue, 9 Feb 2016 14:08:57 +0100 Subject: [PATCH 06/35] 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"); From 847c539373ba58548bf010a96e60ac66a56b44dc Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Tue, 9 Feb 2016 14:44:12 +0100 Subject: [PATCH 07/35] Fix viewport --- resources/Shaders/ForwardPlus.frag.glsl | 21 ++------------------- resources/Shaders/ForwardPlus.vert.glsl | 4 ++-- src/Engine/Rendering/ShadowPass.cpp | 5 ++--- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index d54de713..56809878 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -114,27 +114,10 @@ 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); + 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 @@ -188,7 +171,7 @@ void main() 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); + shadowFactor = CalcShadowValue(Input.PositionLightSpace, vec4(Input.Normal, 0.0), light.Direction, DepthMap); } totalLighting.Diffuse += light_result.Diffuse; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index 21f3f370..bde356e9 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -47,7 +47,7 @@ void main() + BoneWeights[3] * Bones[int(BoneIndices[3])]; } - //vec4 lightPos = biasMatrix * LightP * LightV * M * vec4(Position, 1.0); // N + //vec4 lightPos = LightP * LightV * M * vec4(Position, 1.0); // N gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); //gl_Position = lightPos; // N @@ -61,5 +61,5 @@ void main() Output.ExplosionPercentageElapsed = 0.0; //Output.PositionLightSpace = lightPos; // N - Output.PositionLightSpace = lightSpaceMatrix * (M * vec4(Position, 1.0)); + Output.PositionLightSpace = lightSpaceMatrix * M * vec4(Position, 1.0); } \ No newline at end of file diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 9855917c..3ae83773 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -25,9 +25,8 @@ void ShadowPass::InitializeFrameBuffers() // Depth texture glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); From ecd823cb9f59843a2d67be0711a18f3daef4d166 Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Tue, 9 Feb 2016 16:15:11 +0100 Subject: [PATCH 08/35] Shadow WIP stage 2 - Soft shadow --- include/Engine/Rendering/ShadowPass.h | 8 ++++++-- resources/Shaders/ForwardPlus.frag.glsl | 22 +++++++++++++++++++++- src/Engine/Rendering/ShadowPass.cpp | 13 +++++++------ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index a8f41502..301af9a5 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -32,8 +32,8 @@ public: 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 + + void setResolution(GLuint width, GLuint height) { resolutionSizeWidth = width; resolutionSizeHeigth = height; } private: @@ -57,6 +57,10 @@ private: glm::mat4 m_LightProjection; glm::mat4 m_LightView; glm::mat4 m_LightSpaceMatrix; + + GLuint resolutionSizeWidth = 2048; + GLuint resolutionSizeHeigth = 2048; + }; #endif \ No newline at end of file diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 56809878..cf3b3ed0 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -114,6 +114,13 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } +vec2 poissonDisk[4] = vec2[]( + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ) + ); + float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampler2D depthTexture) { @@ -129,8 +136,21 @@ float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampl //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 - bias > closestDepth ? 1.0 : 0.0; // float shadow = currentDepth > closestDepth ? 1.0 : 0.0; + + float shadow = 0.0; + //soft shadow - using percentage-closer filtering (PCF) is to simply sample the surrounding texels of the depth map and average the results: + vec2 texelSize = 1.0 / textureSize(depthTexture, 0); + for(int x = -1; x <= 1; ++x) + { + for(int y = -1; y <= 1; ++y) + { + float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; + shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; + } + } + shadow /= 9.0; return shadow; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 3ae83773..c6bb4313 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -25,7 +25,7 @@ void ShadowPass::InitializeFrameBuffers() // Depth texture glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -65,9 +65,9 @@ void ShadowPass::Draw(RenderScene & scene) GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); - //if (scene.ClearDepth) { - // glClear(GL_COLOR_BUFFER_BIT); - //} + glViewport(0, 0, resolutionSizeWidth, resolutionSizeHeigth); + glCullFace(GL_FRONT); + ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); @@ -111,8 +111,9 @@ void ShadowPass::Draw(RenderScene & scene) - - //m_ShadowProgram->Unbind(); + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glCullFace(GL_BACK); + m_ShadowProgram->Unbind(); From 6af167675d102f02a40df9291371b51768707d86 Mon Sep 17 00:00:00 2001 From: Ayumiwii Date: Wed, 10 Feb 2016 11:48:44 +0100 Subject: [PATCH 09/35] Shadow WIP stage 2 - fix cel-shading --- include/Engine/Rendering/ShadowPass.h | 9 ++-- resources/Shaders/ForwardPlus.frag.glsl | 32 +++++++------ src/Engine/Rendering/ShadowPass.cpp | 61 +++++++++++++------------ 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 301af9a5..e26045db 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -51,16 +51,17 @@ private: GLuint m_DepthFBO; - GLfloat m_NearFarPlane[2] = { -40.f, 30.f }; - GLfloat m_LRBT[4] = { -40.f, 100.f, -50.f, 50.f }; + GLfloat m_NearFarPlane[2] = { -84.f, 28.f }; + GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f }; glm::mat4 m_LightProjection; glm::mat4 m_LightView; glm::mat4 m_LightSpaceMatrix; - GLuint resolutionSizeWidth = 2048; - GLuint resolutionSizeHeigth = 2048; + GLuint resolutionSizeWidth = 2048 * 4; + GLuint resolutionSizeHeigth = 2048 * 4; + bool m_ShadowOn = true; }; #endif \ No newline at end of file diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index cf3b3ed0..a82555c8 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -124,7 +124,8 @@ vec2 poissonDisk[4] = vec2[]( float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampler2D depthTexture) { - float bias = max(0.05 * (1.0 - dot(normal, -lightDir)), 0.005); + float bias = 0.005; + //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 @@ -136,21 +137,26 @@ float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampl //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; + float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; + //float shadow = currentDepth > closestDepth ? 1.0 : 0.0; - float shadow = 0.0; - //soft shadow - using percentage-closer filtering (PCF) is to simply sample the surrounding texels of the depth map and average the results: - vec2 texelSize = 1.0 / textureSize(depthTexture, 0); - for(int x = -1; x <= 1; ++x) + //float shadow = 0.0; + ////soft shadow - using percentage-closer filtering (PCF) is to simply sample the surrounding texels of the depth map and average the results: + //vec2 texelSize = 1.0 / textureSize(depthTexture, 0); + //for(int x = -1; x <= 1; ++x) + //{ + // for(int y = -1; y <= 1; ++y) + // { + // float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; + // shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; + // } + //} + //shadow /= 9.0; + // + if(projCoords.z > 0.9) { - for(int y = -1; y <= 1; ++y) - { - float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; - shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; - } + shadow = 1.0; } - shadow /= 9.0; return shadow; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index c6bb4313..61e37da3 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -25,13 +25,14 @@ void ShadowPass::InitializeFrameBuffers() // Depth texture glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); m_DepthBuffer.Generate(); @@ -66,47 +67,51 @@ void ShadowPass::Draw(RenderScene & scene) m_ShadowProgram->Bind(); glViewport(0, 0, resolutionSizeWidth, resolutionSizeHeigth); - glCullFace(GL_FRONT); - + glCullFace(GL_BACK); + //state->Disable(GL_CULL_FACE); ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); + ImGui::Checkbox("EnableShadow", &m_ShadowOn); - for (auto &job : scene.DirectionalLightJobs) { - auto directionalLightJob = std::dynamic_pointer_cast(job); + if (m_ShadowOn == true) + { + for (auto &job : scene.DirectionalLightJobs) { + auto directionalLightJob = std::dynamic_pointer_cast(job); - if(directionalLightJob) { - //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; + if(directionalLightJob) { + //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; - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView)); + 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"); + GLERROR("ShadowLight ERROR"); - for (auto &objectJob : scene.OpaqueObjects) { - auto modelJob = std::dynamic_pointer_cast(objectJob); + for (auto &objectJob : scene.OpaqueObjects) { + auto modelJob = std::dynamic_pointer_cast(objectJob); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - GLERROR("Shadow Draw ERROR"); + GLERROR("Shadow Draw ERROR"); - } + } + } + + m_DepthBuffer.Unbind(); + + delete state; + + } - - m_DepthBuffer.Unbind(); - - delete state; - - } From 69db32337ddb04557e8e60187782076249a5d253 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 10 Feb 2016 15:16:58 +0100 Subject: [PATCH 10/35] Shado wip --- include/Engine/Rendering/ShadowPass.h | 2 +- resources/Schema/Entities/GameMap.xml | 7 +++ resources/Shaders/ForwardPlus.frag.glsl | 63 +++++++++++-------------- src/Engine/Rendering/ShadowPass.cpp | 14 ++++-- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index e26045db..5acc376e 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -51,7 +51,7 @@ private: GLuint m_DepthFBO; - GLfloat m_NearFarPlane[2] = { -84.f, 28.f }; + GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f }; glm::mat4 m_LightProjection; diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 97fd3f4d..7b62b5d8 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -238,6 +238,13 @@ + + + + + + + diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index a82555c8..170a9d5a 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -13,7 +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; +layout (binding = 4) uniform sampler2DShadow DepthMap; #define TILE_SIZE 16 @@ -114,49 +114,39 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } -vec2 poissonDisk[4] = vec2[]( - vec2( -0.94201624, -0.39906216 ), - vec2( 0.94558609, -0.76890725 ), - vec2( -0.094184101, -0.92938870 ), - vec2( 0.34495938, 0.29387760 ) - ); - -float CalcShadowValue(vec4 positionLightSpace, vec4 normal, vec4 lightDir, sampler2D depthTexture) +float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampler2DShadow depthTexture) { float bias = 0.005; - //float bias = max(0.05 * (1.0 - dot(normal, -lightDir)), 0.005); - // perform perspective divide + //float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); + //float bias = 0.005 * tan(acos(clamp(dot(normal, lightDir), 0,1))); bias = clamp(bias, 0,0.01); + 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; - + //float shadowMapDepth = texture(depthTexture, projCoords.xy).r; + float shadowMapDepth = 1.0 - texture(depthTexture, projCoords); + float geometryDepth = projCoords.z; + //float shadow = geometryDepth - bias > shadowMapDepth ? 1.0 : 0.0; + //float shadow = geometryDepth - bias > shadowMapDepth ? 0.0 : 1.0; + float shadow = shadowMapDepth; + //float shadow = 0.0; - ////soft shadow - using percentage-closer filtering (PCF) is to simply sample the surrounding texels of the depth map and average the results: + //vec2 texelSize = 1.0 / textureSize(depthTexture, 0); - //for(int x = -1; x <= 1; ++x) + //for(int x = -1; x <= 1; x++) //{ - // for(int y = -1; y <= 1; ++y) + // for(int y = -1; y <= 1; y++) // { - // float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; - // shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; + // float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; + // shadow += geometryDepth - bias > pcfDepth ? 1.0 : 0.0; // } //} //shadow /= 9.0; - // - if(projCoords.z > 0.9) - { - shadow = 1.0; - } + + //if(projCoords.z > 1.0) + //{ + // shadow = 0.0; + //} return shadow; @@ -184,7 +174,7 @@ void main() int start = int(LightGrids.Data[currentTile].Start); int amount = int(LightGrids.Data[currentTile].Amount); - float shadowFactor = 1.0; + float shadowFactor = 0.0; for(int i = start; i < start + amount; i++) { @@ -197,15 +187,16 @@ void main() 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, vec4(Input.Normal, 0.0), light.Direction, DepthMap); + shadowFactor = CalcShadowValue(Input.PositionLightSpace, Input.Normal, vec3(light.Direction), DepthMap); } totalLighting.Diffuse += light_result.Diffuse; totalLighting.Specular += light_result.Specular; } - totalLighting.Diffuse += (1.0 - shadowFactor); - totalLighting.Specular += (1.0 - shadowFactor); + totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + //LightResult getInformation; vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 61e37da3..5ffd553f 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -25,12 +25,15 @@ void ShadowPass::InitializeFrameBuffers() // Depth texture glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D, m_DepthMap); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); @@ -67,7 +70,8 @@ void ShadowPass::Draw(RenderScene & scene) m_ShadowProgram->Bind(); glViewport(0, 0, resolutionSizeWidth, resolutionSizeHeigth); - glCullFace(GL_BACK); + + //glCullFace(GL_FRONT); //state->Disable(GL_CULL_FACE); ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); @@ -117,7 +121,7 @@ void ShadowPass::Draw(RenderScene & scene) glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - glCullFace(GL_BACK); + //glCullFace(GL_BACK); m_ShadowProgram->Unbind(); From cb77c1ff974fcb1f031f9fc3a6d1e12714533917 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 10 Feb 2016 16:16:41 +0100 Subject: [PATCH 11/35] Working pcf, not optimized --- include/Engine/Rendering/ShadowPass.h | 4 ++-- resources/Shaders/ForwardPlus.frag.glsl | 9 ++++----- src/Engine/Rendering/ShadowPass.cpp | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 5acc376e..7c93fcd8 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -58,8 +58,8 @@ private: glm::mat4 m_LightView; glm::mat4 m_LightSpaceMatrix; - GLuint resolutionSizeWidth = 2048 * 4; - GLuint resolutionSizeHeigth = 2048 * 4; + GLuint resolutionSizeWidth = 2048 * 2; + GLuint resolutionSizeHeigth = 2048 * 2; bool m_ShadowOn = true; }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 170a9d5a..ce71be28 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -121,16 +121,15 @@ float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampl //float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); //float bias = 0.005 * tan(acos(clamp(dot(normal, lightDir), 0,1))); bias = clamp(bias, 0,0.01); - vec3 projCoords = positionLightSpace.xyz / positionLightSpace.w; + vec3 projCoords = vec3(positionLightSpace.xy, positionLightSpace.z + bias) / positionLightSpace.w; projCoords = projCoords * 0.5 + 0.5; //float shadowMapDepth = texture(depthTexture, projCoords.xy).r; - float shadowMapDepth = 1.0 - texture(depthTexture, projCoords); + float shadowMapDepth = texture(depthTexture, projCoords); float geometryDepth = projCoords.z; //float shadow = geometryDepth - bias > shadowMapDepth ? 1.0 : 0.0; - //float shadow = geometryDepth - bias > shadowMapDepth ? 0.0 : 1.0; - float shadow = shadowMapDepth; + //float shadow = 1.0 - bias > shadowMapDepth ? 0.0 : 1.0; - //float shadow = 0.0; + float shadow = 1.0 - shadowMapDepth; //vec2 texelSize = 1.0 / textureSize(depthTexture, 0); //for(int x = -1; x <= 1; x++) diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 5ffd553f..fbf25219 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -33,7 +33,7 @@ void ShadowPass::InitializeFrameBuffers() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); @@ -71,7 +71,7 @@ void ShadowPass::Draw(RenderScene & scene) glViewport(0, 0, resolutionSizeWidth, resolutionSizeHeigth); - //glCullFace(GL_FRONT); + glCullFace(GL_FRONT); //state->Disable(GL_CULL_FACE); ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); @@ -121,7 +121,7 @@ void ShadowPass::Draw(RenderScene & scene) glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - //glCullFace(GL_BACK); + glCullFace(GL_BACK); m_ShadowProgram->Unbind(); From 36043010af52d4d346f6cd4423d0ac32513af655 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 10 Feb 2016 20:51:33 +0100 Subject: [PATCH 12/35] wip for shadows they work, but will be shit until we get cascaded. --- include/Engine/Rendering/ShadowPass.h | 4 +-- resources/Shaders/ForwardPlus.frag.glsl | 45 ++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 7c93fcd8..c5bf038e 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -58,8 +58,8 @@ private: glm::mat4 m_LightView; glm::mat4 m_LightSpaceMatrix; - GLuint resolutionSizeWidth = 2048 * 2; - GLuint resolutionSizeHeigth = 2048 * 2; + GLuint resolutionSizeWidth = 1024 * 8; + GLuint resolutionSizeHeigth = 1024 * 8; bool m_ShadowOn = true; }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index ce71be28..1157a019 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -114,18 +114,53 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } +vec2 poissonDisk[16] = vec2[]( + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ), + vec2( -0.91588581, 0.45771432 ), + vec2( -0.81544232, -0.87912464 ), + vec2( -0.38277543, 0.27676845 ), + vec2( 0.97484398, 0.75648379 ), + vec2( 0.44323325, -0.97511554 ), + vec2( 0.53742981, -0.47373420 ), + vec2( -0.26496911, -0.41893023 ), + vec2( 0.79197514, 0.19090188 ), + vec2( -0.24188840, 0.99706507 ), + vec2( -0.81409955, 0.91437590 ), + vec2( 0.19984126, 0.78641367 ), + vec2( 0.14383161, -0.14100790 ) +); + +float random(vec3 seed, int i) +{ + vec4 seed4 = vec4(seed, i); + float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673)); + return fract(sin(dot_product) * 43758.5453); +} + float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampler2DShadow depthTexture) { float bias = 0.005; //float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); - //float bias = 0.005 * tan(acos(clamp(dot(normal, lightDir), 0,1))); bias = clamp(bias, 0,0.01); + //float bias = 0.005 * tan(acos(clamp(dot(normal, -lightDir), 0.0, 1.0))); vec3 projCoords = vec3(positionLightSpace.xy, positionLightSpace.z + bias) / positionLightSpace.w; projCoords = projCoords * 0.5 + 0.5; //float shadowMapDepth = texture(depthTexture, projCoords.xy).r; - float shadowMapDepth = texture(depthTexture, projCoords); - float geometryDepth = projCoords.z; + float shadowMapDepth; + //for (int i = 0; i < 4; i++) + //{ + // int index = i; + // //int index = int(16.0 * random(gl_FragCoord.xyy, i)) % 16; + // shadowMapDepth += 0.25 * texture(depthTexture, projCoords + vec3(poissonDisk[index], 0.0) / 700.0); + //} + + shadowMapDepth = texture(depthTexture, projCoords); + + //float geometryDepth = projCoords.z; //float shadow = geometryDepth - bias > shadowMapDepth ? 1.0 : 0.0; //float shadow = 1.0 - bias > shadowMapDepth ? 0.0 : 1.0; @@ -193,8 +228,8 @@ void main() totalLighting.Specular += light_result.Specular; } - totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); //LightResult getInformation; From 178402e9646b11e3b0a61e189ba082161a228ac1 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 18 Feb 2016 10:08:29 +0100 Subject: [PATCH 13/35] cascade shadow wip --- include/Engine/Rendering/ShadowPass.h | 20 +++++- resources/Shaders/ForwardPlus.frag.glsl | 6 +- src/Engine/Editor/EditorRenderSystem.cpp | 2 +- src/Engine/Rendering/RenderSystem.cpp | 2 +- src/Engine/Rendering/ShadowPass.cpp | 91 ++++++++++++++++++++++-- 5 files changed, 108 insertions(+), 13 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index c5bf038e..685432c8 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -9,11 +9,18 @@ #include "ShadowPassState.h" #include "imgui/imgui.h" +#define MAX_SPLITS 5 + //#include "ShadowPassState.h" // not created yet enum NearFar { Near = 0, Far = 1 }; enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; +struct ShadowCamera{ + Camera* camera; + std::array frustumCorners; +}; + class ShadowPass { public: @@ -37,7 +44,10 @@ public: private: - + void CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob); + glm::vec3 LightDirectionToPoint(glm::vec4 direction); + std::array UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir); + void UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance); EventBroker* m_EventBroker; @@ -52,7 +62,8 @@ private: GLuint m_DepthFBO; GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; - GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f }; + //GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f }; + GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; glm::mat4 m_LightProjection; glm::mat4 m_LightView; @@ -62,6 +73,11 @@ private: GLuint resolutionSizeHeigth = 1024 * 8; bool m_ShadowOn = true; + + int m_CurrentNrOfSplits = 3; + float m_SplitWeight = 0.75f; + + std::array shadCams; }; #endif \ No newline at end of file diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 1157a019..205f1c5d 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -228,8 +228,10 @@ void main() totalLighting.Specular += light_result.Specular; } - totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + //totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + //totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0); + totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0); //LightResult getInformation; diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 4d65e9d3..1a521b88 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -7,7 +7,7 @@ EditorRenderSystem::EditorRenderSystem(World* m_World, EventBroker* eventBroker, { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorRenderSystem::OnSetCamera); auto resolution = Rectangle::Rectangle(1280, 720); - m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 5000.f); + m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 500.f); } void EditorRenderSystem::Update(double dt) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..03613842 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -10,7 +10,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); - m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); + m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 300.f); } RenderSystem::~RenderSystem() diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index fbf25219..ca7b59f0 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -14,6 +14,86 @@ ShadowPass::~ShadowPass() } +// Compute the 8 corner points of the current view frustum +std::array ShadowPass::UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir) +{ + glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); + glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); + + glm::vec3 farCenter = center + view_dir * cam->FarClip(); + glm::vec3 nearCenter = center + view_dir * cam->NearClip(); + + up = glm::normalize(glm::cross(right, view_dir)); + + float near_height = tan(cam->FOV() / 2.0f) * cam->NearClip(); + float near_width = near_height * cam->AspectRatio(); + float far_height = tan(cam->FOV() / 2.0f) * cam->FarClip(); + float far_width = far_height * cam->AspectRatio(); + + std::array frustumPoints; + frustumPoints[0] = nearCenter - up*near_height - right*near_width; + frustumPoints[1] = nearCenter + up*near_height - right*near_width; + frustumPoints[2] = nearCenter + up*near_height + right*near_width; + frustumPoints[3] = nearCenter - up*near_height + right*near_width; + + frustumPoints[4] = farCenter - up*far_height - right*far_width; + frustumPoints[5] = farCenter + up*far_height - right*far_width; + frustumPoints[6] = farCenter + up*far_height + right*far_width; + frustumPoints[7] = farCenter - up*far_height + right*far_width; + + return frustumPoints; +} + +// UpdateSplitDist computes the near and far distances for every frustum slice +// in camera eye space - that is, at what distance does a slice start and end +void ShadowPass::UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance) +{ + float lambda = m_SplitWeight; + float ratio = far_distance / near_distance; + + shadow_cams[0].camera->SetNearClip(near_distance); + + for (int i = 1; i < m_CurrentNrOfSplits; i++) { + float si = i / static_cast(m_CurrentNrOfSplits); + + shadow_cams[i].camera->SetNearClip(lambda * (near_distance * powf(ratio, si)) + (1 - lambda) * (near_distance + (far_distance - near_distance) * si)); + shadow_cams[i - 1].camera->SetFarClip(shadow_cams[i].camera->NearClip() * 1.005f); + } + + shadow_cams[m_CurrentNrOfSplits - 1].camera->SetFarClip(far_distance); +} + +float applyCropMatrix() +{ + +} + +// GLM wants a point for glm::lookAt, brute out a point that is on the light direction's tangent. +glm::vec3 ShadowPass::LightDirectionToPoint(glm::vec4 direction) +{ + return -glm::normalize(glm::vec3(direction)); +} + +void ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob) +{ + //m_LightView = glm::lookAt(LightDirectionToPoint(directionalLightJob->Direction), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)); + + m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + + glm::vec3 LightPoint = LightDirectionToPoint(directionalLightJob->Direction); + + float CameraDistance = scene.Camera->FarClip() - scene.Camera->NearClip(); + float CameraPercentiles[3] = { 0.f, CameraDistance * 0.2f, CameraDistance * 0.65f }; + + + glm::vec3 point = scene.Camera->Position() + (scene.Camera->Forward() * 30.f); + + m_LightView = glm::lookAt(LightPoint + point, point, glm::vec3(0.f, 1.f, 0.f)); + + m_LightSpaceMatrix = m_LightProjection * m_LightView; + + //scene.Camera-> +} void ShadowPass::InitializeFrameBuffers() { @@ -29,9 +109,10 @@ void ShadowPass::InitializeFrameBuffers() //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); @@ -84,11 +165,7 @@ void ShadowPass::Draw(RenderScene & scene) auto directionalLightJob = std::dynamic_pointer_cast(job); if(directionalLightJob) { - //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; + CalculateFrustum(scene, directionalLightJob); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView)); From bf376f54b627973f7950ae968336ce43273fc34b Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 18 Feb 2016 20:48:39 +0100 Subject: [PATCH 14/35] WIP I think this is now finding the different segments of the cascade --- include/Engine/Rendering/ShadowPass.h | 21 +- resources/Shaders/ForwardPlus.frag.glsl | 4 +- src/Engine/Editor/EditorSystem.cpp | 4 +- src/Engine/Rendering/ShadowPass.cpp | 311 ++++++++++++++++-------- 4 files changed, 230 insertions(+), 110 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 685432c8..306ae8e0 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -33,9 +33,7 @@ public: void ClearBuffer(); void Draw(RenderScene& scene); - - - GLuint DepthMap() const { return m_DepthMap; } + GLuint DepthMap() const { return m_DepthMap[m_ShadowLevel]; } glm::mat4 lightSpaceMatrix() const { return m_LightSpaceMatrix; } glm::mat4 lightP() const { return m_LightProjection; } glm::mat4 lightV() const { return m_LightView; } @@ -44,18 +42,20 @@ public: private: - void CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob); + glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam); glm::vec3 LightDirectionToPoint(glm::vec4 direction); std::array UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir); void UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance); + void InitializeLightCameras(); + glm::mat4 ApplyCropMatrix(ShadowCamera& shadow_cam, glm::mat4 m, glm::mat4 v); + glm::mat4 FindNewFrustum(ShadowCamera shadow_cam); EventBroker* m_EventBroker; const IRenderer* m_Renderer; - GLuint m_DepthMap; - - FrameBuffer m_DepthBuffer; + std::array m_DepthMap; + std::array m_DepthBuffer; ShaderProgram* m_ShadowProgram; @@ -69,15 +69,16 @@ private: glm::mat4 m_LightView; glm::mat4 m_LightSpaceMatrix; - GLuint resolutionSizeWidth = 1024 * 8; - GLuint resolutionSizeHeigth = 1024 * 8; + GLuint resolutionSizeWidth = 1024 * 2; + GLuint resolutionSizeHeigth = 1024 * 2; bool m_ShadowOn = true; + int m_ShadowLevel = 0; int m_CurrentNrOfSplits = 3; float m_SplitWeight = 0.75f; - std::array shadCams; + std::array m_shadCams; }; #endif \ No newline at end of file diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 205f1c5d..1f3ba711 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -143,9 +143,9 @@ float random(vec3 seed, int i) float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampler2DShadow depthTexture) { - float bias = 0.005; + //float bias = 0.005; //float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); - //float bias = 0.005 * tan(acos(clamp(dot(normal, -lightDir), 0.0, 1.0))); + float bias = 0.005 * tan(acos(clamp(dot(normal, -lightDir), 0.0, 1.0))); vec3 projCoords = vec3(positionLightSpace.xy, positionLightSpace.z + bias) / positionLightSpace.w; projCoords = projCoords * 0.5 + 0.5; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index ccbc1b48..96b48874 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -17,7 +17,9 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); - m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); + auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); + (double&)cCamera["FarClip"] = 30.0; + m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index ca7b59f0..7be01b5b 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -11,7 +11,7 @@ ShadowPass::ShadowPass(IRenderer * renderer) ShadowPass::~ShadowPass() { - + // m_shadCams } // Compute the 8 corner points of the current view frustum @@ -25,28 +25,28 @@ std::array ShadowPass::UpdateFrustumPoints(Camera* cam, glm::vec3 up = glm::normalize(glm::cross(right, view_dir)); - float near_height = tan(cam->FOV() / 2.0f) * cam->NearClip(); + float near_height = tan(cam->FOV() / 2.f) * cam->NearClip(); float near_width = near_height * cam->AspectRatio(); - float far_height = tan(cam->FOV() / 2.0f) * cam->FarClip(); + float far_height = tan(cam->FOV() / 2.f) * cam->FarClip(); float far_width = far_height * cam->AspectRatio(); std::array frustumPoints; - frustumPoints[0] = nearCenter - up*near_height - right*near_width; - frustumPoints[1] = nearCenter + up*near_height - right*near_width; - frustumPoints[2] = nearCenter + up*near_height + right*near_width; - frustumPoints[3] = nearCenter - up*near_height + right*near_width; - - frustumPoints[4] = farCenter - up*far_height - right*far_width; - frustumPoints[5] = farCenter + up*far_height - right*far_width; - frustumPoints[6] = farCenter + up*far_height + right*far_width; - frustumPoints[7] = farCenter - up*far_height + right*far_width; + frustumPoints[0] = nearCenter - up * near_height - right * near_width; + frustumPoints[1] = nearCenter + up * near_height - right * near_width; + frustumPoints[2] = nearCenter + up * near_height + right * near_width; + frustumPoints[3] = nearCenter - up * near_height + right * near_width; + + frustumPoints[4] = farCenter - up * far_height - right * far_width; + frustumPoints[5] = farCenter + up * far_height - right * far_width; + frustumPoints[6] = farCenter + up * far_height + right * far_width; + frustumPoints[7] = farCenter - up * far_height + right * far_width; return frustumPoints; } // UpdateSplitDist computes the near and far distances for every frustum slice // in camera eye space - that is, at what distance does a slice start and end -void ShadowPass::UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance) +void ShadowPass::UpdateSplitDist(std::array shadow_cams, float near_distance, float far_distance) { float lambda = m_SplitWeight; float ratio = far_distance / near_distance; @@ -63,66 +63,165 @@ void ShadowPass::UpdateSplitDist(std::array shadow_cam shadow_cams[m_CurrentNrOfSplits - 1].camera->SetFarClip(far_distance); } -float applyCropMatrix() +glm::mat4 ShadowPass::FindNewFrustum(ShadowCamera shadow_cam) { + float maxX = -1000.0f; + float maxY = -1000.0f; + float maxZ; + float minX = 1000.0f; + float minY = 1000.0f; + float minZ; + glm::vec4 transf = glm::vec4(shadow_cam.frustumCorners[0], 1.f); + + //if (transf.x > maxX) maxX = transf.x; + //if (transf.x < minX) minX = transf.x; + //if (transf.y > maxY) maxY = transf.y; + //if (transf.y < minY) minY = transf.y; + + for (int i = 0; i < 8; i++) + { + transf = glm::vec4(shadow_cam.frustumCorners[i], 1.f); + + transf.x /= transf.w; + transf.y /= transf.w; + + if (transf.x > maxX) maxX = transf.x; + if (transf.x < minX) minX = transf.x; + if (transf.y > maxY) maxY = transf.y; + if (transf.y < minY) minY = transf.y; + } + + glm::mat4 p = glm::ortho(minX, maxX, minY, maxY, m_NearFarPlane[Near], m_NearFarPlane[Far]); + + return p; } -// GLM wants a point for glm::lookAt, brute out a point that is on the light direction's tangent. -glm::vec3 ShadowPass::LightDirectionToPoint(glm::vec4 direction) +glm::mat4 ShadowPass::ApplyCropMatrix(ShadowCamera& shadow_cam, glm::mat4 m, glm::mat4 v) { - return -glm::normalize(glm::vec3(direction)); + glm::mat4 shad_modelview; + glm::mat4 shad_proj; + glm::mat4 shad_crop; + glm::mat4 shad_mvp; + float maxX = -1000.0f; + float maxY = -1000.0f; + float maxZ; + float minX = 1000.0f; + float minY = 1000.0f; + float minZ; + + glm::mat4 nv_mvp; + glm::vec4 transf; + + shad_modelview = m * v; + nv_mvp = shad_modelview; + + transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[0], 1.f); + minZ = transf.z; + maxZ = transf.z; + + for (int i = 1; i < 8; i++) { + transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[i], 1.f); + if (transf.z > maxZ) { + maxZ = transf.z; + } + if (transf.z < minZ) { + minZ = transf.z; + } + } + + // make sure all relevant shadow casters are included here + + shad_proj = glm::ortho(-1.f, 1.f, -1.f, 1.f, m_NearFarPlane[0], m_NearFarPlane[1]); + + //return shad_proj; + + shad_mvp = shad_proj * shad_modelview; + + nv_mvp = shad_mvp; + + for (int i = 0; i < 8; i++) + { + transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[i], 1.0f); + + transf.x /= transf.w; + transf.y /= transf.w; + + if (transf.x > maxX) maxX = transf.x; + if (transf.x < minX) minX = transf.x; + if (transf.y > maxY) maxY = transf.y; + if (transf.y < minY) minY = transf.y; + } + + float scaleX = 2.0f / (maxX - minX); + float scaleY = 2.0f / (maxY - minY); + float offsetX = -0.5f*(maxX + minX)*scaleX; + float offsetY = -0.5f*(maxY + minY)*scaleY; + + nv_mvp = glm::mat4(); + nv_mvp[0][0] = scaleX; + nv_mvp[1][1] = scaleY; + nv_mvp[0][3] = offsetX; + nv_mvp[1][3] = offsetY; + glm::transpose(nv_mvp); + + shad_crop = nv_mvp; + shad_crop *= shad_proj; + + //return nv_mvp; + //return shad_crop; + return glm::mat4(); } -void ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob) +void MakeShadowMap(glm::mat4 m, glm::mat4 v, glm::mat4 p, glm::vec3 light_dir) { - //m_LightView = glm::lookAt(LightDirectionToPoint(directionalLightJob->Direction), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)); + //float shad_modelview[16]; - m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); - - glm::vec3 LightPoint = LightDirectionToPoint(directionalLightJob->Direction); + glDisable(GL_TEXTURE_2D); - float CameraDistance = scene.Camera->FarClip() - scene.Camera->NearClip(); - float CameraPercentiles[3] = { 0.f, CameraDistance * 0.2f, CameraDistance * 0.65f }; + glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.f), light_dir, glm::vec3(-1.f, 0.f, 0.f)); - - glm::vec3 point = scene.Camera->Position() + (scene.Camera->Forward() * 30.f); - - m_LightView = glm::lookAt(LightPoint + point, point, glm::vec3(0.f, 1.f, 0.f)); - m_LightSpaceMatrix = m_LightProjection * m_LightView; - //scene.Camera-> + + + + + + + glEnable(GL_TEXTURE_2D); +} + +glm::mat4 ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam) +{ + p = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + v = glm::lookAt(glm::vec3(0.f) + shad_cam.camera->Position(), glm::vec3(directionalLightJob->Direction) + shad_cam.camera->Position(), glm::vec3(-1.f, 0.f, 0.f)); + + return p * v; } void ShadowPass::InitializeFrameBuffers() { - -// glGenRenderbuffers(1, &m_DepthFBO); -// glBindRenderbuffer(GL_RENDERBUFFER, m_DepthFBO); -// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - // Depth texture - glGenTextures(1, &m_DepthMap); - glBindTexture(GL_TEXTURE_2D, m_DepthMap); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth, resolutionSizeHeigth, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + glGenTextures(m_CurrentNrOfSplits, m_DepthMap.data()); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth / (1 + i), resolutionSizeHeigth + (1 + i), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); - m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); - //m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_COLOR_ATTACHMENT0))); - m_DepthBuffer.Generate(); + m_DepthBuffer[i].AddResource(std::shared_ptr(new Texture2D(&m_DepthMap[i], GL_DEPTH_ATTACHMENT))); + m_DepthBuffer[i].Generate(); + } GLERROR("depthMap failed"); - } void ShadowPass::InitializeShaderPrograms() @@ -135,74 +234,92 @@ void ShadowPass::InitializeShaderPrograms() m_ShadowProgram->Link(); } +void ShadowPass::InitializeLightCameras() +{ + //for (int i = 0; i < MAX_SPLITS; i++) { + // m_shadCams[i].camera = new Camera(1.f, ); + // Camera. + //} +} + void ShadowPass::ClearBuffer() { - m_DepthBuffer.Bind(); - glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - m_DepthBuffer.Unbind(); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + m_DepthBuffer[i].Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_DepthBuffer[i].Unbind(); + } } void ShadowPass::Draw(RenderScene & scene) { - ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); + ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); + ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); + ImGui::Checkbox("EnableShadow", &m_ShadowOn); + ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); - GLuint shaderHandle = m_ShadowProgram->GetHandle(); - m_ShadowProgram->Bind(); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + m_shadCams[i].camera = new Camera(*scene.Camera); + //m_shadCams[i].frustumCorners = tempPoints; + } - glViewport(0, 0, resolutionSizeWidth, resolutionSizeHeigth); + UpdateSplitDist(m_shadCams, scene.Camera->NearClip(), scene.Camera->FarClip()); + + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + m_shadCams[i].frustumCorners = UpdateFrustumPoints(m_shadCams[i].camera, m_shadCams[i].camera->Position(), m_shadCams[i].camera->Forward()); - glCullFace(GL_FRONT); - //state->Disable(GL_CULL_FACE); + ShadowPassState* state = new ShadowPassState(m_DepthBuffer[i].GetHandle()); - ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); - ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); - ImGui::Checkbox("EnableShadow", &m_ShadowOn); + GLuint shaderHandle = m_ShadowProgram->GetHandle(); + m_ShadowProgram->Bind(); - if (m_ShadowOn == true) - { - for (auto &job : scene.DirectionalLightJobs) { - auto directionalLightJob = std::dynamic_pointer_cast(job); - - if(directionalLightJob) { - CalculateFrustum(scene, directionalLightJob); + glViewport(0, 0, resolutionSizeWidth / (1 + i), resolutionSizeHeigth); + glDisable(GL_TEXTURE_2D); + glCullFace(GL_FRONT); + //state->Disable(GL_CULL_FACE); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView)); + //m_LightProjection = FindNewFrustum(m_shadCams[0], m_LightProjection, m_LightProjection); - GLERROR("ShadowLight ERROR"); + if (m_ShadowOn == true) + { + for (auto &job : scene.DirectionalLightJobs) { + auto directionalLightJob = std::dynamic_pointer_cast(job); - for (auto &objectJob : scene.OpaqueObjects) { - auto modelJob = std::dynamic_pointer_cast(objectJob); - - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + if (directionalLightJob) { + m_LightSpaceMatrix = CalculateFrustum(scene, directionalLightJob, m_LightProjection, m_LightView, m_shadCams[i]); + m_LightProjection = FindNewFrustum(m_shadCams[i]); - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + 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("Shadow Draw ERROR"); + GLERROR("ShadowLight ERROR"); - } - - } + for (auto &objectJob : scene.OpaqueObjects) { + auto modelJob = std::dynamic_pointer_cast(objectJob); - m_DepthBuffer.Unbind(); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - delete state; - - - } - } - - - - glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - glCullFace(GL_BACK); - m_ShadowProgram->Unbind(); + //glm::mat4 proj_mat = ApplyCropMatrix(m_shadCams[0], modelJob->Matrix, m_LightView); + //glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(proj_mat)); + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + GLERROR("Shadow Draw ERROR"); + } + } + m_DepthBuffer[i].Unbind(); + delete state; + } + } + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glEnable(GL_TEXTURE_2D); + glCullFace(GL_BACK); + m_ShadowProgram->Unbind(); + } } From f2ab02d860bf33e58460129dbd3054313afbb55b Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 18 Feb 2016 22:38:50 +0100 Subject: [PATCH 15/35] More WIP Switching between levels seem to work, but I borked all matrices --- include/Engine/Rendering/ShadowPass.h | 29 ++--- resources/Shaders/ForwardPlus.vert.glsl | 3 +- src/Engine/Editor/EditorSystem.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 1 - src/Engine/Rendering/ShadowPass.cpp | 136 ++++-------------------- 5 files changed, 29 insertions(+), 142 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 306ae8e0..7df1bbe9 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -11,8 +11,6 @@ #define MAX_SPLITS 5 -//#include "ShadowPassState.h" // not created yet - enum NearFar { Near = 0, Far = 1 }; enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; @@ -34,41 +32,30 @@ public: void Draw(RenderScene& scene); GLuint DepthMap() const { return m_DepthMap[m_ShadowLevel]; } - glm::mat4 lightSpaceMatrix() const { return m_LightSpaceMatrix; } - glm::mat4 lightP() const { return m_LightProjection; } - glm::mat4 lightV() const { return m_LightView; } - - void setResolution(GLuint width, GLuint height) { resolutionSizeWidth = width; resolutionSizeHeigth = height; } - + glm::mat4 lightP() const { return m_LightProjection[m_ShadowLevel]; } + glm::mat4 lightV() const { return m_LightView[m_ShadowLevel]; } private: glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam); - glm::vec3 LightDirectionToPoint(glm::vec4 direction); std::array UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir); void UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance); - void InitializeLightCameras(); - glm::mat4 ApplyCropMatrix(ShadowCamera& shadow_cam, glm::mat4 m, glm::mat4 v); glm::mat4 FindNewFrustum(ShadowCamera shadow_cam); EventBroker* m_EventBroker; - - const IRenderer* m_Renderer; + const IRenderer* m_Renderer; std::array m_DepthMap; std::array m_DepthBuffer; - ShaderProgram* m_ShadowProgram; + std::array m_LightProjection; + std::array m_LightView; - GLuint m_DepthFBO; + ShaderProgram* m_ShadowProgram; + GLuint m_DepthFBO; GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; - //GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f }; GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; - glm::mat4 m_LightProjection; - glm::mat4 m_LightView; - glm::mat4 m_LightSpaceMatrix; - GLuint resolutionSizeWidth = 1024 * 2; GLuint resolutionSizeHeigth = 1024 * 2; @@ -76,7 +63,7 @@ private: int m_ShadowLevel = 0; int m_CurrentNrOfSplits = 3; - float m_SplitWeight = 0.75f; + float m_SplitWeight = 0.5f; std::array m_shadCams; }; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index bde356e9..be7fa273 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -3,7 +3,6 @@ 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]; @@ -61,5 +60,5 @@ void main() Output.ExplosionPercentageElapsed = 0.0; //Output.PositionLightSpace = lightPos; // N - Output.PositionLightSpace = lightSpaceMatrix * M * vec4(Position, 1.0); + Output.PositionLightSpace = LightP * LightV * M * vec4(Position, 1.0); } \ No newline at end of file diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 96b48874..a13bac0b 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -18,7 +18,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - (double&)cCamera["FarClip"] = 30.0; + (double&)cCamera["FarClip"] = 60.0; m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 3e74cd1a..776bb1b3 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -244,7 +244,6 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrlightSpaceMatrix())); 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 }; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 7be01b5b..ce9ac0c4 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -4,7 +4,6 @@ ShadowPass::ShadowPass(IRenderer * renderer) { m_Renderer = renderer; - //InitializeTextures(); InitializeFrameBuffers(); InitializeShaderPrograms(); } @@ -63,6 +62,7 @@ void ShadowPass::UpdateSplitDist(std::array shadow_cam shadow_cams[m_CurrentNrOfSplits - 1].camera->SetFarClip(far_distance); } +// Create a new light frustum based on the 8 corner points of a view frustum segment glm::mat4 ShadowPass::FindNewFrustum(ShadowCamera shadow_cam) { float maxX = -1000.0f; @@ -72,126 +72,35 @@ glm::mat4 ShadowPass::FindNewFrustum(ShadowCamera shadow_cam) float minY = 1000.0f; float minZ; - glm::vec4 transf = glm::vec4(shadow_cam.frustumCorners[0], 1.f); - - //if (transf.x > maxX) maxX = transf.x; - //if (transf.x < minX) minX = transf.x; - //if (transf.y > maxY) maxY = transf.y; - //if (transf.y < minY) minY = transf.y; + glm::vec4 transf; for (int i = 0; i < 8; i++) { transf = glm::vec4(shadow_cam.frustumCorners[i], 1.f); - transf.x /= transf.w; - transf.y /= transf.w; - if (transf.x > maxX) maxX = transf.x; if (transf.x < minX) minX = transf.x; if (transf.y > maxY) maxY = transf.y; if (transf.y < minY) minY = transf.y; } + //float scaleX = 2.0f / (maxX - minX); + //float scaleY = 2.0f / (maxY - minY); + //float offsetX = -0.5f * (maxX + minX) * scaleX; + //float offsetY = -0.5f * (maxY + minY) * scaleY; + // + //glm::mat4 nv_mvp = glm::mat4(); + //nv_mvp[0][0] = scaleX; + //nv_mvp[1][1] = scaleY; + //nv_mvp[0][3] = offsetX; + //nv_mvp[1][3] = offsetY; + //glm::transpose(nv_mvp); + glm::mat4 p = glm::ortho(minX, maxX, minY, maxY, m_NearFarPlane[Near], m_NearFarPlane[Far]); return p; } -glm::mat4 ShadowPass::ApplyCropMatrix(ShadowCamera& shadow_cam, glm::mat4 m, glm::mat4 v) -{ - glm::mat4 shad_modelview; - glm::mat4 shad_proj; - glm::mat4 shad_crop; - glm::mat4 shad_mvp; - float maxX = -1000.0f; - float maxY = -1000.0f; - float maxZ; - float minX = 1000.0f; - float minY = 1000.0f; - float minZ; - - glm::mat4 nv_mvp; - glm::vec4 transf; - - shad_modelview = m * v; - nv_mvp = shad_modelview; - - transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[0], 1.f); - minZ = transf.z; - maxZ = transf.z; - - for (int i = 1; i < 8; i++) { - transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[i], 1.f); - if (transf.z > maxZ) { - maxZ = transf.z; - } - if (transf.z < minZ) { - minZ = transf.z; - } - } - - // make sure all relevant shadow casters are included here - - shad_proj = glm::ortho(-1.f, 1.f, -1.f, 1.f, m_NearFarPlane[0], m_NearFarPlane[1]); - - //return shad_proj; - - shad_mvp = shad_proj * shad_modelview; - - nv_mvp = shad_mvp; - - for (int i = 0; i < 8; i++) - { - transf = nv_mvp * glm::vec4(shadow_cam.frustumCorners[i], 1.0f); - - transf.x /= transf.w; - transf.y /= transf.w; - - if (transf.x > maxX) maxX = transf.x; - if (transf.x < minX) minX = transf.x; - if (transf.y > maxY) maxY = transf.y; - if (transf.y < minY) minY = transf.y; - } - - float scaleX = 2.0f / (maxX - minX); - float scaleY = 2.0f / (maxY - minY); - float offsetX = -0.5f*(maxX + minX)*scaleX; - float offsetY = -0.5f*(maxY + minY)*scaleY; - - nv_mvp = glm::mat4(); - nv_mvp[0][0] = scaleX; - nv_mvp[1][1] = scaleY; - nv_mvp[0][3] = offsetX; - nv_mvp[1][3] = offsetY; - glm::transpose(nv_mvp); - - shad_crop = nv_mvp; - shad_crop *= shad_proj; - - //return nv_mvp; - //return shad_crop; - return glm::mat4(); -} - -void MakeShadowMap(glm::mat4 m, glm::mat4 v, glm::mat4 p, glm::vec3 light_dir) -{ - //float shad_modelview[16]; - - glDisable(GL_TEXTURE_2D); - - glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.f), light_dir, glm::vec3(-1.f, 0.f, 0.f)); - - - - - - - - - - glEnable(GL_TEXTURE_2D); -} - glm::mat4 ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam) { p = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); @@ -234,14 +143,6 @@ void ShadowPass::InitializeShaderPrograms() m_ShadowProgram->Link(); } -void ShadowPass::InitializeLightCameras() -{ - //for (int i = 0; i < MAX_SPLITS; i++) { - // m_shadCams[i].camera = new Camera(1.f, ); - // Camera. - //} -} - void ShadowPass::ClearBuffer() { for (int i = 0; i < m_CurrentNrOfSplits; i++) { @@ -287,11 +188,11 @@ void ShadowPass::Draw(RenderScene & scene) auto directionalLightJob = std::dynamic_pointer_cast(job); if (directionalLightJob) { - m_LightSpaceMatrix = CalculateFrustum(scene, directionalLightJob, m_LightProjection, m_LightView, m_shadCams[i]); - m_LightProjection = FindNewFrustum(m_shadCams[i]); + CalculateFrustum(scene, directionalLightJob, m_LightProjection[i], m_LightView[i], m_shadCams[i]); + m_LightProjection[i] = FindNewFrustum(m_shadCams[i]); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); GLERROR("ShadowLight ERROR"); @@ -321,5 +222,6 @@ void ShadowPass::Draw(RenderScene & scene) glCullFace(GL_BACK); m_ShadowProgram->Unbind(); + } } From 73a4336206df535b13f2087048bc6d7f4ff8491d Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 18 Feb 2016 23:33:10 +0100 Subject: [PATCH 16/35] Try some stuff --- include/Engine/Rendering/ShadowPass.h | 2 +- src/Engine/Rendering/ShadowPass.cpp | 20 ++++++++------------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 7df1bbe9..2022a5ab 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -36,7 +36,7 @@ public: glm::mat4 lightV() const { return m_LightView[m_ShadowLevel]; } private: - glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam); + glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, ShadowCamera shad_cam); std::array UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir); void UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance); glm::mat4 FindNewFrustum(ShadowCamera shadow_cam); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index ce9ac0c4..412a1fc7 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -19,8 +19,10 @@ std::array ShadowPass::UpdateFrustumPoints(Camera* cam, glm::vec3 glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); - glm::vec3 farCenter = center + view_dir * cam->FarClip(); - glm::vec3 nearCenter = center + view_dir * cam->NearClip(); + //glm::vec3 farCenter = center + view_dir * cam->FarClip(); + //glm::vec3 nearCenter = center + view_dir * cam->NearClip(); + glm::vec3 farCenter = view_dir * cam->FarClip(); + glm::vec3 nearCenter = view_dir * cam->NearClip(); up = glm::normalize(glm::cross(right, view_dir)); @@ -101,12 +103,11 @@ glm::mat4 ShadowPass::FindNewFrustum(ShadowCamera shadow_cam) return p; } -glm::mat4 ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, glm::mat4& p, glm::mat4& v, ShadowCamera shad_cam) +glm::mat4 ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, ShadowCamera shad_cam) { - p = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); - v = glm::lookAt(glm::vec3(0.f) + shad_cam.camera->Position(), glm::vec3(directionalLightJob->Direction) + shad_cam.camera->Position(), glm::vec3(-1.f, 0.f, 0.f)); + glm::vec3 middle = shad_cam.camera->Position() + (shad_cam.camera->Forward() * shad_cam.camera->FarClip() * 0.5f); - return p * v; + return glm::lookAt(glm::vec3(0.f) + middle, glm::vec3(directionalLightJob->Direction) + middle, glm::vec3(-1.f, 0.f, 0.f)); } void ShadowPass::InitializeFrameBuffers() @@ -180,15 +181,13 @@ void ShadowPass::Draw(RenderScene & scene) glCullFace(GL_FRONT); //state->Disable(GL_CULL_FACE); - //m_LightProjection = FindNewFrustum(m_shadCams[0], m_LightProjection, m_LightProjection); - if (m_ShadowOn == true) { for (auto &job : scene.DirectionalLightJobs) { auto directionalLightJob = std::dynamic_pointer_cast(job); if (directionalLightJob) { - CalculateFrustum(scene, directionalLightJob, m_LightProjection[i], m_LightView[i], m_shadCams[i]); + m_LightView[i] = CalculateFrustum(scene, directionalLightJob, m_shadCams[i]); m_LightProjection[i] = FindNewFrustum(m_shadCams[i]); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); @@ -201,9 +200,6 @@ void ShadowPass::Draw(RenderScene & scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - //glm::mat4 proj_mat = ApplyCropMatrix(m_shadCams[0], modelJob->Matrix, m_LightView); - //glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(proj_mat)); - glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); From 8867e7ac3c0ea9c34eee4a32227d09a75bc5c910 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 25 Feb 2016 20:29:41 +0100 Subject: [PATCH 17/35] Working shadows, no cascade blend yet --- include/Engine/Rendering/ShadowPass.h | 41 ++++- resources/Shaders/ExplosionEffect.geom.glsl | 6 +- resources/Shaders/ForwardPlus.frag.glsl | 80 +++++++- resources/Shaders/ForwardPlus.vert.glsl | 13 +- src/Engine/Rendering/DrawFinalPass.cpp | 24 ++- src/Engine/Rendering/Renderer.cpp | 2 +- src/Engine/Rendering/ShadowPass.cpp | 194 +++++++++++--------- 7 files changed, 243 insertions(+), 117 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 2022a5ab..b7c37b31 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -9,7 +9,8 @@ #include "ShadowPassState.h" #include "imgui/imgui.h" -#define MAX_SPLITS 5 +#define MAX_SPLITS 3 +#define MAP_SIZE 216.f enum NearFar { Near = 0, Far = 1 }; enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; @@ -19,6 +20,18 @@ struct ShadowCamera{ std::array frustumCorners; }; +struct Frustum +{ + float NearClip; + float FarClip; + float FOV; + float AspectRatio; + glm::vec3 MiddlePoint; + float Radius; + std::array LRTB; + std::array CornerPoint; +}; + class ShadowPass { public: @@ -31,15 +44,23 @@ public: void ClearBuffer(); void Draw(RenderScene& scene); - GLuint DepthMap() const { return m_DepthMap[m_ShadowLevel]; } - glm::mat4 lightP() const { return m_LightProjection[m_ShadowLevel]; } - glm::mat4 lightV() const { return m_LightView[m_ShadowLevel]; } + GLuint DepthMap(int level) const { return m_DepthMap[level]; } + std::array lightP() const { return m_LightProjection; } + std::array lightV() const { return m_LightView; } + std::array farDistance() const { return { m_shadFrusta[0].FarClip, m_shadFrusta[1].FarClip, m_shadFrusta[2].FarClip }; } + int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; } private: + void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v); + void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); + glm::mat4 ApplyCropMatrix(Frustum& frustum, glm::mat4 m, glm::mat4 v); glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, ShadowCamera shad_cam); - std::array UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir); - void UpdateSplitDist(std::array shadow_cams, float far_distance, float near_distance); - glm::mat4 FindNewFrustum(ShadowCamera shadow_cam); + glm::mat4 FindNewFrustum(Frustum frustum, glm::mat4 v, glm::mat4 p); + void InitializeCameras(RenderScene & scene); + float FindRadius(Frustum& frustum); + void PointsToLightspace(Frustum& frustum, glm::mat4 v); + void RadiusToLightspace(Frustum& frustum, glm::mat4 v); + EventBroker* m_EventBroker; const IRenderer* m_Renderer; @@ -63,9 +84,11 @@ private: int m_ShadowLevel = 0; int m_CurrentNrOfSplits = 3; - float m_SplitWeight = 0.5f; + float m_SplitWeight = 0.75f; - std::array m_shadCams; + //std::array m_shadCams; + Frustum m_MainCamera; + std::array m_shadFrusta; }; #endif \ No newline at end of file diff --git a/resources/Shaders/ExplosionEffect.geom.glsl b/resources/Shaders/ExplosionEffect.geom.glsl index 3471e4f2..b4a90e3b 100644 --- a/resources/Shaders/ExplosionEffect.geom.glsl +++ b/resources/Shaders/ExplosionEffect.geom.glsl @@ -1,5 +1,7 @@ #version 430 +#define MAX_SPLITS 3 + uniform mat4 M; uniform mat4 V; uniform mat4 P; @@ -22,7 +24,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; - vec4 PositionLightSpace; + vec4 PositionLightSpace[MAX_SPLITS]; }Input[]; out VertexData{ @@ -33,7 +35,7 @@ out VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; - vec4 PositionLightSpace; + vec4 PositionLightSpace[MAX_SPLITS]; }Output; layout(triangles) in; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 1f3ba711..76169707 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,5 +1,7 @@ #version 430 +#define MAX_SPLITS 3 + uniform mat4 M; uniform mat4 V; uniform mat4 P; @@ -9,11 +11,15 @@ uniform vec2 ScreenDimensions; uniform vec4 FillColor; uniform vec4 AmbientColor; uniform float FillPercentage; +uniform float FarDistance[MAX_SPLITS]; + 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 sampler2DShadow DepthMap; +layout (binding = 4) uniform sampler2DShadow DepthMap0; +layout (binding = 5) uniform sampler2DShadow DepthMap1; +layout (binding = 6) uniform sampler2DShadow DepthMap2; #define TILE_SIZE 16 @@ -57,7 +63,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; - vec4 PositionLightSpace; + vec4 PositionLightSpace[MAX_SPLITS]; }Input; out vec4 sceneColor; @@ -186,8 +192,52 @@ float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampl } +int getShadowIndex(float far_distance[MAX_SPLITS]) +{ + int index = 2; + if( gl_FragCoord.z < far_distance[0] ) + { + index = 0; + } + else if( gl_FragCoord.z < far_distance[1] && gl_FragCoord.z > far_distance[0] ) + { + index = 1; + } + + return index; +} + +//sampler2DShadow whichDepthMap( int DepthMapIndex ) +//{ +// if( DepthMapIndex == 0 ) +// { +// return DepthMap0; +// } +// else if( DepthMapIndex == 1 ) +// { +// return DepthMap1; +// } +// else +// { +// return DepthMap2; +// } +// +//} + void main() { + //sampler2DShadow DepthMaps[3] = { sampler2DShadow(DepthMap0), sampler2DShadow(DepthMap1), sampler2DShadow(DepthMap2) }; + //sampler2DShadow DepthMaps[3] = { DepthMap0, DepthMap1, DepthMap2 }; + //sampler2DShadow DepthMaps[3] = sampler2DShadow[]( DepthMap0, DepthMap1, DepthMap2 ); + //sampler2DShadow DepthMaps[3] = sampler2DShadow[3]( DepthMap0, DepthMap1, DepthMap2 ); + //sampler2DShadow DepthMaps[3]; + + //sampler2DShadow DepthMapOne = DepthMap0; + + //DepthMaps[0] = DepthMap0; + //DepthMaps[1] = DepthMap1; + //DepthMaps[2] = DepthMap2; + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate); @@ -220,18 +270,32 @@ void main() 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 + int DepthMapIndex = getShadowIndex(FarDistance); + //sampler2DShadow WhichDepthMap = whichDepthMap(DepthMapIndex); + light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); - shadowFactor = CalcShadowValue(Input.PositionLightSpace, Input.Normal, vec3(light.Direction), DepthMap); + + shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap0); + //if( DepthMapIndex == 0 ) + //{ + // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap0); + //} + //else if( DepthMapIndex == 1 ) + //{ + // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); + //} + //else + //{ + // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); + //} } totalLighting.Diffuse += light_result.Diffuse; - totalLighting.Specular += light_result.Specular; + totalLighting.Specular += light_result.Specular; } - //totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); - //totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0); - totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0); + totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); //LightResult getInformation; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index be7fa273..fb280e3a 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -1,10 +1,12 @@ #version 430 +#define MAX_SPLITS 3 + uniform mat4 M; uniform mat4 V; uniform mat4 P; -uniform mat4 LightV; -uniform mat4 LightP; +uniform mat4 LightV[MAX_SPLITS]; +uniform mat4 LightP[MAX_SPLITS]; uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; @@ -23,7 +25,7 @@ out VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; - vec4 PositionLightSpace; + vec4 PositionLightSpace[MAX_SPLITS]; }Output; // N @@ -60,5 +62,8 @@ void main() Output.ExplosionPercentageElapsed = 0.0; //Output.PositionLightSpace = lightPos; // N - Output.PositionLightSpace = LightP * LightV * M * vec4(Position, 1.0); + for(int i = 0; i < MAX_SPLITS; i++) + { + Output.PositionLightSpace[i] = LightP[i] * LightV[i] * 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 776bb1b3..8770adb4 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -244,8 +244,11 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrlightP())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), 1, GL_FALSE, glm::value_ptr(m_ShadowPass->lightV())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->lightP().data())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->lightV().data())); + glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->farDistance().data()); + + //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]); @@ -317,11 +320,16 @@ void DrawFinalPass::BindModelTextures(std::shared_ptr& job) 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); - } + for (int i = 0; i < m_ShadowPass->CurrentNrOfSplits(); i++) + { + glActiveTexture(GL_TEXTURE4 + i); + if (m_ShadowPass->DepthMap(i) != NULL) { + glBindTexture(GL_TEXTURE_2D, m_ShadowPass->DepthMap(i)); + } else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } + } + + } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index f8e1cd6b..5aa411fc 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -137,7 +137,7 @@ void Renderer::Draw(RenderFrame& frame) m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } if (m_DebugTextureToDraw == 5) { - m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); + m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap(0)); } m_ImGuiRenderPass->Draw(); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 412a1fc7..1c31f91e 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -1,11 +1,12 @@ #include "Rendering/ShadowPass.h" + ShadowPass::ShadowPass(IRenderer * renderer) { - m_Renderer = renderer; + m_Renderer = renderer; - InitializeFrameBuffers(); - InitializeShaderPrograms(); + InitializeFrameBuffers(); + InitializeShaderPrograms(); } ShadowPass::~ShadowPass() @@ -13,101 +14,94 @@ ShadowPass::~ShadowPass() // m_shadCams } -// Compute the 8 corner points of the current view frustum -std::array ShadowPass::UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir) +void ShadowPass::InitializeCameras(RenderScene & scene) { - glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); - glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); - - //glm::vec3 farCenter = center + view_dir * cam->FarClip(); - //glm::vec3 nearCenter = center + view_dir * cam->NearClip(); - glm::vec3 farCenter = view_dir * cam->FarClip(); - glm::vec3 nearCenter = view_dir * cam->NearClip(); - - up = glm::normalize(glm::cross(right, view_dir)); - - float near_height = tan(cam->FOV() / 2.f) * cam->NearClip(); - float near_width = near_height * cam->AspectRatio(); - float far_height = tan(cam->FOV() / 2.f) * cam->FarClip(); - float far_width = far_height * cam->AspectRatio(); - - std::array frustumPoints; - frustumPoints[0] = nearCenter - up * near_height - right * near_width; - frustumPoints[1] = nearCenter + up * near_height - right * near_width; - frustumPoints[2] = nearCenter + up * near_height + right * near_width; - frustumPoints[3] = nearCenter - up * near_height + right * near_width; - - frustumPoints[4] = farCenter - up * far_height - right * far_width; - frustumPoints[5] = farCenter + up * far_height - right * far_width; - frustumPoints[6] = farCenter + up * far_height + right * far_width; - frustumPoints[7] = farCenter - up * far_height + right * far_width; - - return frustumPoints; + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + m_shadFrusta[i].AspectRatio = scene.Camera->AspectRatio(); + m_shadFrusta[i].FOV = scene.Camera->FOV(); + } } // UpdateSplitDist computes the near and far distances for every frustum slice // in camera eye space - that is, at what distance does a slice start and end -void ShadowPass::UpdateSplitDist(std::array shadow_cams, float near_distance, float far_distance) +void ShadowPass::UpdateSplitDist(std::array& frusta, float near_distance, float far_distance) { float lambda = m_SplitWeight; float ratio = far_distance / near_distance; - shadow_cams[0].camera->SetNearClip(near_distance); + frusta[0].NearClip = near_distance; for (int i = 1; i < m_CurrentNrOfSplits; i++) { float si = i / static_cast(m_CurrentNrOfSplits); - shadow_cams[i].camera->SetNearClip(lambda * (near_distance * powf(ratio, si)) + (1 - lambda) * (near_distance + (far_distance - near_distance) * si)); - shadow_cams[i - 1].camera->SetFarClip(shadow_cams[i].camera->NearClip() * 1.005f); + frusta[i].NearClip = lambda * (near_distance * powf(ratio, si)) + (1 - lambda) * (near_distance + (far_distance - near_distance) * si); + frusta[i - 1].FarClip = frusta[i].NearClip * 1.005f; } - shadow_cams[m_CurrentNrOfSplits - 1].camera->SetFarClip(far_distance); + frusta[m_CurrentNrOfSplits - 1].FarClip = far_distance; } -// Create a new light frustum based on the 8 corner points of a view frustum segment -glm::mat4 ShadowPass::FindNewFrustum(ShadowCamera shadow_cam) +// Compute the 8 corner points of the current view frustum in world space +void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v) { - float maxX = -1000.0f; - float maxY = -1000.0f; - float maxZ; - float minX = 1000.0f; - float minY = 1000.0f; - float minZ; + glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); + glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); - glm::vec4 transf; + glm::vec3 far_center = camera_position + glm::normalize(view_dir) * frustum.FarClip; + glm::vec3 near_center = camera_position + glm::normalize(view_dir) * frustum.NearClip; + frustum.MiddlePoint = near_center + (far_center - near_center) * 0.5f; - for (int i = 0; i < 8; i++) - { - transf = glm::vec4(shadow_cam.frustumCorners[i], 1.f); + up = glm::normalize(glm::cross(right, view_dir)); - if (transf.x > maxX) maxX = transf.x; - if (transf.x < minX) minX = transf.x; - if (transf.y > maxY) maxY = transf.y; - if (transf.y < minY) minY = transf.y; + // these heights and widths are half the heights and widths of the near and far plane rectangles. + float near_height = tan(frustum.FOV / 2.f) * frustum.NearClip; + float near_width = near_height * frustum.AspectRatio; + float far_height = tan(frustum.FOV / 2.f) * frustum.FarClip; + float far_width = far_height * frustum.AspectRatio; + + frustum.CornerPoint[0] = near_center - up * near_height - right * near_width; + frustum.CornerPoint[1] = near_center + up * near_height - right * near_width; + frustum.CornerPoint[2] = near_center + up * near_height + right * near_width; + frustum.CornerPoint[3] = near_center - up * near_height + right * near_width; + + frustum.CornerPoint[4] = far_center - up * far_height - right * far_width; + frustum.CornerPoint[5] = far_center + up * far_height - right * far_width; + frustum.CornerPoint[6] = far_center + up * far_height + right * far_width; + frustum.CornerPoint[7] = far_center - up * far_height + right * far_width; + + // Alternative way + //std::array CornerPoint = { + // glm::vec4(-1.f, -1.f, -1.f, 1.f), + // glm::vec4(-1.f, 1.f, -1.f, 1.f), + // glm::vec4(1.f, 1.f, -1.f, 1.f), + // glm::vec4(1.f, -1.f, -1.f, 1.f), + // glm::vec4(-1.f, -1.f, 1.f, 1.f), + // glm::vec4(-1.f, 1.f, 1.f, 1.f), + // glm::vec4(1.f, 1.f, 1.f, 1.f), + // glm::vec4(1.f, -1.f, 1.f, 1.f) }; + + //std::array final; + + //for (int i = 0; i < 8; i++) { + // glm::vec4 anus = glm::inverse(p) * CornerPoint[i]; + // anus = anus / anus.w; + // final[i] = glm::vec3(glm::inverse(v) * anus); + //} +} + +float ShadowPass::FindRadius(Frustum& frustum) +{ + float radius = 0.f; + + for (int i = 0; i < 8; i++) { + float distance = glm::distance(frustum.MiddlePoint, frustum.CornerPoint[i]); + if (distance > radius) { + radius = distance; + } } - //float scaleX = 2.0f / (maxX - minX); - //float scaleY = 2.0f / (maxY - minY); - //float offsetX = -0.5f * (maxX + minX) * scaleX; - //float offsetY = -0.5f * (maxY + minY) * scaleY; - // - //glm::mat4 nv_mvp = glm::mat4(); - //nv_mvp[0][0] = scaleX; - //nv_mvp[1][1] = scaleY; - //nv_mvp[0][3] = offsetX; - //nv_mvp[1][3] = offsetY; - //glm::transpose(nv_mvp); - - glm::mat4 p = glm::ortho(minX, maxX, minY, maxY, m_NearFarPlane[Near], m_NearFarPlane[Far]); - - return p; -} - -glm::mat4 ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, ShadowCamera shad_cam) -{ - glm::vec3 middle = shad_cam.camera->Position() + (shad_cam.camera->Forward() * shad_cam.camera->FarClip() * 0.5f); - - return glm::lookAt(glm::vec3(0.f) + middle, glm::vec3(directionalLightJob->Direction) + middle, glm::vec3(-1.f, 0.f, 0.f)); + frustum.Radius = radius; + return radius; } void ShadowPass::InitializeFrameBuffers() @@ -154,6 +148,36 @@ void ShadowPass::ClearBuffer() } } +void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) +{ + float left = INFINITY; + float right = -INFINITY; + float bottom = INFINITY; + float top = -INFINITY; + + for (int i = 0; i < 8; i++) + { + glm::vec3 tempPoint = glm::vec3(v * glm::vec4(frustum.CornerPoint[i], 1.f)); + + if (tempPoint.x < left) { left = tempPoint.x; } + if (tempPoint.x > right) { right = tempPoint.x; } + if (tempPoint.y < bottom) { bottom = tempPoint.y; } + if (tempPoint.y > top) { top = tempPoint.y; } + } + + frustum.LRTB = { left, right, bottom, top }; +} + +void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) +{ + float left = -frustum.Radius; + float right = frustum.Radius; + float bottom = -frustum.Radius; + float top =frustum.Radius; + + frustum.LRTB = { left, right, bottom, top }; +} + void ShadowPass::Draw(RenderScene & scene) { ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); @@ -161,15 +185,12 @@ void ShadowPass::Draw(RenderScene & scene) ImGui::Checkbox("EnableShadow", &m_ShadowOn); ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); - for (int i = 0; i < m_CurrentNrOfSplits; i++) { - m_shadCams[i].camera = new Camera(*scene.Camera); - //m_shadCams[i].frustumCorners = tempPoints; - } - - UpdateSplitDist(m_shadCams, scene.Camera->NearClip(), scene.Camera->FarClip()); + InitializeCameras(scene); + UpdateSplitDist(m_shadFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); for (int i = 0; i < m_CurrentNrOfSplits; i++) { - m_shadCams[i].frustumCorners = UpdateFrustumPoints(m_shadCams[i].camera, m_shadCams[i].camera->Position(), m_shadCams[i].camera->Forward()); + UpdateFrustumPoints(m_shadFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); + //float test = FindRadius(m_shadFrusta[i]); ShadowPassState* state = new ShadowPassState(m_DepthBuffer[i].GetHandle()); @@ -187,8 +208,11 @@ void ShadowPass::Draw(RenderScene & scene) auto directionalLightJob = std::dynamic_pointer_cast(job); if (directionalLightJob) { - m_LightView[i] = CalculateFrustum(scene, directionalLightJob, m_shadCams[i]); - m_LightProjection[i] = FindNewFrustum(m_shadCams[i]); + m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadFrusta[i].MiddlePoint, m_shadFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); + + PointsToLightspace(m_shadFrusta[i], m_LightView[i]); + m_LightProjection[i] = glm::ortho(m_shadFrusta[i].LRTB[Left], m_shadFrusta[i].LRTB[Right], m_shadFrusta[i].LRTB[Bottom], m_shadFrusta[i].LRTB[Top], -30.f, 30.f); + //m_LightProjection[i] = glm::ortho(m_shadFrusta[i].LRTB[Left], m_shadFrusta[i].LRTB[Right], m_shadFrusta[i].LRTB[Bottom], m_shadFrusta[i].LRTB[Top], -0.f, 300.f); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); @@ -197,7 +221,7 @@ void ShadowPass::Draw(RenderScene & scene) for (auto &objectJob : scene.OpaqueObjects) { auto modelJob = std::dynamic_pointer_cast(objectJob); - + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glBindVertexArray(modelJob->Model->VAO); From df2e4abb527938bcaf4689b8e392f835456ff1f7 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 25 Feb 2016 21:21:38 +0100 Subject: [PATCH 18/35] WE HAVE WORKING CASCADE SHADOWS --- resources/Shaders/ForwardPlus.frag.glsl | 35 +++++++++++++------------ src/Engine/Rendering/ShadowPass.cpp | 4 +-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 76169707..f4fd0dd1 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -194,12 +194,14 @@ float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampl int getShadowIndex(float far_distance[MAX_SPLITS]) { + float depth = gl_FragCoord.z / gl_FragCoord.w; + int index = 2; - if( gl_FragCoord.z < far_distance[0] ) + if( depth < far_distance[0] ) { index = 0; } - else if( gl_FragCoord.z < far_distance[1] && gl_FragCoord.z > far_distance[0] ) + else if( depth < far_distance[1] && depth > far_distance[0] ) { index = 1; } @@ -207,7 +209,7 @@ int getShadowIndex(float far_distance[MAX_SPLITS]) return index; } -//sampler2DShadow whichDepthMap( int DepthMapIndex ) +//sampler2DShadow whichDepthMap(int DepthMapIndex) //{ // if( DepthMapIndex == 0 ) // { @@ -221,7 +223,6 @@ int getShadowIndex(float far_distance[MAX_SPLITS]) // { // return DepthMap2; // } -// //} void main() @@ -275,19 +276,19 @@ void main() light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); - shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap0); - //if( DepthMapIndex == 0 ) - //{ - // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap0); - //} - //else if( DepthMapIndex == 1 ) - //{ - // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); - //} - //else - //{ - // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); - //} + //shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap0); + if( DepthMapIndex == 0 ) + { + shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap0); + } + else if( DepthMapIndex == 1 ) + { + shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); + } + else + { + shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); + } } totalLighting.Diffuse += light_result.Diffuse; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 1c31f91e..a5ef4663 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -111,7 +111,7 @@ void ShadowPass::InitializeFrameBuffers() for (int i = 0; i < m_CurrentNrOfSplits; i++) { glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, resolutionSizeWidth / (1 + i), resolutionSizeHeigth + (1 + i), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, resolutionSizeWidth / (1 /*+ i*/), resolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); @@ -197,7 +197,7 @@ void ShadowPass::Draw(RenderScene & scene) GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); - glViewport(0, 0, resolutionSizeWidth / (1 + i), resolutionSizeHeigth); + glViewport(0, 0, resolutionSizeWidth / (1/* + i*/), resolutionSizeHeigth); glDisable(GL_TEXTURE_2D); glCullFace(GL_FRONT); //state->Disable(GL_CULL_FACE); From f220d8088c13285239625b86f6519dc93fb3a6ee Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Fri, 26 Feb 2016 10:53:16 +0100 Subject: [PATCH 19/35] Begin clean-up --- include/Engine/Rendering/ShadowPass.h | 30 +++++++--------------- src/Engine/Rendering/DrawFinalPass.cpp | 6 ++--- src/Engine/Rendering/ShadowPass.cpp | 35 +++++++++++++------------- 3 files changed, 29 insertions(+), 42 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index b7c37b31..373bc21b 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -9,17 +9,12 @@ #include "ShadowPassState.h" #include "imgui/imgui.h" -#define MAX_SPLITS 3 +#define MAX_SPLITS 4 #define MAP_SIZE 216.f enum NearFar { Near = 0, Far = 1 }; enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; -struct ShadowCamera{ - Camera* camera; - std::array frustumCorners; -}; - struct Frustum { float NearClip; @@ -28,7 +23,7 @@ struct Frustum float AspectRatio; glm::vec3 MiddlePoint; float Radius; - std::array LRTB; + std::array LRBT; std::array CornerPoint; }; @@ -45,24 +40,19 @@ public: void Draw(RenderScene& scene); GLuint DepthMap(int level) const { return m_DepthMap[level]; } - std::array lightP() const { return m_LightProjection; } - std::array lightV() const { return m_LightView; } - std::array farDistance() const { return { m_shadFrusta[0].FarClip, m_shadFrusta[1].FarClip, m_shadFrusta[2].FarClip }; } + std::array LightP() const { return m_LightProjection; } + std::array LightV() const { return m_LightView; } + std::array FarDistance() const { return { m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; } private: void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v); void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); - glm::mat4 ApplyCropMatrix(Frustum& frustum, glm::mat4 m, glm::mat4 v); - - glm::mat4 CalculateFrustum(RenderScene & scene, std::shared_ptr directionalLightJob, ShadowCamera shad_cam); - glm::mat4 FindNewFrustum(Frustum frustum, glm::mat4 v, glm::mat4 p); void InitializeCameras(RenderScene & scene); float FindRadius(Frustum& frustum); void PointsToLightspace(Frustum& frustum, glm::mat4 v); void RadiusToLightspace(Frustum& frustum, glm::mat4 v); - - EventBroker* m_EventBroker; + EventBroker* m_EventBroker; const IRenderer* m_Renderer; std::array m_DepthMap; @@ -77,8 +67,8 @@ private: GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; - GLuint resolutionSizeWidth = 1024 * 2; - GLuint resolutionSizeHeigth = 1024 * 2; + GLuint m_ResolutionSizeWidth = 1024 * 2; + GLuint m_ResolutionSizeHeigth = 1024 * 2; bool m_ShadowOn = true; int m_ShadowLevel = 0; @@ -86,9 +76,7 @@ private: int m_CurrentNrOfSplits = 3; float m_SplitWeight = 0.75f; - //std::array m_shadCams; - Frustum m_MainCamera; - std::array m_shadFrusta; + std::array m_shadowFrusta; }; #endif \ No newline at end of file diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8770adb4..537bc3dc 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -244,9 +244,9 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrlightP().data())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->lightV().data())); - glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->farDistance().data()); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data())); + glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data()); //GLfloat m_NearFarPlane[2] = { -40.f, 30.f }; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index a5ef4663..c3eb8c73 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -11,14 +11,14 @@ ShadowPass::ShadowPass(IRenderer * renderer) ShadowPass::~ShadowPass() { - // m_shadCams + } void ShadowPass::InitializeCameras(RenderScene & scene) { for (int i = 0; i < m_CurrentNrOfSplits; i++) { - m_shadFrusta[i].AspectRatio = scene.Camera->AspectRatio(); - m_shadFrusta[i].FOV = scene.Camera->FOV(); + m_shadowFrusta[i].AspectRatio = scene.Camera->AspectRatio(); + m_shadowFrusta[i].FOV = scene.Camera->FOV(); } } @@ -69,7 +69,7 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position frustum.CornerPoint[6] = far_center + up * far_height + right * far_width; frustum.CornerPoint[7] = far_center - up * far_height + right * far_width; - // Alternative way + // Alternative way. //std::array CornerPoint = { // glm::vec4(-1.f, -1.f, -1.f, 1.f), // glm::vec4(-1.f, 1.f, -1.f, 1.f), @@ -80,12 +80,12 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position // glm::vec4(1.f, 1.f, 1.f, 1.f), // glm::vec4(1.f, -1.f, 1.f, 1.f) }; - //std::array final; + //std::array FinalPoints; //for (int i = 0; i < 8; i++) { - // glm::vec4 anus = glm::inverse(p) * CornerPoint[i]; - // anus = anus / anus.w; - // final[i] = glm::vec3(glm::inverse(v) * anus); + // glm::vec4 NDC = glm::inverse(p) * CornerPoint[i]; + // NDC = NDC / NDC.w; + // FinalPoints[i] = glm::vec3(glm::inverse(v) * NDC); //} } @@ -111,7 +111,7 @@ void ShadowPass::InitializeFrameBuffers() for (int i = 0; i < m_CurrentNrOfSplits; i++) { glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, resolutionSizeWidth / (1 /*+ i*/), resolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth / (1 /*+ i*/), m_ResolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); @@ -165,7 +165,7 @@ void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) if (tempPoint.y > top) { top = tempPoint.y; } } - frustum.LRTB = { left, right, bottom, top }; + frustum.LRBT = { left, right, bottom, top }; } void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) @@ -175,7 +175,7 @@ void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) float bottom = -frustum.Radius; float top =frustum.Radius; - frustum.LRTB = { left, right, bottom, top }; + frustum.LRBT = { left, right, bottom, top }; } void ShadowPass::Draw(RenderScene & scene) @@ -186,10 +186,10 @@ void ShadowPass::Draw(RenderScene & scene) ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); InitializeCameras(scene); - UpdateSplitDist(m_shadFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); + UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); for (int i = 0; i < m_CurrentNrOfSplits; i++) { - UpdateFrustumPoints(m_shadFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); + UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); //float test = FindRadius(m_shadFrusta[i]); ShadowPassState* state = new ShadowPassState(m_DepthBuffer[i].GetHandle()); @@ -197,7 +197,7 @@ void ShadowPass::Draw(RenderScene & scene) GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); - glViewport(0, 0, resolutionSizeWidth / (1/* + i*/), resolutionSizeHeigth); + glViewport(0, 0, m_ResolutionSizeWidth / (1/* + i*/), m_ResolutionSizeHeigth); glDisable(GL_TEXTURE_2D); glCullFace(GL_FRONT); //state->Disable(GL_CULL_FACE); @@ -208,11 +208,10 @@ void ShadowPass::Draw(RenderScene & scene) auto directionalLightJob = std::dynamic_pointer_cast(job); if (directionalLightJob) { - m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadFrusta[i].MiddlePoint, m_shadFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); + m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); - PointsToLightspace(m_shadFrusta[i], m_LightView[i]); - m_LightProjection[i] = glm::ortho(m_shadFrusta[i].LRTB[Left], m_shadFrusta[i].LRTB[Right], m_shadFrusta[i].LRTB[Bottom], m_shadFrusta[i].LRTB[Top], -30.f, 30.f); - //m_LightProjection[i] = glm::ortho(m_shadFrusta[i].LRTB[Left], m_shadFrusta[i].LRTB[Right], m_shadFrusta[i].LRTB[Bottom], m_shadFrusta[i].LRTB[Top], -0.f, 300.f); + PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); + m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[Left], m_shadowFrusta[i].LRBT[Right], m_shadowFrusta[i].LRBT[Bottom], m_shadowFrusta[i].LRBT[Top], -30.f, 30.f); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); From 22c391df54c3aa5479339c6e26dd7dbdedde5537 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Fri, 26 Feb 2016 17:40:35 +0100 Subject: [PATCH 20/35] Initial work on texture arrays --- include/Engine/Rendering/FrameBuffer.h | 14 +++++ include/Engine/Rendering/ShadowPass.h | 9 ++- resources/Shaders/ExplosionEffect.geom.glsl | 2 +- resources/Shaders/ForwardPlus.frag.glsl | 63 ++++++--------------- resources/Shaders/ForwardPlus.vert.glsl | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 14 ++--- src/Engine/Rendering/FrameBuffer.cpp | 24 +++++++- src/Engine/Rendering/Renderer.cpp | 6 +- src/Engine/Rendering/ShadowPass.cpp | 53 ++++++++++------- 9 files changed, 101 insertions(+), 86 deletions(-) diff --git a/include/Engine/Rendering/FrameBuffer.h b/include/Engine/Rendering/FrameBuffer.h index cf63b6c6..325fbe3b 100644 --- a/include/Engine/Rendering/FrameBuffer.h +++ b/include/Engine/Rendering/FrameBuffer.h @@ -8,10 +8,12 @@ class BufferResource { public: BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment); + BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment, GLuint layers); GLuint* m_ResourceHandle; GLenum m_ResourceType; GLenum m_Attachment; + GLuint m_Layers; private: }; @@ -22,6 +24,9 @@ class ResourceType : public BufferResource public: ResourceType(GLuint* resourceHandle, GLenum attachment) : BufferResource(resourceHandle, RESOURCETYPE, attachment) { } + + ResourceType(GLuint* resourceHandle, GLenum attachment, GLuint layers) + : BufferResource(resourceHandle, RESOURCETYPE, attachment, layers) { } }; class Texture2D : public ResourceType @@ -43,6 +48,15 @@ public: ~RenderBuffer(); }; +class Texture2DArray : public ResourceType +{ +public: + Texture2DArray(GLuint* resourceHandle, GLenum attachment, GLuint layers) + : ResourceType(resourceHandle, attachment, layers) { }; + + ~Texture2DArray(); +}; + class FrameBuffer { public: diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 373bc21b..192d54c7 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -39,7 +39,8 @@ public: void ClearBuffer(); void Draw(RenderScene& scene); - GLuint DepthMap(int level) const { return m_DepthMap[level]; } + //GLuint DepthMap(int level) const { return m_DepthMap[level]; } + GLuint DepthMap() const { return m_DepthMap; } std::array LightP() const { return m_LightProjection; } std::array LightV() const { return m_LightView; } std::array FarDistance() const { return { m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } @@ -55,8 +56,10 @@ private: EventBroker* m_EventBroker; const IRenderer* m_Renderer; - std::array m_DepthMap; - std::array m_DepthBuffer; + //std::array m_DepthMap; + //std::array m_DepthBuffer; + GLuint m_DepthMap; + FrameBuffer m_DepthBuffer; std::array m_LightProjection; std::array m_LightView; diff --git a/resources/Shaders/ExplosionEffect.geom.glsl b/resources/Shaders/ExplosionEffect.geom.glsl index b4a90e3b..ffc78900 100644 --- a/resources/Shaders/ExplosionEffect.geom.glsl +++ b/resources/Shaders/ExplosionEffect.geom.glsl @@ -1,6 +1,6 @@ #version 430 -#define MAX_SPLITS 3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index f4fd0dd1..7f80826a 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,6 +1,6 @@ #version 430 -#define MAX_SPLITS 3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; @@ -17,9 +17,8 @@ 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 sampler2DShadow DepthMap0; -layout (binding = 5) uniform sampler2DShadow DepthMap1; -layout (binding = 6) uniform sampler2DShadow DepthMap2; +layout (binding = 4) uniform sampler2DShadow DepthMap[MAX_SPLITS]; + #define TILE_SIZE 16 @@ -209,36 +208,8 @@ int getShadowIndex(float far_distance[MAX_SPLITS]) return index; } -//sampler2DShadow whichDepthMap(int DepthMapIndex) -//{ -// if( DepthMapIndex == 0 ) -// { -// return DepthMap0; -// } -// else if( DepthMapIndex == 1 ) -// { -// return DepthMap1; -// } -// else -// { -// return DepthMap2; -// } -//} - void main() { - //sampler2DShadow DepthMaps[3] = { sampler2DShadow(DepthMap0), sampler2DShadow(DepthMap1), sampler2DShadow(DepthMap2) }; - //sampler2DShadow DepthMaps[3] = { DepthMap0, DepthMap1, DepthMap2 }; - //sampler2DShadow DepthMaps[3] = sampler2DShadow[]( DepthMap0, DepthMap1, DepthMap2 ); - //sampler2DShadow DepthMaps[3] = sampler2DShadow[3]( DepthMap0, DepthMap1, DepthMap2 ); - //sampler2DShadow DepthMaps[3]; - - //sampler2DShadow DepthMapOne = DepthMap0; - - //DepthMaps[0] = DepthMap0; - //DepthMaps[1] = DepthMap1; - //DepthMaps[2] = DepthMap2; - vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate); @@ -271,24 +242,22 @@ void main() 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 - int DepthMapIndex = getShadowIndex(FarDistance); - //sampler2DShadow WhichDepthMap = whichDepthMap(DepthMapIndex); + //int DepthMapIndex = getShadowIndex(FarDistance); light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); - //shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap0); - if( DepthMapIndex == 0 ) - { - shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap0); - } - else if( DepthMapIndex == 1 ) - { - shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); - } - else - { - shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); - } + //if( DepthMapIndex == 0 ) + //{ + shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap[0]); + //} + //else if( DepthMapIndex == 1 ) + //{ + // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); + //} + //else + //{ + // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); + //} } totalLighting.Diffuse += light_result.Diffuse; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index fb280e3a..0d9661cc 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -1,6 +1,6 @@ #version 430 -#define MAX_SPLITS 3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 537bc3dc..72bd8711 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -320,15 +320,15 @@ void DrawFinalPass::BindModelTextures(std::shared_ptr& job) glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); } - for (int i = 0; i < m_ShadowPass->CurrentNrOfSplits(); i++) - { - glActiveTexture(GL_TEXTURE4 + i); - if (m_ShadowPass->DepthMap(i) != NULL) { - glBindTexture(GL_TEXTURE_2D, m_ShadowPass->DepthMap(i)); + //for (int i = 0; i < m_ShadowPass->CurrentNrOfSplits(); i++) + //{ + glActiveTexture(GL_TEXTURE4); + if (m_ShadowPass->DepthMap() != NULL) { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); } else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); } - } + //} } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 44ffb20e..b5dad961 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -9,6 +9,14 @@ BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLen m_Attachment = attachment; } +BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment, GLuint layers) +{ + m_ResourceHandle = resourceHandle; + m_ResourceType = resourceType; + m_Attachment = attachment; + m_Layers = layers; +} + Texture2D::~Texture2D() { if (m_ResourceHandle != 0) { @@ -16,6 +24,12 @@ Texture2D::~Texture2D() } } +Texture2DArray::~Texture2DArray() +{ + if (m_ResourceHandle != 0) { + glDeleteTextures(1, m_ResourceHandle); + } +} RenderBuffer::~RenderBuffer() { @@ -48,18 +62,22 @@ void FrameBuffer::Generate() switch ((*it)->m_ResourceType) { case GL_TEXTURE_2D: glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + attachments.push_back((*it)->m_Attachment); GLERROR("FrameBuffer generate: glFramebufferTexture2D"); break; case GL_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); break; + case GL_TEXTURE_2D_ARRAY: + glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, 0); + attachments.push_back((*it)->m_Attachment); + GLERROR("FrameBuffer generate: GL_TEXTURE_2D_ARRAY"); + + break; } - if ((*it)->m_ResourceType == GL_TEXTURE_2D) { - attachments.push_back((*it)->m_Attachment); - } } GLenum* bufferTextures = &attachments[0]; diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 5aa411fc..1341ac15 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -136,9 +136,9 @@ void Renderer::Draw(RenderFrame& frame) if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } - if (m_DebugTextureToDraw == 5) { - m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap(0)); - } + //if (m_DebugTextureToDraw == 5) { + // m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); + //} m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index c3eb8c73..c734f695 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -106,26 +106,37 @@ float ShadowPass::FindRadius(Frustum& frustum) void ShadowPass::InitializeFrameBuffers() { - // Depth texture - glGenTextures(m_CurrentNrOfSplits, m_DepthMap.data()); + GLERROR("depthMap failed PRE"); + // Depth texture + glGenTextures(1, &m_DepthMap); - for (int i = 0; i < m_CurrentNrOfSplits; i++) { - glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth / (1 /*+ i*/), m_ResolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + GLERROR("depthMap failed1"); + glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap); + GLERROR("depthMap failed2"); + glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits); + GLERROR("depthMap failed3"); - m_DepthBuffer[i].AddResource(std::shared_ptr(new Texture2D(&m_DepthMap[i], GL_DEPTH_ATTACHMENT))); - m_DepthBuffer[i].Generate(); - } + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + GLERROR("depthMap failed4"); - GLERROR("depthMap failed"); + //for (int i = 0; i < m_CurrentNrOfSplits; i++) { + // glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth / (1 /*+ i*/), m_ResolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); + GLERROR("depthMap failed5"); + + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits))); + m_DepthBuffer.Generate(); + //} + + GLERROR("depthMap failed END"); } void ShadowPass::InitializeShaderPrograms() @@ -141,10 +152,10 @@ void ShadowPass::InitializeShaderPrograms() void ShadowPass::ClearBuffer() { for (int i = 0; i < m_CurrentNrOfSplits; i++) { - m_DepthBuffer[i].Bind(); + m_DepthBuffer.Bind(); glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - m_DepthBuffer[i].Unbind(); + m_DepthBuffer.Unbind(); } } @@ -192,7 +203,7 @@ void ShadowPass::Draw(RenderScene & scene) UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); //float test = FindRadius(m_shadFrusta[i]); - ShadowPassState* state = new ShadowPassState(m_DepthBuffer[i].GetHandle()); + ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); GLuint shaderHandle = m_ShadowProgram->GetHandle(); m_ShadowProgram->Bind(); @@ -230,7 +241,7 @@ void ShadowPass::Draw(RenderScene & scene) GLERROR("Shadow Draw ERROR"); } } - m_DepthBuffer[i].Unbind(); + m_DepthBuffer.Unbind(); delete state; } From 38d8cdded221dd9a82535ea99024b142ed8b9be0 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sat, 27 Feb 2016 15:53:28 +0100 Subject: [PATCH 21/35] Texture Array is now working. Enjoy your single Bind(). --- include/Engine/Rendering/ShadowPass.h | 4 +- resources/Shaders/ForwardPlus.frag.glsl | 74 +++++++++++++--------- src/Engine/Rendering/FrameBuffer.cpp | 1 - src/Engine/Rendering/Renderer.cpp | 6 +- src/Engine/Rendering/ShadowPass.cpp | 78 +++++++++++------------- src/Engine/Rendering/ShadowPassState.cpp | 4 ++ 6 files changed, 91 insertions(+), 76 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 192d54c7..6fab8a3a 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -68,7 +68,7 @@ private: GLuint m_DepthFBO; GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; - GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; + //GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; GLuint m_ResolutionSizeWidth = 1024 * 2; GLuint m_ResolutionSizeHeigth = 1024 * 2; @@ -77,7 +77,7 @@ private: int m_ShadowLevel = 0; int m_CurrentNrOfSplits = 3; - float m_SplitWeight = 0.75f; + float m_SplitWeight = 0.7f; std::array m_shadowFrusta; }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 7f80826a..7659f3b0 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -17,7 +17,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 sampler2DShadow DepthMap[MAX_SPLITS]; +layout (binding = 4) uniform sampler2DArrayShadow DepthMap; #define TILE_SIZE 16 @@ -138,32 +138,59 @@ vec2 poissonDisk[16] = vec2[]( vec2( 0.14383161, -0.14100790 ) ); -float random(vec3 seed, int i) +float Random(vec3 seed, int i) { vec4 seed4 = vec4(seed, i); float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673)); return fract(sin(dot_product) * 43758.5453); } -float CalcShadowValue(vec4 positionLightSpace, vec3 normal, vec3 lightDir, sampler2DShadow depthTexture) +// Standard hardware-calculated PCF method +float PCFShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_coords, int layer_index) +{ + return texture(depth_texture_array, vec4(projection_coords.xy, layer_index, projection_coords.z)); +} + +float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler2DArrayShadow depth_texture_array, int layer_index) { - - //float bias = 0.005; - //float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); - float bias = 0.005 * tan(acos(clamp(dot(normal, -lightDir), 0.0, 1.0))); - - vec3 projCoords = vec3(positionLightSpace.xy, positionLightSpace.z + bias) / positionLightSpace.w; - projCoords = projCoords * 0.5 + 0.5; - //float shadowMapDepth = texture(depthTexture, projCoords.xy).r; float shadowMapDepth; + float bias; + + // Various bias methods. + + //bias = 0.005; + //bias = max(0.05 * (1.0 - dot(normal, light_dir)), 0.005); + bias = 0.005 * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + + // Calculate coordinates in projection space + vec3 projCoords = vec3(light_space_pos.xy, light_space_pos.z + bias) / light_space_pos.w; + projCoords = projCoords * 0.5 + 0.5; + + // Various methods for shadow calculation in fastest to slowest order. + + shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index); + + // PCF + Four-tap Poisson model method + //float SplitWeight = 0.7; //for (int i = 0; i < 4; i++) //{ - // int index = i; - // //int index = int(16.0 * random(gl_FragCoord.xyy, i)) % 16; - // shadowMapDepth += 0.25 * texture(depthTexture, projCoords + vec3(poissonDisk[index], 0.0) / 700.0); + // int loop = i; + // vec3 newProjCoords = projCoords + vec3(poissonDisk[loop], 0.0) / (1500.0 * SplitWeight * (1.0 + layer_index)); + // shadowMapDepth += 0.25 * texture(depthTexture, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); //} - - shadowMapDepth = texture(depthTexture, projCoords); + // + //// PCF + Four-tap Poisson model method + //float SplitWeight = 0.7; + //for (int i = 0; i < 4; i++) + //{ + // int loop = i; + // vec3 newProjCoords = projCoords + vec3(poissonDisk[loop], 0.0) / (1500.0 * SplitWeight * (1.0 + layer_index)); + // //int loop = int(16.0 * Random(gl_FragCoord.xyy, i)) % 16; + // shadowMapDepth += 0.25 * texture(depthTexture, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); + //} + + + //float geometryDepth = projCoords.z; //float shadow = geometryDepth - bias > shadowMapDepth ? 1.0 : 0.0; @@ -242,22 +269,11 @@ void main() 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 - //int DepthMapIndex = getShadowIndex(FarDistance); + int DepthMapIndex = getShadowIndex(FarDistance); light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); - //if( DepthMapIndex == 0 ) - //{ - shadowFactor = CalcShadowValue(Input.PositionLightSpace[0], Input.Normal, vec3(light.Direction), DepthMap[0]); - //} - //else if( DepthMapIndex == 1 ) - //{ - // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap1); - //} - //else - //{ - // shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap2); - //} + shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap, DepthMapIndex); } totalLighting.Diffuse += light_result.Diffuse; diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index b5dad961..cc563600 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -73,7 +73,6 @@ void FrameBuffer::Generate() glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, 0); attachments.push_back((*it)->m_Attachment); GLERROR("FrameBuffer generate: GL_TEXTURE_2D_ARRAY"); - break; } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 1341ac15..a26a7f09 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -136,9 +136,9 @@ void Renderer::Draw(RenderFrame& frame) if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } - //if (m_DebugTextureToDraw == 5) { - // m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); - //} + if (m_DebugTextureToDraw == 5) { + m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); + } m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index c734f695..dd423f25 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -119,9 +119,6 @@ void ShadowPass::InitializeFrameBuffers() glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); GLERROR("depthMap failed4"); - //for (int i = 0; i < m_CurrentNrOfSplits; i++) { - // glBindTexture(GL_TEXTURE_2D, m_DepthMap[i]); - // glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth / (1 /*+ i*/), m_ResolutionSizeHeigth + (1 /*+ i*/), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); @@ -129,7 +126,6 @@ void ShadowPass::InitializeFrameBuffers() glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); GLERROR("depthMap failed5"); m_DepthBuffer.AddResource(std::shared_ptr(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits))); @@ -151,12 +147,15 @@ void ShadowPass::InitializeShaderPrograms() void ShadowPass::ClearBuffer() { + m_DepthBuffer.Bind(); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { - m_DepthBuffer.Bind(); - glClearColor(0.f, 0.f, 0.f, 0.f); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - m_DepthBuffer.Unbind(); } + + m_DepthBuffer.Unbind(); } void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) @@ -191,67 +190,64 @@ void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) void ShadowPass::Draw(RenderScene & scene) { - ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); +// ImGui::DragFloat4("ShadowMapCam", m_LRBT, 1.f, -1000.f, 1000.f); ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); ImGui::Checkbox("EnableShadow", &m_ShadowOn); - ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); + //ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); InitializeCameras(scene); UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); + ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); + + m_ShadowProgram->Bind(); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); //float test = FindRadius(m_shadFrusta[i]); - ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); - GLuint shaderHandle = m_ShadowProgram->GetHandle(); - m_ShadowProgram->Bind(); + + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - glViewport(0, 0, m_ResolutionSizeWidth / (1/* + i*/), m_ResolutionSizeHeigth); - glDisable(GL_TEXTURE_2D); - glCullFace(GL_FRONT); + glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth); + //state->Disable(GL_CULL_FACE); - if (m_ShadowOn == true) - { - for (auto &job : scene.DirectionalLightJobs) { - auto directionalLightJob = std::dynamic_pointer_cast(job); + for (auto &job : scene.DirectionalLightJobs) { + auto directionalLightJob = std::dynamic_pointer_cast(job); - if (directionalLightJob) { - m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); - - PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); - m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[Left], m_shadowFrusta[i].LRBT[Right], m_shadowFrusta[i].LRBT[Bottom], m_shadowFrusta[i].LRBT[Top], -30.f, 30.f); + if (directionalLightJob) { + m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); + PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); + m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[Left], m_shadowFrusta[i].LRBT[Right], m_shadowFrusta[i].LRBT[Bottom], m_shadowFrusta[i].LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); - GLERROR("ShadowLight ERROR"); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); - for (auto &objectJob : scene.OpaqueObjects) { - auto modelJob = std::dynamic_pointer_cast(objectJob); - - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + GLERROR("ShadowLight ERROR"); - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + for (auto &objectJob : scene.OpaqueObjects) { + auto modelJob = std::dynamic_pointer_cast(objectJob); - GLERROR("Shadow Draw ERROR"); - } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + + GLERROR("Shadow Draw ERROR"); } - m_DepthBuffer.Unbind(); - - delete state; } + } glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - glEnable(GL_TEXTURE_2D); - glCullFace(GL_BACK); m_ShadowProgram->Unbind(); } + m_DepthBuffer.Unbind(); + delete state; } diff --git a/src/Engine/Rendering/ShadowPassState.cpp b/src/Engine/Rendering/ShadowPassState.cpp index caa09b9f..f84b6436 100644 --- a/src/Engine/Rendering/ShadowPassState.cpp +++ b/src/Engine/Rendering/ShadowPassState.cpp @@ -8,6 +8,10 @@ ShadowPassState::ShadowPassState(GLuint frameBuffer) Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); Disable(GL_BLEND); + Disable(GL_TEXTURE_2D); + CullFace(GL_FRONT); + ClearColor(glm::vec4(255.f, 128.f, 128.f, 128.f)); + GLERROR("---4"); } ShadowPassState::~ShadowPassState() From ecab5de0567f1b6dffd237da40d3ea5f88b2de2c Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sat, 27 Feb 2016 16:35:15 +0100 Subject: [PATCH 22/35] Various shadow calculation methods implemented and ready for use. --- resources/Shaders/ForwardPlus.frag.glsl | 136 +++++++++++++----------- resources/Shaders/Shadow.frag.glsl | 10 +- resources/Shaders/Shadow.vert.glsl | 5 - src/Engine/Rendering/DrawFinalPass.cpp | 16 ++- 4 files changed, 82 insertions(+), 85 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 7659f3b0..b3240911 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,6 +1,7 @@ #version 430 #define MAX_SPLITS 4 +#define SPLIT_WEIGHT 0.7 uniform mat4 M; uniform mat4 V; @@ -73,6 +74,25 @@ struct LightResult { vec4 Specular; }; +vec2 poissonDisk[16] = vec2[]( + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ), + vec2( -0.91588581, 0.45771432 ), + vec2( -0.81544232, -0.87912464 ), + vec2( -0.38277543, 0.27676845 ), + vec2( 0.97484398, 0.75648379 ), + vec2( 0.44323325, -0.97511554 ), + vec2( 0.53742981, -0.47373420 ), + vec2( -0.26496911, -0.41893023 ), + vec2( 0.79197514, 0.19090188 ), + vec2( -0.24188840, 0.99706507 ), + vec2( -0.81409955, 0.91437590 ), + vec2( 0.19984126, 0.78641367 ), + vec2( 0.14383161, -0.14100790 ) + ); + float CalcAttenuation(float radius, float dist, float falloff) { return 1.0 - smoothstep(radius * 0.3, radius, dist); } @@ -119,25 +139,6 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } -vec2 poissonDisk[16] = vec2[]( - vec2( -0.94201624, -0.39906216 ), - vec2( 0.94558609, -0.76890725 ), - vec2( -0.094184101, -0.92938870 ), - vec2( 0.34495938, 0.29387760 ), - vec2( -0.91588581, 0.45771432 ), - vec2( -0.81544232, -0.87912464 ), - vec2( -0.38277543, 0.27676845 ), - vec2( 0.97484398, 0.75648379 ), - vec2( 0.44323325, -0.97511554 ), - vec2( 0.53742981, -0.47373420 ), - vec2( -0.26496911, -0.41893023 ), - vec2( 0.79197514, 0.19090188 ), - vec2( -0.24188840, 0.99706507 ), - vec2( -0.81409955, 0.91437590 ), - vec2( 0.19984126, 0.78641367 ), - vec2( 0.14383161, -0.14100790 ) -); - float Random(vec3 seed, int i) { vec4 seed4 = vec4(seed, i); @@ -151,6 +152,57 @@ float PCFShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_coords return texture(depth_texture_array, vec4(projection_coords.xy, layer_index, projection_coords.z)); } +// PCF + Poisson model method +float PoissonShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_coords, int layer_index, int taps, float spread) +{ + int loop; + float multiplier = 1.0 / float(taps); + float shadowMapDepth; + + for (int i = 0; i < taps; i++) + { + loop = i; + vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index)); + shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); + } + + return shadowMapDepth; +} + +// PCF + Poisson + RandomSample model method +float PoissonDotShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_coords, int layer_index, int taps, float spread) +{ + int loop; + float multiplier = 1.0 / float(taps); + float shadowMapDepth; + + for (int i = 0; i < taps; i++) + { + loop = int(16.0 * Random(gl_FragCoord.xyy, i)) % 16; + vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index)); + shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); + } + + return shadowMapDepth; +} + +// Hardware PCF + Additional software PCF method +float SoftwarePCF(sampler2DArrayShadow depth_texture_array, vec3 projection_coords, int layer_index, float bias) +{ + float shadow = 0.0; + + vec3 texelSize = 1.0 / textureSize(depth_texture_array, 0); + for(int x = -1; x <= 1; x++) + { + for(int y = -1; y <= 1; y++) + { + shadow += texture(depth_texture_array, vec4(projection_coords.xy + vec2(x, y) * texelSize.xy, layer_index, projection_coords.z)); + } + } + + return shadow / 9.0; +} + float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler2DArrayShadow depth_texture_array, int layer_index) { float shadowMapDepth; @@ -169,53 +221,13 @@ float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler // Various methods for shadow calculation in fastest to slowest order. shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index); - - // PCF + Four-tap Poisson model method - //float SplitWeight = 0.7; - //for (int i = 0; i < 4; i++) - //{ - // int loop = i; - // vec3 newProjCoords = projCoords + vec3(poissonDisk[loop], 0.0) / (1500.0 * SplitWeight * (1.0 + layer_index)); - // shadowMapDepth += 0.25 * texture(depthTexture, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); - //} - // - //// PCF + Four-tap Poisson model method - //float SplitWeight = 0.7; - //for (int i = 0; i < 4; i++) - //{ - // int loop = i; - // vec3 newProjCoords = projCoords + vec3(poissonDisk[loop], 0.0) / (1500.0 * SplitWeight * (1.0 + layer_index)); - // //int loop = int(16.0 * Random(gl_FragCoord.xyy, i)) % 16; - // shadowMapDepth += 0.25 * texture(depthTexture, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); - //} - - - - - //float geometryDepth = projCoords.z; - //float shadow = geometryDepth - bias > shadowMapDepth ? 1.0 : 0.0; - //float shadow = 1.0 - bias > shadowMapDepth ? 0.0 : 1.0; + //shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0); + //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0); + //shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); float shadow = 1.0 - shadowMapDepth; - - //vec2 texelSize = 1.0 / textureSize(depthTexture, 0); - //for(int x = -1; x <= 1; x++) - //{ - // for(int y = -1; y <= 1; y++) - // { - // float pcfDepth = texture(depthTexture, projCoords.xy + vec2(x, y) * texelSize).r; - // shadow += geometryDepth - bias > pcfDepth ? 1.0 : 0.0; - // } - //} - //shadow /= 9.0; - - //if(projCoords.z > 1.0) - //{ - // shadow = 0.0; - //} return shadow; - } int getShadowIndex(float far_distance[MAX_SPLITS]) diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index 798d1cda..58290b59 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -1,18 +1,10 @@ #version 430 - - -//in VertexData{ -// vec3 Position; -//}Input; - -//layout(location = 0 ) out vec4 ShadowMap; layout(location = 0 ) out float ShadowMap; void main() { - //ShadowMap = vec4(vec3(gl_FragCoord.z), 1.0); - //ShadowMap = (gl_FragCoord.z); + } diff --git a/resources/Shaders/Shadow.vert.glsl b/resources/Shaders/Shadow.vert.glsl index 16c0b26e..8a0dc8f4 100644 --- a/resources/Shaders/Shadow.vert.glsl +++ b/resources/Shaders/Shadow.vert.glsl @@ -6,12 +6,7 @@ uniform mat4 P; layout(location = 0) in vec3 Position; -//out VertexData{ -// vec3 Position; -//}Output; - void main() { -// Output.Position = Position; gl_Position = P * V * 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 72bd8711..98a56f6b 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -320,15 +320,13 @@ void DrawFinalPass::BindModelTextures(std::shared_ptr& job) glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); } - //for (int i = 0; i < m_ShadowPass->CurrentNrOfSplits(); i++) - //{ - glActiveTexture(GL_TEXTURE4); - if (m_ShadowPass->DepthMap() != NULL) { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); - } else { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); - } - //} + glActiveTexture(GL_TEXTURE4); + if (m_ShadowPass->DepthMap() != NULL) { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); + } + else { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); + } } From 8647267cad3dcd549c131229e1a2554410c8ba0c Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sat, 27 Feb 2016 18:04:33 +0100 Subject: [PATCH 23/35] Make code less dumb, save 7 fps --- include/Engine/Rendering/ShadowPass.h | 38 +++++------ resources/Shaders/ForwardPlus.frag.glsl | 87 +++++++++++++++--------- resources/Shaders/ForwardPlus.vert.glsl | 6 +- src/Engine/Editor/EditorSystem.cpp | 2 +- src/Engine/Rendering/ShadowPass.cpp | 88 +++++++++++-------------- 5 files changed, 113 insertions(+), 108 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 6fab8a3a..1ff09338 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -10,10 +10,9 @@ #include "imgui/imgui.h" #define MAX_SPLITS 4 -#define MAP_SIZE 216.f -enum NearFar { Near = 0, Far = 1 }; -enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 }; +enum NearFar { NEAR = 0, FAR = 1 }; +enum LRBT { LEFT = 0, RIGHT = 1, BOTTOM = 2, TOP = 3 }; struct Frustum { @@ -30,8 +29,8 @@ struct Frustum class ShadowPass { public: - ShadowPass(IRenderer* renderer); + ShadowPass(IRenderer * renderer, int ShadowResX, int ShadowResY); ~ShadowPass(); void InitializeFrameBuffers(); @@ -39,45 +38,40 @@ public: void ClearBuffer(); void Draw(RenderScene& scene); - //GLuint DepthMap(int level) const { return m_DepthMap[level]; } GLuint DepthMap() const { return m_DepthMap; } std::array LightP() const { return m_LightProjection; } std::array LightV() const { return m_LightView; } std::array FarDistance() const { return { m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; } + + void SetSplitWeight(float split_weight) { m_SplitWeight = split_weight; }; private: - void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v); - void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); void InitializeCameras(RenderScene & scene); - float FindRadius(Frustum& frustum); + void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); + void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir); + void UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v); + void PointsToLightspace(Frustum& frustum, glm::mat4 v); - void RadiusToLightspace(Frustum& frustum, glm::mat4 v); + + float FindRadius(Frustum& frustum); + void RadiusToLightspace(Frustum& frustum); EventBroker* m_EventBroker; const IRenderer* m_Renderer; - //std::array m_DepthMap; - //std::array m_DepthBuffer; GLuint m_DepthMap; FrameBuffer m_DepthBuffer; + ShaderProgram* m_ShadowProgram; std::array m_LightProjection; std::array m_LightView; - ShaderProgram* m_ShadowProgram; - GLuint m_DepthFBO; - GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; - //GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f }; - GLuint m_ResolutionSizeWidth = 1024 * 2; - GLuint m_ResolutionSizeHeigth = 1024 * 2; + GLuint m_ResolutionSizeHeight = 1024 * 2; - bool m_ShadowOn = true; - int m_ShadowLevel = 0; - - int m_CurrentNrOfSplits = 3; - float m_SplitWeight = 0.7f; + int m_CurrentNrOfSplits = 4; + float m_SplitWeight = 0.91f; std::array m_shadowFrusta; }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index b3240911..d29abfdc 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,7 +1,6 @@ #version 430 #define MAX_SPLITS 4 -#define SPLIT_WEIGHT 0.7 uniform mat4 M; uniform mat4 V; @@ -139,6 +138,7 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu return vec4(TBN * normalize(NormalMap), 0.0); } +// Returns a "random" value. float Random(vec3 seed, int i) { vec4 seed4 = vec4(seed, i); @@ -162,7 +162,7 @@ float PoissonShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_co for (int i = 0; i < taps; i++) { loop = i; - vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index)); + vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * (1.0 + layer_index)); shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); } @@ -179,7 +179,7 @@ float PoissonDotShadow(sampler2DArrayShadow depth_texture_array, vec3 projection for (int i = 0; i < taps; i++) { loop = int(16.0 * Random(gl_FragCoord.xyy, i)) % 16; - vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * SPLIT_WEIGHT * (1.0 + layer_index)); + vec3 newProjCoords = projection_coords + vec3(poissonDisk[loop], 0.0) / (spread * (1.0 + layer_index)); shadowMapDepth += multiplier * texture(depth_texture_array, vec4(newProjCoords.xy, layer_index, newProjCoords.z)); } @@ -196,7 +196,7 @@ float SoftwarePCF(sampler2DArrayShadow depth_texture_array, vec3 projection_coor { for(int y = -1; y <= 1; y++) { - shadow += texture(depth_texture_array, vec4(projection_coords.xy + vec2(x, y) * texelSize.xy, layer_index, projection_coords.z)); + shadow += texture(depth_texture_array, vec4(projection_coords.xy + vec2(x, y) * texelSize.xy / (1.0 + layer_index), layer_index, projection_coords.z)); } } @@ -206,40 +206,56 @@ float SoftwarePCF(sampler2DArrayShadow depth_texture_array, vec3 projection_coor float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler2DArrayShadow depth_texture_array, int layer_index) { float shadowMapDepth; - float bias; + float bias = 0.005; // Various bias methods. - //bias = 0.005; - //bias = max(0.05 * (1.0 - dot(normal, light_dir)), 0.005); - bias = 0.005 * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + bias = max(0.05 * (1.0 - dot(normal, light_dir)), bias); + //bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + + // Calculate coordinates in projection space. - // Calculate coordinates in projection space vec3 projCoords = vec3(light_space_pos.xy, light_space_pos.z + bias) / light_space_pos.w; projCoords = projCoords * 0.5 + 0.5; // Various methods for shadow calculation in fastest to slowest order. shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index); - //shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0); - //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 1500.0); + //shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS - 1]); + //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS]); //shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); - - float shadow = 1.0 - shadowMapDepth; - return shadow; + return 1.0 - shadowMapDepth; } -int getShadowIndex(float far_distance[MAX_SPLITS]) +int getShadowIndex(float far_distance[1]) +{ + return 0; +} + +int getShadowIndex(float far_distance[2]) +{ + float depth = gl_FragCoord.z / gl_FragCoord.w; + + int index = 1; + if ( depth < far_distance[0] ) + { + index = 0; + } + + return index; +} + +int getShadowIndex(float far_distance[3]) { float depth = gl_FragCoord.z / gl_FragCoord.w; int index = 2; - if( depth < far_distance[0] ) + if ( depth < far_distance[0] ) { index = 0; } - else if( depth < far_distance[1] && depth > far_distance[0] ) + else if ( depth < far_distance[1] && depth > far_distance[0] ) { index = 1; } @@ -247,6 +263,27 @@ int getShadowIndex(float far_distance[MAX_SPLITS]) return index; } +int getShadowIndex(float far_distance[4]) +{ + float depth = gl_FragCoord.z / gl_FragCoord.w; + + int index = 3; + if ( depth < far_distance[0] ) + { + index = 0; + } + else if ( depth < far_distance[1] && depth > far_distance[0] ) + { + index = 1; + } + else if ( depth < far_distance[2] && depth > far_distance[1] ) + { + index = 2; + } + + return index; +} + void main() { vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); @@ -282,9 +319,7 @@ void main() light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); } else if (light.Type == 2) { //Directional int DepthMapIndex = getShadowIndex(FarDistance); - light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); - shadowFactor = CalcShadowValue(Input.PositionLightSpace[DepthMapIndex], Input.Normal, vec3(light.Direction), DepthMap, DepthMapIndex); } @@ -298,19 +333,7 @@ void main() //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; - + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index 0d9661cc..d77ee20a 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -47,11 +47,8 @@ void main() + BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[3] * Bones[int(BoneIndices[3])]; } - - //vec4 lightPos = 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; @@ -61,7 +58,6 @@ void main() Output.ExplosionColor = vec4(1.0); Output.ExplosionPercentageElapsed = 0.0; - //Output.PositionLightSpace = lightPos; // N for(int i = 0; i < MAX_SPLITS; i++) { Output.PositionLightSpace[i] = LightP[i] * LightV[i] * M * vec4(Position, 1.0); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index a13bac0b..6128c1f9 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -18,7 +18,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - (double&)cCamera["FarClip"] = 60.0; + (double&)cCamera["FarClip"] = 300.0; m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index dd423f25..33a42e3b 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -1,6 +1,16 @@ #include "Rendering/ShadowPass.h" +ShadowPass::ShadowPass(IRenderer * renderer, int shadow_res_x, int shadow_res_y) +{ + m_Renderer = renderer; + m_ResolutionSizeWidth = shadow_res_x; + m_ResolutionSizeHeight = shadow_res_y; + + InitializeFrameBuffers(); + InitializeShaderPrograms(); +} + ShadowPass::ShadowPass(IRenderer * renderer) { m_Renderer = renderer; @@ -41,8 +51,28 @@ void ShadowPass::UpdateSplitDist(std::array& frusta, float frusta[m_CurrentNrOfSplits - 1].FarClip = far_distance; } +void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v) +{ + std::array CornerPoint = { + glm::vec4(-1.f, -1.f, -1.f, 1.f), + glm::vec4(-1.f, 1.f, -1.f, 1.f), + glm::vec4(1.f, 1.f, -1.f, 1.f), + glm::vec4(1.f, -1.f, -1.f, 1.f), + glm::vec4(-1.f, -1.f, 1.f, 1.f), + glm::vec4(-1.f, 1.f, 1.f, 1.f), + glm::vec4(1.f, 1.f, 1.f, 1.f), + glm::vec4(1.f, -1.f, 1.f, 1.f) + }; + + for (int i = 0; i < 8; i++) { + glm::vec4 NDC = glm::inverse(p) * CornerPoint[i]; + NDC = NDC / NDC.w; + frustum.CornerPoint[i] = glm::vec3(glm::inverse(v) * NDC); + } +} + // Compute the 8 corner points of the current view frustum in world space -void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir, glm::mat4 p, glm::mat4 v) +void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir) { glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); @@ -68,25 +98,6 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position frustum.CornerPoint[5] = far_center + up * far_height - right * far_width; frustum.CornerPoint[6] = far_center + up * far_height + right * far_width; frustum.CornerPoint[7] = far_center - up * far_height + right * far_width; - - // Alternative way. - //std::array CornerPoint = { - // glm::vec4(-1.f, -1.f, -1.f, 1.f), - // glm::vec4(-1.f, 1.f, -1.f, 1.f), - // glm::vec4(1.f, 1.f, -1.f, 1.f), - // glm::vec4(1.f, -1.f, -1.f, 1.f), - // glm::vec4(-1.f, -1.f, 1.f, 1.f), - // glm::vec4(-1.f, 1.f, 1.f, 1.f), - // glm::vec4(1.f, 1.f, 1.f, 1.f), - // glm::vec4(1.f, -1.f, 1.f, 1.f) }; - - //std::array FinalPoints; - - //for (int i = 0; i < 8; i++) { - // glm::vec4 NDC = glm::inverse(p) * CornerPoint[i]; - // NDC = NDC / NDC.w; - // FinalPoints[i] = glm::vec3(glm::inverse(v) * NDC); - //} } float ShadowPass::FindRadius(Frustum& frustum) @@ -106,18 +117,13 @@ float ShadowPass::FindRadius(Frustum& frustum) void ShadowPass::InitializeFrameBuffers() { - GLERROR("depthMap failed PRE"); // Depth texture glGenTextures(1, &m_DepthMap); - GLERROR("depthMap failed1"); glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap); - GLERROR("depthMap failed2"); - glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits); - GLERROR("depthMap failed3"); + glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); - GLERROR("depthMap failed4"); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -126,11 +132,9 @@ void ShadowPass::InitializeFrameBuffers() glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - GLERROR("depthMap failed5"); m_DepthBuffer.AddResource(std::shared_ptr(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits))); m_DepthBuffer.Generate(); - //} GLERROR("depthMap failed END"); } @@ -178,7 +182,7 @@ void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) frustum.LRBT = { left, right, bottom, top }; } -void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) +void ShadowPass::RadiusToLightspace(Frustum& frustum) { float left = -frustum.Radius; float right = frustum.Radius; @@ -190,10 +194,7 @@ void ShadowPass::RadiusToLightspace(Frustum& frustum, glm::mat4 v) 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); - ImGui::Checkbox("EnableShadow", &m_ShadowOn); - //ImGui::DragInt("ShadowLevel", &m_ShadowLevel, 0.05f, 0, m_CurrentNrOfSplits - 1); InitializeCameras(scene); UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); @@ -201,19 +202,14 @@ void ShadowPass::Draw(RenderScene & scene) ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); m_ShadowProgram->Bind(); + GLuint shaderHandle = m_ShadowProgram->GetHandle(); + glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight); for (int i = 0; i < m_CurrentNrOfSplits; i++) { - UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward(), scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix()); - //float test = FindRadius(m_shadFrusta[i]); - - GLuint shaderHandle = m_ShadowProgram->GetHandle(); + UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward()); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - - glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeigth); - //state->Disable(GL_CULL_FACE); - for (auto &job : scene.DirectionalLightJobs) { auto directionalLightJob = std::dynamic_pointer_cast(job); @@ -221,7 +217,7 @@ void ShadowPass::Draw(RenderScene & scene) m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); - m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[Left], m_shadowFrusta[i].LRBT[Right], m_shadowFrusta[i].LRBT[Bottom], m_shadowFrusta[i].LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]); + m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); @@ -240,14 +236,10 @@ void ShadowPass::Draw(RenderScene & scene) GLERROR("Shadow Draw ERROR"); } } - } - - glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - - m_ShadowProgram->Unbind(); - } + m_ShadowProgram->Unbind(); + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); m_DepthBuffer.Unbind(); delete state; } From 14b0a64720cead73c7c3ed124cd126f6f6ef8a32 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sat, 27 Feb 2016 18:42:51 +0100 Subject: [PATCH 24/35] begin fixing transparent object's shadows --- include/Engine/Rendering/ShadowPass.h | 24 +++++----- .../Schema/Entities/QualityAssurance.xml | 2 +- resources/Shaders/ForwardPlus.frag.glsl | 4 +- src/Engine/Rendering/DrawFinalPass.cpp | 13 +++--- src/Engine/Rendering/Renderer.cpp | 3 -- src/Engine/Rendering/ShadowPass.cpp | 44 ++++++++++++------- src/Engine/Rendering/ShadowPassState.cpp | 5 +-- 7 files changed, 51 insertions(+), 44 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 1ff09338..a26ddf97 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -29,19 +29,19 @@ struct Frustum class ShadowPass { public: - ShadowPass(IRenderer* renderer); + ShadowPass(IRenderer* renderer); ShadowPass(IRenderer * renderer, int ShadowResX, int ShadowResY); - ~ShadowPass(); - - void InitializeFrameBuffers(); - void InitializeShaderPrograms(); - void ClearBuffer(); - void Draw(RenderScene& scene); + ~ShadowPass(); + + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + void ClearBuffer(); + void Draw(RenderScene& scene); GLuint DepthMap() const { return m_DepthMap; } std::array LightP() const { return m_LightProjection; } std::array LightV() const { return m_LightView; } - std::array FarDistance() const { return { m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } + std::array FarDistance() const { return{ m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; } void SetSplitWeight(float split_weight) { m_SplitWeight = split_weight; }; @@ -55,7 +55,7 @@ private: float FindRadius(Frustum& frustum); void RadiusToLightspace(Frustum& frustum); - + EventBroker* m_EventBroker; const IRenderer* m_Renderer; @@ -66,9 +66,9 @@ private: std::array m_LightProjection; std::array m_LightView; - GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; - GLuint m_ResolutionSizeWidth = 1024 * 2; - GLuint m_ResolutionSizeHeight = 1024 * 2; + GLfloat m_NearFarPlane[2] = { -34.f, 27.f }; + GLuint m_ResolutionSizeWidth = 1024 * 2; + GLuint m_ResolutionSizeHeight = 1024 * 2; int m_CurrentNrOfSplits = 4; float m_SplitWeight = 0.91f; diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index e057cf38..04dfc6aa 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -569,7 +569,7 @@ Models/Core/UnitCube.mesh - + true diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index d29abfdc..8250d96d 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -210,8 +210,8 @@ float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler // Various bias methods. - bias = max(0.05 * (1.0 - dot(normal, light_dir)), bias); - //bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + //bias = max(0.05 * (1.0 - dot(normal, light_dir)), bias); + bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); // Calculate coordinates in projection space. diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 98a56f6b..a1139902 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -226,6 +226,12 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptrFillColor)); glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage); glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor)); + + //Shadow + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data())); + glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data()); + GLERROR("END"); } @@ -248,13 +254,6 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrLightV().data())); glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data()); - - //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"); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a26a7f09..cc6ab11b 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -136,9 +136,6 @@ void Renderer::Draw(RenderFrame& frame) if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } - if (m_DebugTextureToDraw == 5) { - m_DrawScreenQuadPass->Draw(m_ShadowPass->DepthMap()); - } m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 33a42e3b..be09626d 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -53,7 +53,7 @@ void ShadowPass::UpdateSplitDist(std::array& frusta, float void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v) { - std::array CornerPoint = { + std::array CornerPoint = { glm::vec4(-1.f, -1.f, -1.f, 1.f), glm::vec4(-1.f, 1.f, -1.f, 1.f), glm::vec4(1.f, 1.f, -1.f, 1.f), @@ -81,7 +81,7 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position glm::vec3 near_center = camera_position + glm::normalize(view_dir) * frustum.NearClip; frustum.MiddlePoint = near_center + (far_center - near_center) * 0.5f; - up = glm::normalize(glm::cross(right, view_dir)); + up = glm::normalize(glm::cross(right, view_dir)); // these heights and widths are half the heights and widths of the near and far plane rectangles. float near_height = tan(frustum.FOV / 2.f) * frustum.NearClip; @@ -118,7 +118,7 @@ float ShadowPass::FindRadius(Frustum& frustum) void ShadowPass::InitializeFrameBuffers() { // Depth texture - glGenTextures(1, &m_DepthMap); + glGenTextures(1, &m_DepthMap); glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap); glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits); @@ -136,17 +136,17 @@ void ShadowPass::InitializeFrameBuffers() m_DepthBuffer.AddResource(std::shared_ptr(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits))); m_DepthBuffer.Generate(); - GLERROR("depthMap failed END"); + GLERROR("depthMap failed END"); } void ShadowPass::InitializeShaderPrograms() { - m_ShadowProgram = ResourceManager::Load("#ShadowProgram"); - m_ShadowProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Shadow.vert.glsl"))); - m_ShadowProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Shadow.frag.glsl"))); - m_ShadowProgram->Compile(); - m_ShadowProgram->BindFragDataLocation(0, "ShadowMap"); - m_ShadowProgram->Link(); + m_ShadowProgram = ResourceManager::Load("#ShadowProgram"); + m_ShadowProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Shadow.vert.glsl"))); + m_ShadowProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Shadow.frag.glsl"))); + m_ShadowProgram->Compile(); + m_ShadowProgram->BindFragDataLocation(0, "ShadowMap"); + m_ShadowProgram->Link(); } void ShadowPass::ClearBuffer() @@ -155,7 +155,7 @@ void ShadowPass::ClearBuffer() for (int i = 0; i < m_CurrentNrOfSplits; i++) { glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -187,7 +187,7 @@ void ShadowPass::RadiusToLightspace(Frustum& frustum) float left = -frustum.Radius; float right = frustum.Radius; float bottom = -frustum.Radius; - float top =frustum.Radius; + float top = frustum.Radius; frustum.LRBT = { left, right, bottom, top }; } @@ -198,7 +198,7 @@ void ShadowPass::Draw(RenderScene & scene) InitializeCameras(scene); UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); - + ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); m_ShadowProgram->Bind(); @@ -207,9 +207,9 @@ void ShadowPass::Draw(RenderScene & scene) for (int i = 0; i < m_CurrentNrOfSplits; i++) { UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward()); - + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - + for (auto &job : scene.DirectionalLightJobs) { auto directionalLightJob = std::dynamic_pointer_cast(job); @@ -235,6 +235,20 @@ void ShadowPass::Draw(RenderScene & scene) GLERROR("Shadow Draw ERROR"); } + + state->CullFace(GL_BACK); + for (auto &objectJob : scene.TransparentObjects) { + auto modelJob = std::dynamic_pointer_cast(objectJob); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + + GLERROR("Shadow Draw ERROR"); + } + state->CullFace(GL_FRONT); } } } diff --git a/src/Engine/Rendering/ShadowPassState.cpp b/src/Engine/Rendering/ShadowPassState.cpp index f84b6436..67e0dd1f 100644 --- a/src/Engine/Rendering/ShadowPassState.cpp +++ b/src/Engine/Rendering/ShadowPassState.cpp @@ -2,16 +2,13 @@ ShadowPassState::ShadowPassState(GLuint frameBuffer) { - GLERROR("---2"); BindFramebuffer(frameBuffer); - GLERROR("---3"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); Disable(GL_BLEND); Disable(GL_TEXTURE_2D); CullFace(GL_FRONT); - ClearColor(glm::vec4(255.f, 128.f, 128.f, 128.f)); - GLERROR("---4"); + ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f)); } ShadowPassState::~ShadowPassState() From 6dd7f1a657147ad8b8134ab6cd48b0f846949b3b Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sun, 28 Feb 2016 18:00:23 +0100 Subject: [PATCH 25/35] Buggy transparent shadows. Transparent textures might glow. --- include/Engine/Rendering/ShadowPass.h | 3 +++ resources/Schema/Entities/QualityAssurance.xml | 4 ++-- resources/Shaders/ForwardPlus.frag.glsl | 4 ++-- resources/Shaders/Shadow.frag.glsl | 16 +++++++++++++++- resources/Shaders/Shadow.vert.glsl | 8 +++++++- src/Engine/Rendering/Renderer.cpp | 10 +--------- src/Engine/Rendering/ShadowPass.cpp | 11 +++++++++++ src/Engine/Rendering/ShadowPassState.cpp | 2 ++ 8 files changed, 43 insertions(+), 15 deletions(-) diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index a26ddf97..c4007cce 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -62,6 +62,7 @@ private: GLuint m_DepthMap; FrameBuffer m_DepthBuffer; ShaderProgram* m_ShadowProgram; + //ShaderProgram* m_TransparentShadowProgram; std::array m_LightProjection; std::array m_LightView; @@ -74,6 +75,8 @@ private: float m_SplitWeight = 0.91f; std::array m_shadowFrusta; + + Texture* m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 04dfc6aa..86281abd 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -568,8 +568,8 @@ - Models/Core/UnitCube.mesh - + Models/BushAlive.mesh + true diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 8250d96d..c3e1a681 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -327,8 +327,8 @@ void main() totalLighting.Specular += light_result.Specular; } - totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); //LightResult getInformation; diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index 58290b59..3287df7c 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -1,10 +1,24 @@ #version 430 -layout(location = 0 ) out float ShadowMap; +#define ALPHA_CUTOFF 0.3 + +layout (binding = 12) uniform sampler2D DiffuseTexture; +uniform float Alpha; + +in VertexData{ + vec2 TextureCoordinate; +}Input; + +layout (location = 0) out float ShadowMap; void main() { + vec4 diffuseTexel = texture(DiffuseTexture, Input.TextureCoordinate) * Alpha; + if (diffuseTexel.a < ALPHA_CUTOFF) + { + discard; + } } diff --git a/resources/Shaders/Shadow.vert.glsl b/resources/Shaders/Shadow.vert.glsl index 8a0dc8f4..7b1b26fb 100644 --- a/resources/Shaders/Shadow.vert.glsl +++ b/resources/Shaders/Shadow.vert.glsl @@ -4,9 +4,15 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; -layout(location = 0) in vec3 Position; +layout (location = 0) in vec3 Position; +layout (location = 4) in vec2 TextureCoords; + +out VertexData{ + vec2 TextureCoordinate; +}Output; void main() { gl_Position = P * V * M * vec4(Position, 1.0); + Output.TextureCoordinate = TextureCoords; } \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index cc6ab11b..cdbd5786 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -68,14 +68,6 @@ void Renderer::InitializeShaders() { m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); m_ExplosionEffectProgram = ResourceManager::Load("#ExplosionEffectProgram"); - //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ExplosionEffect.vert.glsl"))); - //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); - //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ExplosionEffect.frag.glsl"))); - //m_ExplosionEffectProgram->Compile(); - //m_ExplosionEffectProgram->Link(); - - - } void Renderer::InputUpdate(double dt) @@ -93,7 +85,7 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& frame) { - ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Shadow"); + ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking"); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index be09626d..c0ee1e54 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -147,6 +147,8 @@ void ShadowPass::InitializeShaderPrograms() m_ShadowProgram->Compile(); m_ShadowProgram->BindFragDataLocation(0, "ShadowMap"); m_ShadowProgram->Link(); + + } void ShadowPass::ClearBuffer() @@ -241,6 +243,15 @@ void ShadowPass::Draw(RenderScene & scene) auto modelJob = std::dynamic_pointer_cast(objectJob); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); + + glActiveTexture(GL_TEXTURE12); + if (modelJob->DiffuseTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); diff --git a/src/Engine/Rendering/ShadowPassState.cpp b/src/Engine/Rendering/ShadowPassState.cpp index 67e0dd1f..ef789487 100644 --- a/src/Engine/Rendering/ShadowPassState.cpp +++ b/src/Engine/Rendering/ShadowPassState.cpp @@ -9,6 +9,8 @@ ShadowPassState::ShadowPassState(GLuint frameBuffer) Disable(GL_TEXTURE_2D); CullFace(GL_FRONT); ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f)); + //Enable(GL_ALPHA_TEST); + //glAlphaFunc(GL_GREATER, 0.9f); } ShadowPassState::~ShadowPassState() From 7749fc5474d893c20ab5c09782cd3f4bb8b42910 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Sun, 28 Feb 2016 19:46:50 +0100 Subject: [PATCH 26/35] Small fixing up --- resources/Shaders/ForwardPlus.frag.glsl | 14 ++++--- resources/Shaders/Shadow.frag.glsl | 2 +- src/Engine/Rendering/ShadowPass.cpp | 54 +++++++++++++++---------- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index c3e1a681..3b94df9e 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -211,19 +211,21 @@ float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler // Various bias methods. //bias = max(0.05 * (1.0 - dot(normal, light_dir)), bias); - bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + //bias = bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); + bias = bias + bias * tan(acos(clamp(dot(normal, -light_dir), 0.0, 1.0))); // Calculate coordinates in projection space. vec3 projCoords = vec3(light_space_pos.xy, light_space_pos.z + bias) / light_space_pos.w; projCoords = projCoords * 0.5 + 0.5; + //projCoords = (floor(projCoords * 255.0)) / 255.0; // Various methods for shadow calculation in fastest to slowest order. - shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index); + //shadowMapDepth = PCFShadow(depth_texture_array, projCoords, layer_index); //shadowMapDepth = PoissonShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS - 1]); - //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS]); - //shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); + //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS - 1]); + shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); return 1.0 - shadowMapDepth; } @@ -327,8 +329,8 @@ void main() totalLighting.Specular += light_result.Specular; } - totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); //LightResult getInformation; diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index 3287df7c..a03e17c7 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -2,7 +2,7 @@ #define ALPHA_CUTOFF 0.3 -layout (binding = 12) uniform sampler2D DiffuseTexture; +layout (binding = 24) uniform sampler2D DiffuseTexture; uniform float Alpha; in VertexData{ diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index c0ee1e54..185d24ab 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -186,6 +186,8 @@ void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) void ShadowPass::RadiusToLightspace(Frustum& frustum) { + float quantizationStep = 1.0f / m_ResolutionSizeHeight; + float left = -frustum.Radius; float right = frustum.Radius; float bottom = -frustum.Radius; @@ -219,6 +221,8 @@ void ShadowPass::Draw(RenderScene & scene) m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); + //FindRadius(m_shadowFrusta[i]); + //RadiusToLightspace(m_shadowFrusta[i]); m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); @@ -227,37 +231,43 @@ void ShadowPass::Draw(RenderScene & scene) GLERROR("ShadowLight ERROR"); for (auto &objectJob : scene.OpaqueObjects) { - auto modelJob = std::dynamic_pointer_cast(objectJob); + if (!std::dynamic_pointer_cast(objectJob)) + { + auto modelJob = std::dynamic_pointer_cast(objectJob); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - GLERROR("Shadow Draw ERROR"); + GLERROR("Shadow Draw ERROR"); + } } state->CullFace(GL_BACK); for (auto &objectJob : scene.TransparentObjects) { - auto modelJob = std::dynamic_pointer_cast(objectJob); + if (!std::dynamic_pointer_cast(objectJob)) + { + auto modelJob = std::dynamic_pointer_cast(objectJob); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - - glActiveTexture(GL_TEXTURE12); - if (modelJob->DiffuseTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); + + glActiveTexture(GL_TEXTURE24); + if (modelJob->DiffuseTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + + GLERROR("Shadow Draw ERROR"); } - else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - - GLERROR("Shadow Draw ERROR"); } state->CullFace(GL_FRONT); } From 70374fa10e53f113f7e7eb4a935f1cc2bc9a86c7 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Mon, 29 Feb 2016 18:20:32 +0100 Subject: [PATCH 27/35] It compiles, but no shadows --- .../Engine/Rendering/DirectionalLightJob.h | 1 - include/Engine/Rendering/ShadowPass.h | 16 +++--- .../Shaders/ForwardPlusSkinned.vert.glsl | 2 + .../Shaders/ForwardPlusSplatMapRGB.frag.glsl | 1 + src/Engine/Rendering/FrameBuffer.cpp | 56 +++++++++---------- src/Engine/Rendering/ShadowPass.cpp | 43 +++++++++----- 6 files changed, 68 insertions(+), 51 deletions(-) diff --git a/include/Engine/Rendering/DirectionalLightJob.h b/include/Engine/Rendering/DirectionalLightJob.h index 0fcfaf84..4c12b1ed 100644 --- a/include/Engine/Rendering/DirectionalLightJob.h +++ b/include/Engine/Rendering/DirectionalLightJob.h @@ -17,7 +17,6 @@ struct DirectionalLightJob : RenderJob { Orientation = Transform::AbsoluteOrientation(m_World, transformComponent.EntityID); Direction = glm::vec4(0,0,-1,0) * glm::inverse(Orientation); - //Direction = glm::vec4((glm::vec3)directionalLightComponent["Direction"], 0.f); Color = (glm::vec4)directionalLightComponent["Color"]; Intensity = (double)directionalLightComponent["Intensity"]; }; diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index c4007cce..3f506cb7 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -14,7 +14,7 @@ enum NearFar { NEAR = 0, FAR = 1 }; enum LRBT { LEFT = 0, RIGHT = 1, BOTTOM = 2, TOP = 3 }; -struct Frustum +struct ShadowFrustum { float NearClip; float FarClip; @@ -47,14 +47,14 @@ public: void SetSplitWeight(float split_weight) { m_SplitWeight = split_weight; }; private: void InitializeCameras(RenderScene & scene); - void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); - void UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir); - void UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v); + void UpdateSplitDist(std::array& frusta, float near_distance, float far_distance); + void UpdateFrustumPoints(ShadowFrustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir); + void UpdateFrustumPoints(ShadowFrustum& frustum, glm::mat4 p, glm::mat4 v); - void PointsToLightspace(Frustum& frustum, glm::mat4 v); + void PointsToLightspace(ShadowFrustum& frustum, glm::mat4 v); - float FindRadius(Frustum& frustum); - void RadiusToLightspace(Frustum& frustum); + float FindRadius(ShadowFrustum& frustum); + void RadiusToLightspace(ShadowFrustum& frustum); EventBroker* m_EventBroker; const IRenderer* m_Renderer; @@ -74,7 +74,7 @@ private: int m_CurrentNrOfSplits = 4; float m_SplitWeight = 0.91f; - std::array m_shadowFrusta; + std::array m_shadowFrusta; Texture* m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); }; diff --git a/resources/Shaders/ForwardPlusSkinned.vert.glsl b/resources/Shaders/ForwardPlusSkinned.vert.glsl index 5fd55a8c..83db983b 100644 --- a/resources/Shaders/ForwardPlusSkinned.vert.glsl +++ b/resources/Shaders/ForwardPlusSkinned.vert.glsl @@ -21,6 +21,7 @@ out VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace[MAX_SPLITS]; }Output; void main() @@ -43,4 +44,5 @@ void main() Output.BiTangent = vec3(M * vec4(BiTangent, 0.0)); Output.ExplosionColor = vec4(1.0); Output.ExplosionPercentageElapsed = 0.0; + Output.PositionLightSpace = boneTransform * vec4(Position, 1.0); } \ No newline at end of file diff --git a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl index cf358b96..af50155d 100644 --- a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl @@ -82,6 +82,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace[MAX_SPLITS]; }Input; out vec4 sceneColor; diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index e0dd9b2d..167de142 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -61,45 +61,45 @@ void FrameBuffer::Generate() glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); GLERROR("1"); - for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { - switch ((*it)->m_ResourceType) { - case GL_TEXTURE_2D: - glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { + switch ((*it)->m_ResourceType) { + case GL_TEXTURE_2D: + glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); attachments.push_back((*it)->m_Attachment); - GLERROR("FrameBuffer generate: glFramebufferTexture2D"); - break; - case GL_RENDERBUFFER: - glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); - GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); - break; + GLERROR("FrameBuffer generate: glFramebufferTexture2D"); + break; + case GL_RENDERBUFFER: + glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); + break; case GL_TEXTURE_2D_ARRAY: glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, 0); attachments.push_back((*it)->m_Attachment); GLERROR("FrameBuffer generate: GL_TEXTURE_2D_ARRAY"); break; - } - GLERROR("2"); + } + GLERROR("2"); - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { - GLERROR("Attachment"); + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { + GLERROR("Attachment"); - } - GLERROR("3"); + } + GLERROR("3"); - GLenum* bufferTextures = &attachments[0]; - glDrawBuffers(attachments.size(), bufferTextures); - if (GLERROR("GLBufferAttachement error")) { - printf(": AttachmentSize %i", attachments.size()); - } - - if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - GLERROR("Framebuffer incomplete"); - //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); - exit(EXIT_FAILURE); - } - GLERROR("END"); + GLenum* bufferTextures = &attachments[0]; + glDrawBuffers(attachments.size(), bufferTextures); + if (GLERROR("GLBufferAttachement error")) { + printf(": AttachmentSize %i", attachments.size()); + } + if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + GLERROR("Framebuffer incomplete"); + //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); + exit(EXIT_FAILURE); + } + GLERROR("END"); + } } void FrameBuffer::Bind() diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 185d24ab..df0da0e1 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -34,7 +34,7 @@ void ShadowPass::InitializeCameras(RenderScene & scene) // UpdateSplitDist computes the near and far distances for every frustum slice // in camera eye space - that is, at what distance does a slice start and end -void ShadowPass::UpdateSplitDist(std::array& frusta, float near_distance, float far_distance) +void ShadowPass::UpdateSplitDist(std::array& frusta, float near_distance, float far_distance) { float lambda = m_SplitWeight; float ratio = far_distance / near_distance; @@ -51,7 +51,7 @@ void ShadowPass::UpdateSplitDist(std::array& frusta, float frusta[m_CurrentNrOfSplits - 1].FarClip = far_distance; } -void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v) +void ShadowPass::UpdateFrustumPoints(ShadowFrustum& frustum, glm::mat4 p, glm::mat4 v) { std::array CornerPoint = { glm::vec4(-1.f, -1.f, -1.f, 1.f), @@ -72,7 +72,7 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::mat4 p, glm::mat4 v) } // Compute the 8 corner points of the current view frustum in world space -void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir) +void ShadowPass::UpdateFrustumPoints(ShadowFrustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir) { glm::vec3 up = glm::vec3(0.f, 1.f, 0.f); glm::vec3 right = glm::normalize(glm::cross(view_dir, up)); @@ -100,7 +100,7 @@ void ShadowPass::UpdateFrustumPoints(Frustum& frustum, glm::vec3 camera_position frustum.CornerPoint[7] = far_center - up * far_height + right * far_width; } -float ShadowPass::FindRadius(Frustum& frustum) +float ShadowPass::FindRadius(ShadowFrustum& frustum) { float radius = 0.f; @@ -164,7 +164,7 @@ void ShadowPass::ClearBuffer() m_DepthBuffer.Unbind(); } -void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) +void ShadowPass::PointsToLightspace(ShadowFrustum& frustum, glm::mat4 v) { float left = INFINITY; float right = -INFINITY; @@ -184,7 +184,7 @@ void ShadowPass::PointsToLightspace(Frustum& frustum, glm::mat4 v) frustum.LRBT = { left, right, bottom, top }; } -void ShadowPass::RadiusToLightspace(Frustum& frustum) +void ShadowPass::RadiusToLightspace(ShadowFrustum& frustum) { float quantizationStep = 1.0f / m_ResolutionSizeHeight; @@ -214,7 +214,7 @@ void ShadowPass::Draw(RenderScene & scene) glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - for (auto &job : scene.DirectionalLightJobs) { + for (auto &job : scene.Jobs.DirectionalLight) { auto directionalLightJob = std::dynamic_pointer_cast(job); if (directionalLightJob) { @@ -230,7 +230,7 @@ void ShadowPass::Draw(RenderScene & scene) GLERROR("ShadowLight ERROR"); - for (auto &objectJob : scene.OpaqueObjects) { + for (auto &objectJob : scene.Jobs.OpaqueObjects) { if (!std::dynamic_pointer_cast(objectJob)) { auto modelJob = std::dynamic_pointer_cast(objectJob); @@ -246,20 +246,35 @@ void ShadowPass::Draw(RenderScene & scene) } state->CullFace(GL_BACK); - for (auto &objectJob : scene.TransparentObjects) { + for (auto &objectJob : scene.Jobs.TransparentObjects) { if (!std::dynamic_pointer_cast(objectJob)) { auto modelJob = std::dynamic_pointer_cast(objectJob); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - - glActiveTexture(GL_TEXTURE24); - if (modelJob->DiffuseTexture != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + + switch (modelJob->Type) { + case RawModel::MaterialType::SingleTextures: + case RawModel::MaterialType::Basic: + { + glActiveTexture(GL_TEXTURE24); + if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + break; } - else { + case RawModel::MaterialType::SplatMapping: + { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + break; + } } glBindVertexArray(modelJob->Model->VAO); From 2ed5fad6996778e21b734b9f9015d049fd49f7bc Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Mon, 29 Feb 2016 19:17:16 +0100 Subject: [PATCH 28/35] The shadows are working --- resources/Shaders/ForwardPlus.frag.glsl | 7 ++++--- resources/Shaders/ForwardPlus.vert.glsl | 8 -------- src/Engine/Rendering/DrawFinalPass.cpp | 18 ++++++++---------- src/Engine/Rendering/ShadowPass.cpp | 6 +++--- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index d1c75cd0..fc7527be 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -2,6 +2,7 @@ #define MAX_SPLITS 4 #define MIN_AMBIENT_LIGHT 0.3 +#define SHADOW_STRENGTH 0.3 //Should be ambient uniform mat4 M; uniform mat4 V; @@ -235,7 +236,7 @@ float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler //shadowMapDepth = PoissonDotShadow(depth_texture_array, projCoords, layer_index, 4, 25.0 * FarDistance[MAX_SPLITS - 1]); shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); - return 1.0 - shadowMapDepth; + return shadowMapDepth; } int getShadowIndex(float far_distance[1]) @@ -342,8 +343,8 @@ void main() totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); } - totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); - totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgba)) - vec4(vec3(shadowFactor), 0.0); + totalLighting.Diffuse *= vec4(min(vec3(shadowFactor) + AmbientColor.xyz, vec3(1.0)), 1.0); + totalLighting.Specular *= vec4(min(vec3(shadowFactor) + AmbientColor.xyz, vec3(1.0)), 1.0); //LightResult getInformation; diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index b8d42b14..2a54415b 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -25,14 +25,6 @@ out VertexData{ vec4 PositionLightSpace[MAX_SPLITS]; }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() { gl_Position = P*V*M * vec4(Position, 1.0); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 11249703..4470ad1b 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -1014,6 +1014,14 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrm_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } + + glActiveTexture(GL_TEXTURE6); + if (m_ShadowPass->DepthMap() != NULL) { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); + } + else { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); + } break; } case RawModel::MaterialType::SplatMapping: @@ -1081,15 +1089,5 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrDepthMap() != NULL) { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); - } - else { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); - } - - } diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index df0da0e1..0fa2193a 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -253,8 +253,8 @@ void ShadowPass::Draw(RenderScene & scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - - switch (modelJob->Type) { + + /*switch (modelJob->Type) { case RawModel::MaterialType::SingleTextures: case RawModel::MaterialType::Basic: { @@ -275,7 +275,7 @@ void ShadowPass::Draw(RenderScene & scene) glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); break; } - } + }*/ glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); From 0908be1e0200092e4c855579badc281f5a3008a0 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Mon, 29 Feb 2016 19:45:56 +0100 Subject: [PATCH 29/35] Shadows are pretty much done. --- .../Engine/Rendering/DirectionalLightJob.h | 2 + .../Schema/Components/DirectionalLight.xml | 1 + .../Schema/Components/DirectionalLight.xsd | 1 + resources/Shaders/ForwardPlus.frag.glsl | 1 - src/Engine/Rendering/ShadowPass.cpp | 40 ++++++++++--------- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/Engine/Rendering/DirectionalLightJob.h b/include/Engine/Rendering/DirectionalLightJob.h index 4c12b1ed..65d477d1 100644 --- a/include/Engine/Rendering/DirectionalLightJob.h +++ b/include/Engine/Rendering/DirectionalLightJob.h @@ -19,12 +19,14 @@ struct DirectionalLightJob : RenderJob Direction = glm::vec4(0,0,-1,0) * glm::inverse(Orientation); Color = (glm::vec4)directionalLightComponent["Color"]; Intensity = (double)directionalLightComponent["Intensity"]; + //TextureAlphaShadows = (bool)directionalLightComponent["TextureAlphaShadows"]; }; glm::quat Orientation; glm::vec4 Direction; glm::vec4 Color; float Intensity; + bool TextureAlphaShadows = false; void CalculateHash() override { diff --git a/resources/Schema/Components/DirectionalLight.xml b/resources/Schema/Components/DirectionalLight.xml index 7f777ef8..a4b22985 100644 --- a/resources/Schema/Components/DirectionalLight.xml +++ b/resources/Schema/Components/DirectionalLight.xml @@ -2,5 +2,6 @@ 0.8 + true \ No newline at end of file diff --git a/resources/Schema/Components/DirectionalLight.xsd b/resources/Schema/Components/DirectionalLight.xsd index a14248a8..692d9677 100644 --- a/resources/Schema/Components/DirectionalLight.xsd +++ b/resources/Schema/Components/DirectionalLight.xsd @@ -9,6 +9,7 @@ + diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index fc7527be..0fd76f80 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -2,7 +2,6 @@ #define MAX_SPLITS 4 #define MIN_AMBIENT_LIGHT 0.3 -#define SHADOW_STRENGTH 0.3 //Should be ambient uniform mat4 M; uniform mat4 V; diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 0fa2193a..14cfcc09 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -254,28 +254,31 @@ void ShadowPass::Draw(RenderScene & scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - /*switch (modelJob->Type) { - case RawModel::MaterialType::SingleTextures: - case RawModel::MaterialType::Basic: - { - glActiveTexture(GL_TEXTURE24); - if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture); - glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat)); + if (directionalLightJob->TextureAlphaShadows) { + switch (modelJob->Type) { + case RawModel::MaterialType::SingleTextures: + case RawModel::MaterialType::Basic: + { + glActiveTexture(GL_TEXTURE24); + if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + break; } - else { + case RawModel::MaterialType::SplatMapping: + { + glActiveTexture(GL_TEXTURE24); glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + break; + } } - break; } - case RawModel::MaterialType::SplatMapping: - { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); - break; - } - }*/ glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -288,7 +291,8 @@ void ShadowPass::Draw(RenderScene & scene) } } } - m_ShadowProgram->Unbind(); + glActiveTexture(GL_TEXTURE24); + glDisable(GL_TEXTURE_2D); glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); m_DepthBuffer.Unbind(); delete state; From 4153a31e3a3fe9b1bb17cba766f76cdeae21fbfb Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Mon, 29 Feb 2016 19:47:24 +0100 Subject: [PATCH 30/35] Fix goof. --- src/Engine/Rendering/ShadowPass.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 14cfcc09..3fc2c5d0 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -291,8 +291,6 @@ void ShadowPass::Draw(RenderScene & scene) } } } - glActiveTexture(GL_TEXTURE24); - glDisable(GL_TEXTURE_2D); glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); m_DepthBuffer.Unbind(); delete state; From d32a483bb42a1831962676204c48eacee9ae28a9 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Tue, 1 Mar 2016 13:17:17 +0100 Subject: [PATCH 31/35] remove farclip override --- src/Engine/Editor/EditorSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 67fad18a..e770c154 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -18,7 +18,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - (double&)cCamera["FarClip"] = 300.0; + //(double&)cCamera["FarClip"] = 300.0; m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); From 1961c16fe27b7b7c82350c26f519a5a038867061 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Tue, 1 Mar 2016 13:27:52 +0100 Subject: [PATCH 32/35] add weight slider --- src/Engine/Rendering/ShadowPass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 3fc2c5d0..7b45e31a 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -199,6 +199,7 @@ void ShadowPass::RadiusToLightspace(ShadowFrustum& frustum) void ShadowPass::Draw(RenderScene & scene) { ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); + ImGui::DragFloat("ShadowClippingWeight", &m_SplitWeight, 0.001f, 0.f, 1.f); InitializeCameras(scene); UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); From 1ae2f3f5f35e16d8cebf00421354a9eb0f3cb227 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Tue, 1 Mar 2016 19:10:13 +0100 Subject: [PATCH 33/35] Begin clean-up --- include/Engine/Rendering/DirectionalLightJob.h | 1 - include/Engine/Rendering/FrameBuffer.h | 14 -------------- include/Engine/Rendering/ShadowPass.h | 2 +- resources/Schema/Components/DirectionalLight.xml | 1 - resources/Schema/Components/DirectionalLight.xsd | 1 - src/Engine/Rendering/FrameBuffer.cpp | 15 --------------- src/Engine/Rendering/ShadowPass.cpp | 2 +- 7 files changed, 2 insertions(+), 34 deletions(-) diff --git a/include/Engine/Rendering/DirectionalLightJob.h b/include/Engine/Rendering/DirectionalLightJob.h index 65d477d1..96b2ec9c 100644 --- a/include/Engine/Rendering/DirectionalLightJob.h +++ b/include/Engine/Rendering/DirectionalLightJob.h @@ -19,7 +19,6 @@ struct DirectionalLightJob : RenderJob Direction = glm::vec4(0,0,-1,0) * glm::inverse(Orientation); Color = (glm::vec4)directionalLightComponent["Color"]; Intensity = (double)directionalLightComponent["Intensity"]; - //TextureAlphaShadows = (bool)directionalLightComponent["TextureAlphaShadows"]; }; glm::quat Orientation; diff --git a/include/Engine/Rendering/FrameBuffer.h b/include/Engine/Rendering/FrameBuffer.h index 325fbe3b..cf63b6c6 100644 --- a/include/Engine/Rendering/FrameBuffer.h +++ b/include/Engine/Rendering/FrameBuffer.h @@ -8,12 +8,10 @@ class BufferResource { public: BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment); - BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment, GLuint layers); GLuint* m_ResourceHandle; GLenum m_ResourceType; GLenum m_Attachment; - GLuint m_Layers; private: }; @@ -24,9 +22,6 @@ class ResourceType : public BufferResource public: ResourceType(GLuint* resourceHandle, GLenum attachment) : BufferResource(resourceHandle, RESOURCETYPE, attachment) { } - - ResourceType(GLuint* resourceHandle, GLenum attachment, GLuint layers) - : BufferResource(resourceHandle, RESOURCETYPE, attachment, layers) { } }; class Texture2D : public ResourceType @@ -48,15 +43,6 @@ public: ~RenderBuffer(); }; -class Texture2DArray : public ResourceType -{ -public: - Texture2DArray(GLuint* resourceHandle, GLenum attachment, GLuint layers) - : ResourceType(resourceHandle, attachment, layers) { }; - - ~Texture2DArray(); -}; - class FrameBuffer { public: diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 3f506cb7..372ba6f2 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -41,7 +41,7 @@ public: GLuint DepthMap() const { return m_DepthMap; } std::array LightP() const { return m_LightProjection; } std::array LightV() const { return m_LightView; } - std::array FarDistance() const { return{ m_shadowFrusta[0].FarClip, m_shadowFrusta[1].FarClip, m_shadowFrusta[2].FarClip, m_shadowFrusta[3].FarClip }; } + std::array FarDistance() const { std::array f; for (int i = 0; i < MAX_SPLITS; i++) f[i] = m_shadowFrusta[i].FarClip; return f; } int CurrentNrOfSplits() const { return m_CurrentNrOfSplits; } void SetSplitWeight(float split_weight) { m_SplitWeight = split_weight; }; diff --git a/resources/Schema/Components/DirectionalLight.xml b/resources/Schema/Components/DirectionalLight.xml index a4b22985..7f777ef8 100644 --- a/resources/Schema/Components/DirectionalLight.xml +++ b/resources/Schema/Components/DirectionalLight.xml @@ -2,6 +2,5 @@ 0.8 - true \ No newline at end of file diff --git a/resources/Schema/Components/DirectionalLight.xsd b/resources/Schema/Components/DirectionalLight.xsd index 692d9677..a14248a8 100644 --- a/resources/Schema/Components/DirectionalLight.xsd +++ b/resources/Schema/Components/DirectionalLight.xsd @@ -9,7 +9,6 @@ - diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 167de142..7c86a7e2 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -9,14 +9,6 @@ BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLen m_Attachment = attachment; } -BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment, GLuint layers) -{ - m_ResourceHandle = resourceHandle; - m_ResourceType = resourceType; - m_Attachment = attachment; - m_Layers = layers; -} - Texture2D::~Texture2D() { if (m_ResourceHandle != 0) { @@ -24,13 +16,6 @@ Texture2D::~Texture2D() } } -Texture2DArray::~Texture2DArray() -{ - if (m_ResourceHandle != 0) { - glDeleteTextures(1, m_ResourceHandle); - } -} - RenderBuffer::~RenderBuffer() { if (m_ResourceHandle != 0) { diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index 7b45e31a..d7741dff 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -133,7 +133,7 @@ void ShadowPass::InitializeFrameBuffers() glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - m_DepthBuffer.AddResource(std::shared_ptr(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT, m_CurrentNrOfSplits))); + m_DepthBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthMap, GL_DEPTH_ATTACHMENT))); m_DepthBuffer.Generate(); GLERROR("depthMap failed END"); From 5a6374f013f40ba8f78dfc33cc969ae711420c88 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 2 Mar 2016 10:57:22 +0100 Subject: [PATCH 34/35] Fix the remainder of errors. Might have borked splatmap in the process. --- assets | 2 +- src/Engine/Editor/EditorSystem.cpp | 3 ++- src/Engine/Rendering/DrawFinalPass.cpp | 14 +++++++------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/assets b/assets index 1d09801c..72530423 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 1d09801cf45452e082ad08bac5e29e3102f31724 +Subproject commit 72530423ad3744341f42cbfdcba18295a2cfac90 diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index e770c154..0aefac9d 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -18,7 +18,8 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - //(double&)cCamera["FarClip"] = 300.0; + // TOBIAS TVINGADE MIG ATT HÅRDKODA + (double&)cCamera["FarClip"] = 400.0; m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index ef930ca6..ac4fa8e4 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -368,6 +368,13 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, SSAOTexture); + glActiveTexture(GL_TEXTURE6); + if (m_ShadowPass->DepthMap() != NULL) { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); + } + else { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); + } for (auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); @@ -1017,13 +1024,6 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrDepthMap() != NULL) { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); - } - else { - glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture); - } break; } case RawModel::MaterialType::SplatMapping: From 7ea26d10eeca755564d52ad6cf736981b596bb3c Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Thu, 3 Mar 2016 03:28:21 +0100 Subject: [PATCH 35/35] Rewritten. Works as a charm now. --- .../Engine/Rendering/DirectionalLightJob.h | 7 +- include/Engine/Rendering/DrawFinalPass.h | 2 +- include/Engine/Rendering/Renderer.h | 4 +- include/Engine/Rendering/ShadowPass.h | 13 +- include/Engine/Rendering/ShadowPassState.h | 4 +- resources/Shaders/ForwardPlus.frag.glsl | 135 ++++++++------- .../Shaders/ForwardPlusShieldCheck.frag.glsl | 2 + .../Shaders/ForwardPlusSkinned.vert.glsl | 10 +- .../Shaders/ForwardPlusSplatMap.frag.glsl | 3 + .../Shaders/ForwardPlusSplatMapRGB.frag.glsl | 1 + resources/Shaders/Shadow.frag.glsl | 4 +- src/Engine/Editor/EditorRenderSystem.cpp | 2 +- src/Engine/Editor/EditorSystem.cpp | 5 +- src/Engine/Rendering/DrawFinalPass.cpp | 16 +- src/Engine/Rendering/FrameBuffer.cpp | 32 ++-- src/Engine/Rendering/RenderSystem.cpp | 2 +- src/Engine/Rendering/Renderer.cpp | 16 +- src/Engine/Rendering/ShadowPass.cpp | 157 +++++++++--------- src/Engine/Rendering/ShadowPassState.cpp | 8 +- 19 files changed, 224 insertions(+), 199 deletions(-) diff --git a/include/Engine/Rendering/DirectionalLightJob.h b/include/Engine/Rendering/DirectionalLightJob.h index 96b2ec9c..5f104ca5 100644 --- a/include/Engine/Rendering/DirectionalLightJob.h +++ b/include/Engine/Rendering/DirectionalLightJob.h @@ -15,17 +15,16 @@ struct DirectionalLightJob : RenderJob DirectionalLightJob(ComponentWrapper transformComponent, ComponentWrapper directionalLightComponent, World* m_World) : RenderJob() { - Orientation = Transform::AbsoluteOrientation(m_World, transformComponent.EntityID); - Direction = glm::vec4(0,0,-1,0) * glm::inverse(Orientation); + + Direction = glm::vec4(0,0,-1,0) * glm::inverse(Transform::AbsoluteOrientation(m_World, transformComponent.EntityID)); + //Direction = glm::vec4((glm::vec3)directionalLightComponent["Direction"], 0.f); Color = (glm::vec4)directionalLightComponent["Color"]; Intensity = (double)directionalLightComponent["Intensity"]; }; - glm::quat Orientation; glm::vec4 Direction; glm::vec4 Color; float Intensity; - bool TextureAlphaShadows = false; void CalculateHash() override { diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 82ae216d..c5b937c6 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -64,9 +64,9 @@ private: const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; - const ShadowPass* m_ShadowPass; const CubeMapPass* m_CubeMapPass; const SSAOPass* m_SSAOPass; + const ShadowPass* m_ShadowPass; ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 75517442..fd3b215e 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -24,9 +24,9 @@ #include "../Core/Transform.h" #include "imgui/imgui.h" #include "TextPass.h" -#include "ShadowPass.h" #include "Util/CommonFunctions.h" #include "Core/PerformanceTimer.h" +#include "ShadowPass.h" class Renderer : public IRenderer { @@ -74,9 +74,9 @@ private: DrawScreenQuadPass* m_DrawScreenQuadPass; DrawBloomPass* m_DrawBloomPass; DrawColorCorrectionPass* m_DrawColorCorrectionPass; - ShadowPass* m_ShadowPass; SSAOPass* m_SSAOPass; CubeMapPass* m_CubeMapPass; + ShadowPass* m_ShadowPass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/include/Engine/Rendering/ShadowPass.h b/include/Engine/Rendering/ShadowPass.h index 372ba6f2..6db8a624 100644 --- a/include/Engine/Rendering/ShadowPass.h +++ b/include/Engine/Rendering/ShadowPass.h @@ -1,5 +1,5 @@ -#ifndef ShadowPass_h_ -#define ShadowPass_h_ +#ifndef ShadowPass_h__ +#define ShadowPass_h__ #include "IRenderer.h" #include "FrameBuffer.h" @@ -38,6 +38,8 @@ public: void ClearBuffer(); void Draw(RenderScene& scene); + void DebugGUI(); + GLuint DepthMap() const { return m_DepthMap; } std::array LightP() const { return m_LightProjection; } std::array LightV() const { return m_LightView; } @@ -62,7 +64,6 @@ private: GLuint m_DepthMap; FrameBuffer m_DepthBuffer; ShaderProgram* m_ShadowProgram; - //ShaderProgram* m_TransparentShadowProgram; std::array m_LightProjection; std::array m_LightView; @@ -71,8 +72,12 @@ private: GLuint m_ResolutionSizeWidth = 1024 * 2; GLuint m_ResolutionSizeHeight = 1024 * 2; + bool m_TransparentObjects = false; + bool m_TexturedShadows = false; + bool m_EnableShadows = true; + int m_CurrentNrOfSplits = 4; - float m_SplitWeight = 0.91f; + float m_SplitWeight = 0.962f; std::array m_shadowFrusta; diff --git a/include/Engine/Rendering/ShadowPassState.h b/include/Engine/Rendering/ShadowPassState.h index ec08a77c..f881b48e 100644 --- a/include/Engine/Rendering/ShadowPassState.h +++ b/include/Engine/Rendering/ShadowPassState.h @@ -6,8 +6,8 @@ class ShadowPassState : public RenderState { public: - ShadowPassState(GLuint frameBuffer); - ~ShadowPassState(); + ShadowPassState(GLuint frameBuffer); + ~ShadowPassState(); private: }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index baf1baf1..f7ddd00c 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,7 +1,7 @@ #version 430 -#define MAX_SPLITS 4 #define MIN_AMBIENT_LIGHT 0.3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; @@ -12,22 +12,22 @@ uniform vec2 ScreenDimensions; uniform vec4 FillColor; uniform vec4 AmbientColor; uniform float FillPercentage; -uniform float FarDistance[MAX_SPLITS]; uniform float GlowIntensity = 10; uniform vec3 CameraPosition; uniform int SSAOQuality; +uniform float FarDistance[MAX_SPLITS]; uniform vec2 DiffuseUVRepeat; uniform vec2 NormalUVRepeat; uniform vec2 SpecularUVRepeat; uniform vec2 GlowUVRepeat; layout (binding = 0) uniform sampler2D AOTexture; -layout (binding = 6) uniform sampler2DArrayShadow DepthMap; layout (binding = 1) uniform sampler2D DiffuseTexture; layout (binding = 2) uniform sampler2D NormalMapTexture; layout (binding = 3) uniform sampler2D SpecularMapTexture; layout (binding = 4) uniform sampler2D GlowMapTexture; layout (binding = 5) uniform samplerCube CubeMap; +layout (binding = 13) uniform sampler2DArrayShadow DepthMap; #define TILE_SIZE 16 @@ -62,7 +62,6 @@ layout (std430, binding = 4) buffer LightIndexBuffer float LightIndex[]; }; - in VertexData{ vec3 Position; vec3 Normal; @@ -155,6 +154,62 @@ float Random(vec3 seed, int i) return fract(sin(dot_product) * 43758.5453); } +int getShadowIndex(float far_distance[1]) +{ + return 0; +} + +int getShadowIndex(float far_distance[2]) +{ + float depth = gl_FragCoord.z / gl_FragCoord.w; + + int index = 1; + if ( depth < far_distance[0] ) + { + index = 0; + } + + return index; +} + +int getShadowIndex(float far_distance[3]) +{ + float depth = gl_FragCoord.z / gl_FragCoord.w; + + int index = 2; + if ( depth < far_distance[0] ) + { + index = 0; + } + else if ( depth < far_distance[1] && depth > far_distance[0] ) + { + index = 1; + } + + return index; +} + +int getShadowIndex(float far_distance[4]) +{ + float depth = gl_FragCoord.z / gl_FragCoord.w; + + int index = 3; + if ( depth < far_distance[0] ) + { + index = 0; + } + else if ( depth < far_distance[1] && depth > far_distance[0] ) + { + index = 1; + } + else if ( depth < far_distance[2] && depth > far_distance[1] ) + { + index = 2; + } + + return index; +} + // Standard hardware-calculated PCF method float PCFShadow(sampler2DArrayShadow depth_texture_array, vec3 projection_coords, int layer_index) { @@ -237,62 +292,6 @@ float CalcShadowValue(vec4 light_space_pos, vec3 normal, vec3 light_dir, sampler shadowMapDepth = SoftwarePCF(depth_texture_array, projCoords, layer_index, bias); return shadowMapDepth; -} - -int getShadowIndex(float far_distance[1]) -{ - return 0; -} - -int getShadowIndex(float far_distance[2]) -{ - float depth = gl_FragCoord.z / gl_FragCoord.w; - - int index = 1; - if ( depth < far_distance[0] ) - { - index = 0; - } - - return index; -} - -int getShadowIndex(float far_distance[3]) -{ - float depth = gl_FragCoord.z / gl_FragCoord.w; - - int index = 2; - if ( depth < far_distance[0] ) - { - index = 0; - } - else if ( depth < far_distance[1] && depth > far_distance[0] ) - { - index = 1; - } - - return index; -} - -int getShadowIndex(float far_distance[4]) -{ - float depth = gl_FragCoord.z / gl_FragCoord.w; - - int index = 3; - if ( depth < far_distance[0] ) - { - index = 0; - } - else if ( depth < far_distance[1] && depth > far_distance[0] ) - { - index = 1; - } - else if ( depth < far_distance[2] && depth > far_distance[1] ) - { - index = 2; - } - - return index; } void main() @@ -322,14 +321,14 @@ void main() int start = int(LightGrids.Data[currentTile].Start); int amount = int(LightGrids.Data[currentTile].Amount); - - float shadowFactor = 0.0; + float shadowFactor = 0.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 @@ -342,17 +341,17 @@ void main() totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a); totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); } - + totalLighting.Diffuse *= vec4(min(vec3(shadowFactor) + AmbientColor.xyz, vec3(1.0)), 1.0); totalLighting.Specular *= vec4(min(vec3(shadowFactor) + AmbientColor.xyz, vec3(1.0)), 1.0); - - //LightResult getInformation; - + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); - color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); float specularResult = (specularTexel.r + specularTexel.g + specularTexel.b)/3.0; vec4 reflectionTotal = reflectionColor * (1-specularTexel.a) * color_result.a; color_result = color_result * clamp(1/specularTexel.a, 0, 1) + reflectionTotal; + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; diff --git a/resources/Shaders/ForwardPlusShieldCheck.frag.glsl b/resources/Shaders/ForwardPlusShieldCheck.frag.glsl index 35db495b..8c7dce04 100644 --- a/resources/Shaders/ForwardPlusShieldCheck.frag.glsl +++ b/resources/Shaders/ForwardPlusShieldCheck.frag.glsl @@ -1,6 +1,7 @@ #version 430 #define MIN_AMBIENT_LIGHT 0.3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; @@ -69,6 +70,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace[MAX_SPLITS]; }Input; out vec4 sceneColor; diff --git a/resources/Shaders/ForwardPlusSkinned.vert.glsl b/resources/Shaders/ForwardPlusSkinned.vert.glsl index 83db983b..12b3c406 100644 --- a/resources/Shaders/ForwardPlusSkinned.vert.glsl +++ b/resources/Shaders/ForwardPlusSkinned.vert.glsl @@ -1,9 +1,13 @@ #version 430 +#define MAX_SPLITS 4 + uniform mat4 M; uniform mat4 V; uniform mat4 P; uniform mat4 Bones[100]; +uniform mat4 LightV[MAX_SPLITS]; +uniform mat4 LightP[MAX_SPLITS]; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; @@ -44,5 +48,9 @@ void main() Output.BiTangent = vec3(M * vec4(BiTangent, 0.0)); Output.ExplosionColor = vec4(1.0); Output.ExplosionPercentageElapsed = 0.0; - Output.PositionLightSpace = boneTransform * vec4(Position, 1.0); + + for(int i = 0; i < MAX_SPLITS; i++) + { + Output.PositionLightSpace[i] = LightP[i] * LightV[i] * M * boneTransform * vec4(Position, 1.0); + } } \ No newline at end of file diff --git a/resources/Shaders/ForwardPlusSplatMap.frag.glsl b/resources/Shaders/ForwardPlusSplatMap.frag.glsl index 239c51b5..655f5502 100644 --- a/resources/Shaders/ForwardPlusSplatMap.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMap.frag.glsl @@ -1,5 +1,7 @@ #version 430 +#define MAX_SPLITS 4 + uniform mat4 M; uniform mat4 V; uniform mat4 P; @@ -95,6 +97,7 @@ in VertexData{ vec2 TextureCoordinate; vec4 ExplosionColor; float ExplosionPercentageElapsed; + vec4 PositionLightSpace[MAX_SPLITS]; }Input; out vec4 sceneColor; diff --git a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl index 87349c5d..f933a605 100644 --- a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl @@ -1,6 +1,7 @@ #version 430 #define MIN_AMBIENT_LIGHT 0.3 +#define MAX_SPLITS 4 uniform mat4 M; uniform mat4 V; diff --git a/resources/Shaders/Shadow.frag.glsl b/resources/Shaders/Shadow.frag.glsl index a03e17c7..c7d153c3 100644 --- a/resources/Shaders/Shadow.frag.glsl +++ b/resources/Shaders/Shadow.frag.glsl @@ -19,6 +19,4 @@ void main() { discard; } -} - - +} \ No newline at end of file diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index a829bc6a..f5fcc1a1 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -7,7 +7,7 @@ EditorRenderSystem::EditorRenderSystem(SystemParams params, IRenderer* renderer, { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorRenderSystem::OnSetCamera); auto resolution = Rectangle::Rectangle(1280, 720); - m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 500.f); + m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 5000.f); } void EditorRenderSystem::Update(double dt) diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 0aefac9d..4bee1427 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -17,10 +17,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); - auto cCamera = m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - // TOBIAS TVINGADE MIG ATT HÅRDKODA - (double&)cCamera["FarClip"] = 400.0; - + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 6152134a..510c665e 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -4,10 +4,10 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling , m_LightCullingPass(lightCullingPass) , m_CubeMapPass(cubeMapPass) , m_SSAOPass(ssaoPass) + , m_ShadowPass(shadowPass) { //TODO: Make sure that uniforms are not sent into shader if not needed. m_ShieldPixelRate = 8; - m_ShadowPass = shadowPass; InitializeTextures(); InitializeShaderPrograms(); InitializeFrameBuffers(); @@ -343,7 +343,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_SSAOPass->SSAOTexture()); - glActiveTexture(GL_TEXTURE6); + + glActiveTexture(GL_TEXTURE13); if (m_ShadowPass->DepthMap() != NULL) { glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap()); } @@ -1091,10 +1092,10 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptrGlowIntensity); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data())); glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data()); - GLERROR("END"); } @@ -1133,12 +1134,10 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptrGlowIntensity); - glUniform1f(Location_GlowIntensity, job->GlowIntensity); - - //Shadow - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data())); glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data()); GLERROR("END"); @@ -1309,7 +1308,6 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrm_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); } - break; } case RawModel::MaterialType::SplatMapping: diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 903eb2a0..c08d4dc4 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -16,6 +16,7 @@ Texture2D::~Texture2D() } } + RenderBuffer::~RenderBuffer() { if (m_ResourceHandle != 0) { @@ -51,7 +52,6 @@ void FrameBuffer::Generate() switch ((*it)->m_ResourceType) { case GL_TEXTURE_2D: glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); - attachments.push_back((*it)->m_Attachment); GLERROR("FrameBuffer generate: glFramebufferTexture2D"); break; case GL_RENDERBUFFER: @@ -60,13 +60,13 @@ void FrameBuffer::Generate() break; case GL_TEXTURE_2D_ARRAY: glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, 0); - attachments.push_back((*it)->m_Attachment); - GLERROR("FrameBuffer generate: GL_TEXTURE_2D_ARRAY"); + GLERROR("FrameBuffer generate: glFramebufferTexture2DArray"); break; } GLERROR("2"); - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { + // Need GL_DEPTH_ATTACHMENT for shadows + if (/*(*it)->m_Attachment != GL_DEPTH_ATTACHMENT &&*/ (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { attachments.push_back((*it)->m_Attachment); } GLERROR("Attachment"); @@ -74,19 +74,19 @@ void FrameBuffer::Generate() } GLERROR("3"); - GLenum* bufferTextures = &attachments[0]; - glDrawBuffers(attachments.size(), bufferTextures); - if (GLERROR("GLBufferAttachement error")) { - printf(": AttachmentSize %i", attachments.size()); - } + GLenum* bufferTextures = &attachments[0]; + glDrawBuffers(attachments.size(), bufferTextures); + if (GLERROR("GLBufferAttachement error")) { + printf(": AttachmentSize %i", attachments.size()); + } + + if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + GLERROR("Framebuffer incomplete"); + //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); + exit(EXIT_FAILURE); + } + GLERROR("END"); - if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - GLERROR("Framebuffer incomplete"); - //LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); - exit(EXIT_FAILURE); - } - GLERROR("END"); - } } void FrameBuffer::Bind() diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 5de7bb51..a1f00c88 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -12,7 +12,7 @@ RenderSystem::RenderSystem(SystemParams params, const IRenderer* renderer, Rende EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); - m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 300.f); + m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); } RenderSystem::~RenderSystem() diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 748caec2..b9a6aa05 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -86,6 +86,11 @@ void Renderer::InitializeShaders() { m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); m_ExplosionEffectProgram = ResourceManager::Load("#ExplosionEffectProgram"); + //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ExplosionEffect.vert.glsl"))); + //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ExplosionEffect.frag.glsl"))); + //m_ExplosionEffectProgram->Compile(); + //m_ExplosionEffectProgram->Link(); } void Renderer::InputUpdate(double dt) @@ -127,8 +132,9 @@ void Renderer::Draw(RenderFrame& frame) m_PickingPass->ClearPicking(); m_DrawFinalPass->ClearBuffer(); m_DrawBloomPass->ClearBuffer(); - m_ShadowPass->ClearBuffer(); m_SSAOPass->ClearBuffer(); + m_ShadowPass->ClearBuffer(); + m_ShadowPass->DebugGUI(); PerformanceTimer::StopTimer("Renderer-ClearBuffers"); GLERROR("ClearBuffers"); for (auto scene : frame.RenderScenes) { @@ -144,7 +150,9 @@ void Renderer::Draw(RenderFrame& frame) PerformanceTimer::StartTimer("Renderer-Depth"); SortRenderJobsByDepth(*scene); GLERROR("SortByDepth"); - m_ShadowPass->Draw(*scene); + PerformanceTimer::StartTimerAndStopPrevious("Draw shadow maps"); + m_ShadowPass->Draw(*scene); + GLERROR("Draw shadow maps"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums"); m_LightCullingPass->GenerateNewFrustum(*scene); GLERROR("Generate frustums"); @@ -187,7 +195,7 @@ void Renderer::Draw(RenderFrame& frame) } if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); - } + } if (m_DebugTextureToDraw == 5) { m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture()); } @@ -239,9 +247,9 @@ void Renderer::InitializeRenderPasses() { m_PickingPass = new PickingPass(this, m_EventBroker); m_LightCullingPass = new LightCullingPass(this); - m_ShadowPass = new ShadowPass(this); m_CubeMapPass = new CubeMapPass(this); m_SSAOPass = new SSAOPass(this, m_Config); + m_ShadowPass = new ShadowPass(this); m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass, m_ShadowPass); m_DrawScreenQuadPass = new DrawScreenQuadPass(this); m_DrawBloomPass = new DrawBloomPass(this, m_Config); diff --git a/src/Engine/Rendering/ShadowPass.cpp b/src/Engine/Rendering/ShadowPass.cpp index d7741dff..daf63ef2 100644 --- a/src/Engine/Rendering/ShadowPass.cpp +++ b/src/Engine/Rendering/ShadowPass.cpp @@ -1,6 +1,5 @@ #include "Rendering/ShadowPass.h" - ShadowPass::ShadowPass(IRenderer * renderer, int shadow_res_x, int shadow_res_y) { m_Renderer = renderer; @@ -24,6 +23,15 @@ ShadowPass::~ShadowPass() } +void ShadowPass::DebugGUI() +{ + ImGui::Checkbox("EnableShadows", &m_EnableShadows); + ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); + ImGui::DragFloat("ShadowClippingWeight", &m_SplitWeight, 0.001f, 0.f, 1.f); + ImGui::Checkbox("ShadowTransparentObjects", &m_TransparentObjects); + ImGui::Checkbox("ShadowOnTextureAlphas", &m_TexturedShadows); +} + void ShadowPass::InitializeCameras(RenderScene & scene) { for (int i = 0; i < m_CurrentNrOfSplits; i++) { @@ -198,101 +206,100 @@ void ShadowPass::RadiusToLightspace(ShadowFrustum& frustum) void ShadowPass::Draw(RenderScene & scene) { - ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f); - ImGui::DragFloat("ShadowClippingWeight", &m_SplitWeight, 0.001f, 0.f, 1.f); + if (m_EnableShadows) { + InitializeCameras(scene); + UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); - InitializeCameras(scene); - UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip()); + ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); - ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle()); + m_ShadowProgram->Bind(); + GLuint shaderHandle = m_ShadowProgram->GetHandle(); + glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight); - m_ShadowProgram->Bind(); - GLuint shaderHandle = m_ShadowProgram->GetHandle(); - glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight); + for (int i = 0; i < m_CurrentNrOfSplits; i++) { + UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward()); - for (int i = 0; i < m_CurrentNrOfSplits; i++) { - UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward()); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); - glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i); + for (auto &job : scene.Jobs.DirectionalLight) { + auto directionalLightJob = std::dynamic_pointer_cast(job); - for (auto &job : scene.Jobs.DirectionalLight) { - auto directionalLightJob = std::dynamic_pointer_cast(job); + if (directionalLightJob) { + m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); - if (directionalLightJob) { - m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f)); + PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); + //FindRadius(m_shadowFrusta[i]); + //RadiusToLightspace(m_shadowFrusta[i]); + m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]); - PointsToLightspace(m_shadowFrusta[i], m_LightView[i]); - //FindRadius(m_shadowFrusta[i]); - //RadiusToLightspace(m_shadowFrusta[i]); - m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i])); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i])); + GLERROR("ShadowLight ERROR"); - GLERROR("ShadowLight ERROR"); + for (auto &objectJob : scene.Jobs.OpaqueObjects) { + if (!std::dynamic_pointer_cast(objectJob)) { + auto modelJob = std::dynamic_pointer_cast(objectJob); - for (auto &objectJob : scene.Jobs.OpaqueObjects) { - if (!std::dynamic_pointer_cast(objectJob)) - { - auto modelJob = std::dynamic_pointer_cast(objectJob); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), 1.f); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - - GLERROR("Shadow Draw ERROR"); + GLERROR("Shadow Draw ERROR"); + } } - } + if (m_TransparentObjects) { + state->CullFace(GL_BACK); + for (auto &objectJob : scene.Jobs.TransparentObjects) { + if (!std::dynamic_pointer_cast(objectJob)) { + auto modelJob = std::dynamic_pointer_cast(objectJob); - state->CullFace(GL_BACK); - for (auto &objectJob : scene.Jobs.TransparentObjects) { - if (!std::dynamic_pointer_cast(objectJob)) - { - auto modelJob = std::dynamic_pointer_cast(objectJob); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a); - - if (directionalLightJob->TextureAlphaShadows) { - switch (modelJob->Type) { - case RawModel::MaterialType::SingleTextures: - case RawModel::MaterialType::Basic: - { - glActiveTexture(GL_TEXTURE24); - if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture); - glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat)); + if (m_TexturedShadows) { + switch (modelJob->Type) { + case RawModel::MaterialType::SingleTextures: + case RawModel::MaterialType::Basic: + { + glActiveTexture(GL_TEXTURE24); + if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat)); + } + else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + glActiveTexture(GL_TEXTURE24); + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); + break; + } + } } - else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); - } - break; - } - case RawModel::MaterialType::SplatMapping: - { - glActiveTexture(GL_TEXTURE24); - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f))); - break; - } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); + + GLERROR("Shadow Draw ERROR"); } } - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); - - GLERROR("Shadow Draw ERROR"); + state->CullFace(GL_FRONT); } } - state->CullFace(GL_FRONT); } } + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + m_DepthBuffer.Unbind(); + delete state; } - glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - m_DepthBuffer.Unbind(); - delete state; -} +} \ No newline at end of file diff --git a/src/Engine/Rendering/ShadowPassState.cpp b/src/Engine/Rendering/ShadowPassState.cpp index ef789487..2211e3ab 100644 --- a/src/Engine/Rendering/ShadowPassState.cpp +++ b/src/Engine/Rendering/ShadowPassState.cpp @@ -2,10 +2,10 @@ ShadowPassState::ShadowPassState(GLuint frameBuffer) { - BindFramebuffer(frameBuffer); - Enable(GL_DEPTH_TEST); - Enable(GL_CULL_FACE); - Disable(GL_BLEND); + BindFramebuffer(frameBuffer); + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + Disable(GL_BLEND); Disable(GL_TEXTURE_2D); CullFace(GL_FRONT); ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));