Shadow maps now use instanced rendering

This commit is contained in:
Grayson Riffe (Laptop) 2021-11-04 14:18:05 -05:00
parent be06ee2d20
commit 231ac792d7
5 changed files with 111 additions and 86 deletions

View File

@ -317,7 +317,6 @@ namespace nf {
if (m_stateChange)
doStateChange();
startOfLastFrame = std::chrono::steady_clock::now();
//Should the physics update before user code?
m_physics->update(m_deltaTime);
m_currentState->update(m_deltaTime);
m_currentState->render(*m_renderer);

View File

@ -59,7 +59,7 @@ namespace nf {
modelsRemaining -= modelCount;
for (unsigned int i = 0; i < modelCount; 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);
mats.erase(mats.begin(), mats.begin() + modelCount);

View File

@ -10,6 +10,7 @@
#include "Shader.h"
#include "Light.h"
#include "Entity.h"
#include "Model.h"
#include "Cubemap.h"
#include "UIElement.h"
#include "Button.h"
@ -289,87 +290,6 @@ namespace nf {
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() {
m_baseAP.load("base.nfpack");
const char* gBufferVertex = m_baseAP.get("gBufferVertex.shader")->data;
@ -438,6 +358,113 @@ namespace nf {
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() {
delete m_gBufferShader;
delete m_lightingShader;

View File

@ -25,6 +25,5 @@ namespace nf {
unsigned int m_width, m_height;
std::unordered_map<Model*, std::vector<glm::mat4>> m_modelsToDraw;
const std::string m_modelString = "model[";
};
}

View File

@ -33,10 +33,10 @@ namespace nf {
~Renderer();
private:
void renderShadowMaps(size_t count);
void loadBaseAssets();
void createShadowMaps();
void renderShadowMaps(size_t count);
void instancedRenderShadows(Shader* shader);
Application* m_app;