Shadow maps now use instanced rendering
This commit is contained in:
parent
be06ee2d20
commit
231ac792d7
@ -317,7 +317,6 @@ namespace nf {
|
|||||||
if (m_stateChange)
|
if (m_stateChange)
|
||||||
doStateChange();
|
doStateChange();
|
||||||
startOfLastFrame = std::chrono::steady_clock::now();
|
startOfLastFrame = std::chrono::steady_clock::now();
|
||||||
//Should the physics update before user code?
|
|
||||||
m_physics->update(m_deltaTime);
|
m_physics->update(m_deltaTime);
|
||||||
m_currentState->update(m_deltaTime);
|
m_currentState->update(m_deltaTime);
|
||||||
m_currentState->render(*m_renderer);
|
m_currentState->render(*m_renderer);
|
||||||
|
@ -59,7 +59,7 @@ namespace nf {
|
|||||||
modelsRemaining -= modelCount;
|
modelsRemaining -= modelCount;
|
||||||
for (unsigned int i = 0; i < modelCount; i++) {
|
for (unsigned int i = 0; i < modelCount; i++) {
|
||||||
pos = std::to_string(i) + "]";
|
pos = std::to_string(i) + "]";
|
||||||
shader->setUniform(m_modelString + pos, mats[i]);
|
shader->setUniform("model[" + pos, mats[i]);
|
||||||
}
|
}
|
||||||
curr.first->render(shader, false, (unsigned int)modelCount);
|
curr.first->render(shader, false, (unsigned int)modelCount);
|
||||||
mats.erase(mats.begin(), mats.begin() + modelCount);
|
mats.erase(mats.begin(), mats.begin() + modelCount);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
|
#include "Model.h"
|
||||||
#include "Cubemap.h"
|
#include "Cubemap.h"
|
||||||
#include "UIElement.h"
|
#include "UIElement.h"
|
||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
@ -289,87 +290,6 @@ namespace nf {
|
|||||||
SwapBuffers(m_hdc);
|
SwapBuffers(m_hdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::renderShadowMaps(size_t count) {
|
|
||||||
float nearP = 0.1f, farP = 400.0f;
|
|
||||||
glm::mat4 directionalLightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
|
|
||||||
glm::mat4 pointLightProj = glm::perspective(glm::radians(90.0f), 1.0f, nearP, farP);
|
|
||||||
glm::mat4 lightView;
|
|
||||||
glm::mat4 lightSpaceMat;
|
|
||||||
bool directionalRendered = false;
|
|
||||||
unsigned int directionalSlot = 0; //TODO: Test this
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
Light::Type type = m_lights[i]->getType();
|
|
||||||
unsigned int tex = type == Light::Type::DIRECTIONAL ? m_directionalShadowMap : m_pointShadowMaps[i];
|
|
||||||
switch (type) {
|
|
||||||
case Light::Type::DIRECTIONAL: {
|
|
||||||
std::string stringPos;
|
|
||||||
glViewport(0, 0, m_directionalDepthTexSize, m_directionalDepthTexSize);
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
|
|
||||||
glDrawBuffer(GL_NONE);
|
|
||||||
glReadBuffer(GL_NONE);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
Vec3 posTemp = m_lights[i]->getPosition();
|
|
||||||
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
|
||||||
lightView = glm::lookAt(lightPos, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
|
|
||||||
lightSpaceMat = directionalLightProj * lightView;
|
|
||||||
m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
|
|
||||||
stringPos = "lightSpaceMat[";
|
|
||||||
stringPos += std::to_string(i);
|
|
||||||
stringPos += "]";
|
|
||||||
m_lightingShader->setUniform(stringPos, lightSpaceMat);
|
|
||||||
for (Entity* curr : m_lGame) {
|
|
||||||
curr->render(m_directionalShadowShader, true);
|
|
||||||
}
|
|
||||||
stringPos = "light[";
|
|
||||||
stringPos += std::to_string(i);
|
|
||||||
stringPos += "].directionalDepthTex";
|
|
||||||
glActiveTexture(GL_TEXTURE4 + i);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
m_lightingShader->setUniform(stringPos, 4 + (int)i);
|
|
||||||
directionalRendered = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Light::Type::POINT: {
|
|
||||||
glViewport(0, 0, m_pointDepthTexSize, m_pointDepthTexSize);
|
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0);
|
|
||||||
glDrawBuffer(GL_NONE);
|
|
||||||
glReadBuffer(GL_NONE);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
Vec3 posTemp = m_lights[i]->getPosition();
|
|
||||||
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
|
||||||
std::vector<glm::mat4> lightSpaceMats;
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
|
|
||||||
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
|
|
||||||
for (int j = 0; j < 6; j++) {
|
|
||||||
std::string stringPos = "lightSpaceMat[";
|
|
||||||
stringPos += std::to_string(j);
|
|
||||||
stringPos += "]";
|
|
||||||
m_pointShadowShader->setUniform(stringPos, lightSpaceMats[j]);
|
|
||||||
}
|
|
||||||
m_pointShadowShader->setUniform("farPlane", farP);
|
|
||||||
m_pointShadowShader->setUniform("lightPos", lightPos);
|
|
||||||
for (Entity* curr : m_lGame) {
|
|
||||||
curr->render(m_pointShadowShader, true);
|
|
||||||
}
|
|
||||||
std::string stringPos = "light[";
|
|
||||||
stringPos += std::to_string(i);
|
|
||||||
stringPos += "].pointDepthTex";
|
|
||||||
glActiveTexture(GL_TEXTURE4 + i);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
|
||||||
m_lightingShader->setUniform(stringPos, 4 + (int)i);
|
|
||||||
m_lightingShader->setUniform("farPlane", farP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_lightingShader->setUniform("numMats", (int)count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::loadBaseAssets() {
|
void Renderer::loadBaseAssets() {
|
||||||
m_baseAP.load("base.nfpack");
|
m_baseAP.load("base.nfpack");
|
||||||
const char* gBufferVertex = m_baseAP.get("gBufferVertex.shader")->data;
|
const char* gBufferVertex = m_baseAP.get("gBufferVertex.shader")->data;
|
||||||
@ -438,6 +358,113 @@ namespace nf {
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::renderShadowMaps(size_t count) {
|
||||||
|
float nearP = 0.1f, farP = 400.0f;
|
||||||
|
glm::mat4 directionalLightProj = glm::ortho(-50.0f, 50.0f, -50.0f, 50.0f, nearP, farP);
|
||||||
|
glm::mat4 pointLightProj = glm::perspective(glm::radians(90.0f), 1.0f, nearP, farP);
|
||||||
|
glm::mat4 lightView;
|
||||||
|
glm::mat4 lightSpaceMat;
|
||||||
|
bool directionalRendered = false;
|
||||||
|
unsigned int directionalSlot = 0; //TODO: Test this
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO);
|
||||||
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
|
Light::Type type = m_lights[i]->getType();
|
||||||
|
unsigned int tex = type == Light::Type::DIRECTIONAL ? m_directionalShadowMap : m_pointShadowMaps[i];
|
||||||
|
switch (type) {
|
||||||
|
case Light::Type::DIRECTIONAL: {
|
||||||
|
std::string stringPos;
|
||||||
|
glViewport(0, 0, m_directionalDepthTexSize, m_directionalDepthTexSize);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
Vec3 posTemp = m_lights[i]->getPosition();
|
||||||
|
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
||||||
|
lightView = glm::lookAt(lightPos, glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));
|
||||||
|
lightSpaceMat = directionalLightProj * lightView;
|
||||||
|
m_directionalShadowShader->setUniform("lightSpace", lightSpaceMat);
|
||||||
|
stringPos = "lightSpaceMat[";
|
||||||
|
stringPos += std::to_string(i);
|
||||||
|
stringPos += "]";
|
||||||
|
m_lightingShader->setUniform(stringPos, lightSpaceMat);
|
||||||
|
|
||||||
|
instancedRenderShadows(m_directionalShadowShader);
|
||||||
|
|
||||||
|
stringPos = "light[";
|
||||||
|
stringPos += std::to_string(i);
|
||||||
|
stringPos += "].directionalDepthTex";
|
||||||
|
glActiveTexture(GL_TEXTURE4 + i);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
m_lightingShader->setUniform(stringPos, 4 + (int)i);
|
||||||
|
directionalRendered = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Light::Type::POINT: {
|
||||||
|
glViewport(0, 0, m_pointDepthTexSize, m_pointDepthTexSize);
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0);
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
Vec3 posTemp = m_lights[i]->getPosition();
|
||||||
|
glm::vec3 lightPos(posTemp.x, posTemp.y, posTemp.z);
|
||||||
|
std::vector<glm::mat4> lightSpaceMats;
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
lightSpaceMats.push_back(pointLightProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
|
||||||
|
for (int j = 0; j < 6; j++) {
|
||||||
|
std::string stringPos = "lightSpaceMat[";
|
||||||
|
stringPos += std::to_string(j);
|
||||||
|
stringPos += "]";
|
||||||
|
m_pointShadowShader->setUniform(stringPos, lightSpaceMats[j]);
|
||||||
|
}
|
||||||
|
m_pointShadowShader->setUniform("farPlane", farP);
|
||||||
|
m_pointShadowShader->setUniform("lightPos", lightPos);
|
||||||
|
|
||||||
|
instancedRenderShadows(m_pointShadowShader);
|
||||||
|
|
||||||
|
std::string stringPos = "light[";
|
||||||
|
stringPos += std::to_string(i);
|
||||||
|
stringPos += "].pointDepthTex";
|
||||||
|
glActiveTexture(GL_TEXTURE4 + i);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||||
|
m_lightingShader->setUniform(stringPos, 4 + (int)i);
|
||||||
|
m_lightingShader->setUniform("farPlane", farP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_lightingShader->setUniform("numMats", (int)count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::instancedRenderShadows(Shader* shader) {
|
||||||
|
std::unordered_map<Model*, std::vector<glm::mat4>> modelsToDraw;
|
||||||
|
for (Entity* curr : m_lGame) {
|
||||||
|
modelsToDraw[curr->getModel()].push_back(curr->getModelMatrix());
|
||||||
|
}
|
||||||
|
for (auto& curr : modelsToDraw) {
|
||||||
|
std::vector<glm::mat4>& mats = curr.second;
|
||||||
|
std::string pos;
|
||||||
|
size_t modelsRemaining = mats.size();
|
||||||
|
while (modelsRemaining != 0) {
|
||||||
|
size_t modelCount;
|
||||||
|
if (modelsRemaining > 60)
|
||||||
|
modelCount = 60;
|
||||||
|
else
|
||||||
|
modelCount = modelsRemaining;
|
||||||
|
modelsRemaining -= modelCount;
|
||||||
|
for (unsigned int i = 0; i < modelCount; i++) {
|
||||||
|
pos = std::to_string(i) + "]";
|
||||||
|
shader->setUniform("model[" + pos, mats[i]);
|
||||||
|
}
|
||||||
|
curr.first->render(shader, true, (unsigned int)modelCount);
|
||||||
|
mats.erase(mats.begin(), mats.begin() + modelCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Renderer::~Renderer() {
|
Renderer::~Renderer() {
|
||||||
delete m_gBufferShader;
|
delete m_gBufferShader;
|
||||||
delete m_lightingShader;
|
delete m_lightingShader;
|
||||||
|
@ -25,6 +25,5 @@ namespace nf {
|
|||||||
unsigned int m_width, m_height;
|
unsigned int m_width, m_height;
|
||||||
|
|
||||||
std::unordered_map<Model*, std::vector<glm::mat4>> m_modelsToDraw;
|
std::unordered_map<Model*, std::vector<glm::mat4>> m_modelsToDraw;
|
||||||
const std::string m_modelString = "model[";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -33,10 +33,10 @@ namespace nf {
|
|||||||
|
|
||||||
~Renderer();
|
~Renderer();
|
||||||
private:
|
private:
|
||||||
void renderShadowMaps(size_t count);
|
|
||||||
|
|
||||||
void loadBaseAssets();
|
void loadBaseAssets();
|
||||||
void createShadowMaps();
|
void createShadowMaps();
|
||||||
|
void renderShadowMaps(size_t count);
|
||||||
|
void instancedRenderShadows(Shader* shader);
|
||||||
|
|
||||||
Application* m_app;
|
Application* m_app;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user