From 069a6756b96eb70167b2948a45418e0dcff72d9e Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 18 Dec 2015 14:31:16 +0100 Subject: [PATCH] LightcullingPass for forward+ is now separate from Renderer.cpp. --- include/Engine/Rendering/LightCullingPass.h | 59 ++++++++++- include/Engine/Rendering/PickingPass.h | 6 +- include/Engine/Rendering/Renderer.h | 54 +--------- resources/Shaders/ForwardPlus.frag.glsl | 1 + src/Engine/Rendering/LightCullingPass.cpp | 107 ++++++++++++++++++++ src/Engine/Rendering/Renderer.cpp | 105 +------------------ 6 files changed, 177 insertions(+), 155 deletions(-) diff --git a/include/Engine/Rendering/LightCullingPass.h b/include/Engine/Rendering/LightCullingPass.h index cf661e1f..f0ed5d6b 100644 --- a/include/Engine/Rendering/LightCullingPass.h +++ b/include/Engine/Rendering/LightCullingPass.h @@ -1,6 +1,9 @@ #ifndef LightCullingPass_h__ #define LightCullingPass_h__ +#define TILE_SIZE 16 +#define NUM_LIGHTS 1000 + #include "IRenderer.h" #include "LightCullingPassState.h" #include "ShaderProgram.h" @@ -9,19 +12,67 @@ class LightCullingPass { public: - LightCullingPass(); + LightCullingPass(IRenderer* renderer); ~LightCullingPass(); - void GenerateNewFrustum(); -private: void CullLights(); - void InitializeTextures(); + GLuint FrustumSSBO() const { return m_FrustumSSBO; } + GLuint LightSSBO() const { return m_LightSSBO; } + GLuint LightGridSSBO() const { return m_LightGridSSBO; } + GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; } + GLuint LightIndexSSBO() const { return m_LightIndexSSBO; } +private: + void InitializeSSBOs(); void InitializeShaderPrograms(); + const IRenderer* m_Renderer; + GLuint m_FrustumSSBO = 0; + GLuint m_LightSSBO = 0; + GLuint m_LightGridSSBO = 0; + GLuint m_LightOffsetSSBO = 0; + GLuint m_LightIndexSSBO = 0; + + ShaderProgram* m_CalculateFrustumProgram; + ShaderProgram* m_LightCullProgram; + + struct Plane { + glm::vec3 Normal; + float d; + }; + + struct Frustum { + Plane Planes[4]; + }; + Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution + + void TEMPCreateLights(); + + //This should be a component + struct PointLight { + glm::vec4 Position = glm::vec4(0.f); + glm::vec4 Color = glm::vec4(1.f); + float Radius = 5.f; + float Intensity = 0.8f; + float Falloff = 0.3f; + float Padding = 1337; + }; + PointLight m_PointLights[NUM_LIGHTS]; + + struct LightGrid { + float Start; + float Amount; + glm::vec2 Padding; + }; + + LightGrid m_LightGrid[80*45]; //TODO: Renderer: Make this change with resolution + + int m_LightOffset = 0; + + float m_LightIndex[80*45*200]; //TODO: Renderer: Make this change with resolution }; diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index e1bc42db..0c1261ce 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -1,6 +1,8 @@ #ifndef PickingPass_h__ #define PickingPass_h__ + + #include "IRenderer.h" #include "PickingPassState.h" #include "FrameBuffer.h" @@ -9,6 +11,8 @@ #include "../Core/EventBroker.h" #include "EPicking.h" + + class PickingPass { public: @@ -20,7 +24,6 @@ public: void Draw(RenderQueueCollection& rq); - //Getters const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } @@ -28,7 +31,6 @@ public: GLuint DepthBuffer() const { return m_DepthBuffer; } const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } - private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index d8928b18..048e6f7e 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -12,11 +12,7 @@ #include "../Core/World.h" #include "PickingPass.h" #include "DrawScenePass.h" - - -#define TILE_SIZE 16 -#define NUM_LIGHTS 1000 - +#include "LightCullingPass.h" #include "../Core/EventBroker.h" #include "EPicking.h" @@ -46,12 +42,12 @@ private: DrawScenePass* m_DrawScenePass; PickingPass* m_PickingPass; + LightCullingPass* m_LightCullingPass; //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); void InitializeTextures(); - void InitializeSSBOs(); void InitializeRenderPasses(); //TODO: Renderer: Get InputUpdate out of renderer void InputUpdate(double dt); @@ -59,58 +55,18 @@ private: void DrawScreenQuad(GLuint textureToDraw); //----------------------Forward+-----------------------// - void CalculateFrustum(); - void CullLights(); void DrawForwardPlus(RenderQueueCollection& rq); //Frustum - struct Plane { - glm::vec3 Normal; - float d; - }; - - struct Frustum { - Plane Planes[4]; - }; - Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution - - //Lights - void TEMPCreateLights(); - //TODO: Renderer: Add Directionllights, spotlights and area lights to this as type. - struct PointLight { - glm::vec4 Position = glm::vec4(0.f); - glm::vec4 Color = glm::vec4(1.f); - float Radius = 5.f; - float Intensity = 0.8f; - float Falloff = 0.3f; - float Padding = 1337; - }; - PointLight m_PointLights[NUM_LIGHTS]; - - struct LightGrid { - float Start; - float Amount; - glm::vec2 Padding; - }; - - LightGrid m_LightGrid[80*45]; - - int m_LightOffset = 0; - - float m_LightIndex[80*45*200]; + //-------------------------SSBO------------------------// - GLuint m_FrustumSSBO = 0; - GLuint m_LightSSBO = 0; - GLuint m_LightGridSSBO = 0; - GLuint m_LightOffsetSSBO = 0; - GLuint m_LightIndexSSBO = 0; + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram* m_BasicForwardProgram; ShaderProgram* m_DrawScreenQuadProgram; - ShaderProgram* m_CalculateFrustumProgram; - ShaderProgram* m_LightCullProgram; + ShaderProgram* m_ForwardPlusProgram; }; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 568195ce..79d5411c 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -115,6 +115,7 @@ void main() } fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; + //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1); //fragmentColor = texel * Input.DiffuseColor * Color; if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) diff --git a/src/Engine/Rendering/LightCullingPass.cpp b/src/Engine/Rendering/LightCullingPass.cpp index e69de29b..85f27a37 100644 --- a/src/Engine/Rendering/LightCullingPass.cpp +++ b/src/Engine/Rendering/LightCullingPass.cpp @@ -0,0 +1,107 @@ +#include "Rendering/LightCullingPass.h" + +LightCullingPass::LightCullingPass(IRenderer* renderer) +{ + m_Renderer = renderer; + TEMPCreateLights(); + InitializeSSBOs(); + InitializeShaderPrograms(); + GenerateNewFrustum(); +} + +LightCullingPass::~LightCullingPass() +{ + +} + +void LightCullingPass::GenerateNewFrustum() +{ + GLERROR("CalculateFrustum Error: Pre"); + + m_CalculateFrustumProgram->Bind(); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); + glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix())); + glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + glDispatchCompute(5, 3, 1); //TODO: Renderer: This needs change so resolution will be right. + + GLERROR("CalculateFrustum Error: End"); +} + +void LightCullingPass::CullLights() +{ + GLERROR("CullLights Error: Pre"); + m_LightOffset = 0; + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + m_LightCullProgram->Bind(); + glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(m_Renderer->Camera()->ViewMatrix())); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); + glDispatchCompute(m_Renderer->Resolution().Width / TILE_SIZE, m_Renderer->Resolution().Height / TILE_SIZE, 1); + + GLERROR("CullLights Error: End"); +} + +void LightCullingPass::InitializeSSBOs() +{ + glGenBuffers(1, &m_FrustumSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + GLERROR("m_FrustumSSBO"); + + glGenBuffers(1, &m_LightSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + GLERROR("m_LightSSBO"); + + glGenBuffers(1, &m_LightGridSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + GLERROR("m_LightGridSSBO"); + + + glGenBuffers(1, &m_LightOffsetSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + GLERROR("m_LightOffsetSSBO"); + + glGenBuffers(1, &m_LightIndexSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + GLERROR("m_LightIndexSSBO"); +} + +void LightCullingPass::InitializeShaderPrograms() +{ + m_CalculateFrustumProgram = ResourceManager::Load("#CalculateFrustumProgram"); + m_CalculateFrustumProgram->AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); + m_CalculateFrustumProgram->Compile(); + m_CalculateFrustumProgram->Link(); + + m_LightCullProgram = ResourceManager::Load("#LightCullProgram"); + m_LightCullProgram->AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); + m_LightCullProgram->Compile(); + m_LightCullProgram->Link(); +} + +void LightCullingPass::TEMPCreateLights() +{ + for (int i = 0; i < NUM_LIGHTS; i++) { + glm::vec3 pos = glm::vec3(cos(i) * i/10.f, 0.5f, sin(i) * i/10.f); + m_PointLights[i].Position = glm::vec4(pos, 1.f); + m_PointLights[i].Color = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand()%255 / 255.f, 1.f); + m_PointLights[i].Radius = glm::length(pos) / 5.f; + } +} diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 28745305..e61c1d7c 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -9,14 +9,11 @@ void Renderer::Initialize() if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } - TEMPCreateLights(); InitializeRenderPasses(); glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); - InitializeSSBOs(); - CalculateFrustum(); m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); @@ -73,16 +70,6 @@ void Renderer::InitializeShaders() m_DrawScreenQuadProgram->Compile(); m_DrawScreenQuadProgram->Link(); - m_CalculateFrustumProgram = ResourceManager::Load("#CalculateFrustumProgram"); - m_CalculateFrustumProgram->AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); - m_CalculateFrustumProgram->Compile(); - m_CalculateFrustumProgram->Link(); - - m_LightCullProgram = ResourceManager::Load("#LightCullProgram"); - m_LightCullProgram->AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); - m_LightCullProgram->Compile(); - m_LightCullProgram->Link(); - m_ForwardPlusProgram = ResourceManager::Load("#ForwardPlusProgram"); m_ForwardPlusProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); m_ForwardPlusProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlus.frag.glsl"))); @@ -156,7 +143,7 @@ void Renderer::Draw(RenderQueueCollection& rq) { m_PickingPass->Draw(rq); //DrawScreenQuad(m_PickingPass->PickingTexture()); - CullLights(); + m_LightCullingPass->CullLights(); //m_DrawScenePass->Draw(rq); DrawForwardPlus(rq); @@ -203,93 +190,11 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin GLERROR("Texture initialization failed"); } -void Renderer::InitializeSSBOs() -{ - printf("Size: %i\n", sizeof(m_Frustums)); - glGenBuffers(1, &m_FrustumSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - GLERROR("m_FrustumSSBO"); - - glGenBuffers(1, &m_LightSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - GLERROR("m_LightSSBO"); - - glGenBuffers(1, &m_LightGridSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - GLERROR("m_LightGridSSBO"); - - - glGenBuffers(1, &m_LightOffsetSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - GLERROR("m_LightOffsetSSBO"); - - glGenBuffers(1, &m_LightIndexSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - GLERROR("m_LightIndexSSBO"); - -} - void Renderer::InitializeRenderPasses() { m_DrawScenePass = new DrawScenePass(this); m_PickingPass = new PickingPass(this, m_EventBroker); -} - -void Renderer::CalculateFrustum() -{ - GLERROR("CalculateFrustum Error: Pre"); - - m_CalculateFrustumProgram->Bind(); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); - glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); - glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); - glDispatchCompute(5, 3, 1); - - GLERROR("CalculateFrustum Error: End"); -} - -void Renderer::TEMPCreateLights() -{ - for (int i = 0; i < NUM_LIGHTS; i++) - { - glm::vec3 pos = glm::vec3(cos(i) * i/10.f , 0.5f, sin(i) * i/10.f); - m_PointLights[i].Position = glm::vec4(pos, 1.f); - m_PointLights[i].Color = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand()%255 / 255.f, 1.f); - m_PointLights[i].Radius = glm::length(pos) / 5.f; - } -} - -void Renderer::CullLights() -{ - GLERROR("CullLights Error: Pre"); - m_LightOffset = 0; - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - m_LightCullProgram->Bind(); - glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(m_Camera->ViewMatrix())); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); - glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1); - - GLERROR("CullLights Error: End"); - + m_LightCullingPass = new LightCullingPass(this); } void Renderer::DrawForwardPlus(RenderQueueCollection& rq) @@ -304,9 +209,9 @@ void Renderer::DrawForwardPlus(RenderQueueCollection& rq) m_ForwardPlusProgram->Bind(); GLuint ShaderHandle = m_ForwardPlusProgram->GetHandle(); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job);