LightcullingPass for forward+ is now separate from Renderer.cpp.

This commit is contained in:
Tleety
2015-12-18 14:31:16 +01:00
parent ab6af30a28
commit 069a6756b9
6 changed files with 177 additions and 155 deletions
+55 -4
View File
@@ -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
};
+4 -2
View File
@@ -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<glm::vec2, EntityID>& 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;
+5 -49
View File
@@ -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;
};
+1
View File
@@ -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 )
+107
View File
@@ -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<ShaderProgram>("#CalculateFrustumProgram");
m_CalculateFrustumProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
m_CalculateFrustumProgram->Compile();
m_CalculateFrustumProgram->Link();
m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
m_LightCullProgram->AddShader(std::shared_ptr<Shader>(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;
}
}
+5 -100
View File
@@ -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<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
@@ -73,16 +70,6 @@ void Renderer::InitializeShaders()
m_DrawScreenQuadProgram->Compile();
m_DrawScreenQuadProgram->Link();
m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
m_CalculateFrustumProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
m_CalculateFrustumProgram->Compile();
m_CalculateFrustumProgram->Link();
m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
m_LightCullProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/cullLights.comp.glsl")));
m_LightCullProgram->Compile();
m_LightCullProgram->Link();
m_ForwardPlusProgram = ResourceManager::Load<ShaderProgram>("#ForwardPlusProgram");
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ForwardPlus.vert.glsl")));
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(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<ModelJob>(job);