feat: deferred lighting (WIP)

This commit is contained in:
MihailRis
2025-06-14 22:43:18 +03:00
parent 2ad076bec3
commit e849d5e9b7
10 changed files with 105 additions and 12 deletions
+56 -1
View File
@@ -84,6 +84,26 @@ void GBuffer::createDepthBuffer() {
);
}
void GBuffer::createSSAOBuffer() {
glGenTextures(1, &ssaoBuffer);
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_R16F,
width,
height,
0,
GL_RED,
GL_FLOAT,
nullptr
);
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);
}
GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -100,7 +120,20 @@ GBuffer::GBuffer(uint width, uint height) : width(width), height(height) {
createDepthBuffer();
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
logger.error() << "framebuffer is not complete!";
logger.error() << "gbuffer is not complete!";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glGenFramebuffers(1, &ssaoFbo);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
createSSAOBuffer();
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoBuffer, 0
);
GLenum ssaoAttachments[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, ssaoAttachments);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
logger.error() << "SSAO framebuffer is not complete!";
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
@@ -109,8 +142,10 @@ GBuffer::~GBuffer() {
glDeleteTextures(1, &colorBuffer);
glDeleteTextures(1, &positionsBuffer);
glDeleteTextures(1, &normalsBuffer);
glDeleteTextures(1, &ssaoBuffer);
glDeleteRenderbuffers(1, &depthBuffer);
glDeleteFramebuffers(1, &fbo);
glDeleteFramebuffers(1, &ssaoFbo);
}
void GBuffer::bind() {
@@ -118,6 +153,11 @@ void GBuffer::bind() {
glClear(GL_COLOR_BUFFER_BIT);
}
void GBuffer::bindSSAO() const {
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
glClear(GL_COLOR_BUFFER_BIT);
}
void GBuffer::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
@@ -133,6 +173,10 @@ void GBuffer::bindBuffers() const {
glBindTexture(GL_TEXTURE_2D, colorBuffer);
}
void GBuffer::bindSSAOBuffer() const {
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
}
void GBuffer::resize(uint width, uint height) {
if (this->width == width && this->height == height) {
return;
@@ -180,6 +224,17 @@ void GBuffer::resize(uint width, uint height) {
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFbo);
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_R16F, width, height, 0, GL_RED, GL_FLOAT, nullptr
);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoBuffer, 0
);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
std::unique_ptr<ImageData> GBuffer::toImage() const {
+5
View File
@@ -10,9 +10,11 @@ public:
~GBuffer() override;
void bind() override;
void bindSSAO() const;
void unbind() override;
void bindBuffers() const;
void bindSSAOBuffer() const;
void resize(uint width, uint height);
@@ -29,9 +31,12 @@ private:
uint positionsBuffer;
uint normalsBuffer;
uint depthBuffer;
uint ssaoFbo;
uint ssaoBuffer;
void createColorBuffer();
void createPositionsBuffer();
void createNormalsBuffer();
void createDepthBuffer();
void createSSAOBuffer();
};
+16 -2
View File
@@ -88,7 +88,9 @@ void PostProcessing::configureEffect(
shader.uniform1i("u_position", 1);
shader.uniform1i("u_normal", 2);
}
shader.uniform1i("u_noise", 3);
shader.uniform1i("u_noise", 3); // used in SSAO pass
shader.uniform1i("u_ssao", 3);
shader.uniform1i("u_shadows", 4);
shader.uniform2i("u_screenSize", viewport);
shader.uniform1f("u_timer", timer);
@@ -126,13 +128,25 @@ void PostProcessing::render(
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glActiveTexture(GL_TEXTURE0);
auto& ssaoEffect = assets.require<PostEffect>("ssao");
auto& shader = ssaoEffect.use();
configureEffect(context, ssaoEffect, shader, timer, camera, shadowMap);
gbuffer->bindSSAO();
quadMesh->draw();
gbuffer->unbind();
glActiveTexture(GL_TEXTURE3);
gbuffer->bindSSAOBuffer();
} else {
glActiveTexture(GL_TEXTURE0);
fbo->getTexture()->bind();
}
if (totalPasses == 0) {
auto& effect = assets.require<PostEffect>("default");
auto& effect = assets.require<PostEffect>(
gbuffer ? "deferred_lighting" : "default"
);
auto& shader = effect.use();
configureEffect(context, effect, shader, timer, camera, shadowMap);
quadMesh->draw();
@@ -17,7 +17,10 @@ static int l_set_effect(lua::State* L) {
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
auto name = lua::require_string(L, 2);
auto& assets = *engine->getAssets();
auto effect = std::make_shared<PostEffect>(assets.require<PostEffect>(name));
auto effect = assets.getShared<PostEffect>(name);
if (effect == nullptr) {
throw std::runtime_error(std::string("post-effect '") + name + "' not found");
}
post_processing->setEffect(index, std::move(effect));
return 0;
}