feat: deferred shading (day 2)
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
static debug::Logger logger("gl-gbuffer");
|
||||
|
||||
void GBuffer::createColorBuffer() {
|
||||
@@ -162,20 +164,30 @@ void GBuffer::unbind() {
|
||||
}
|
||||
|
||||
void GBuffer::bindBuffers() const {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_NORMALS);
|
||||
glBindTexture(GL_TEXTURE_2D, normalsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_POSITIONS);
|
||||
glBindTexture(GL_TEXTURE_2D, positionsBuffer);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_COLOR);
|
||||
glBindTexture(GL_TEXTURE_2D, colorBuffer);
|
||||
|
||||
if (TARGET_COLOR != 0)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void GBuffer::bindSSAOBuffer() const {
|
||||
glBindTexture(GL_TEXTURE_2D, ssaoBuffer);
|
||||
}
|
||||
|
||||
void GBuffer::bindDepthBuffer() {
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
void GBuffer::resize(uint width, uint height) {
|
||||
if (this->width == width && this->height == height) {
|
||||
return;
|
||||
|
||||
@@ -16,6 +16,8 @@ public:
|
||||
void bindBuffers() const;
|
||||
void bindSSAOBuffer() const;
|
||||
|
||||
void bindDepthBuffer();
|
||||
|
||||
void resize(uint width, uint height);
|
||||
|
||||
uint getWidth() const;
|
||||
|
||||
@@ -100,6 +100,10 @@ Shader& PostEffect::use() {
|
||||
return *shader;
|
||||
}
|
||||
|
||||
Shader& PostEffect::getShader() {
|
||||
return *shader;
|
||||
}
|
||||
|
||||
float PostEffect::getIntensity() const {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
|
||||
Shader& use();
|
||||
|
||||
Shader& getShader();
|
||||
|
||||
float getIntensity() const;
|
||||
void setIntensity(float value);
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <stdexcept>
|
||||
#include <random>
|
||||
|
||||
using namespace advanced_pipeline;
|
||||
|
||||
PostProcessing::PostProcessing(size_t effectSlotsCount)
|
||||
: effectSlots(effectSlotsCount) {
|
||||
// Fullscreen quad mesh bulding
|
||||
@@ -74,28 +76,46 @@ void PostProcessing::refreshFbos(uint width, uint height) {
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::bindDepthBuffer() {
|
||||
gbuffer->bindDepthBuffer();
|
||||
}
|
||||
|
||||
void PostProcessing::configureEffect(
|
||||
const DrawContext& context,
|
||||
PostEffect& effect,
|
||||
Shader& shader,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
) {
|
||||
const auto& viewport = context.getViewport();
|
||||
shader.uniform1i("u_screen", 0);
|
||||
shader.uniform1i("u_screen", TARGET_COLOR);
|
||||
shader.uniform1i("u_skybox", TARGET_SKYBOX);
|
||||
if (gbuffer) {
|
||||
shader.uniform1i("u_position", 1);
|
||||
shader.uniform1i("u_normal", 2);
|
||||
shader.uniform1i("u_position", TARGET_POSITIONS);
|
||||
shader.uniform1i("u_normal", TARGET_NORMALS);
|
||||
}
|
||||
shader.uniform1i("u_noise", 3); // used in SSAO pass
|
||||
shader.uniform1i("u_ssao", 3);
|
||||
shader.uniform1i("u_noise", TARGET_SSAO); // used in SSAO pass
|
||||
shader.uniform1i("u_ssao", TARGET_SSAO);
|
||||
|
||||
shader.uniform1i("u_shadows", 4);
|
||||
shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0);
|
||||
shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1);
|
||||
shader.uniformMatrix("u_shadowsMatrix[0]", shadowMatrix);
|
||||
shader.uniformMatrix("u_shadowsMatrix[1]", shadowMatrix2);
|
||||
shader.uniform1f("u_shadowsOpacity", 1.0f);
|
||||
shader.uniform1f("u_shadowsSoftness", 1.0f);
|
||||
shader.uniform1i("u_shadowsRes", shadowMapResolution);
|
||||
shader.uniform2i("u_screenSize", viewport);
|
||||
shader.uniform3f("u_cameraPos", camera.position);
|
||||
shader.uniform1f("u_timer", timer);
|
||||
shader.uniform1i("u_enableShadows", shadowMap != 0);
|
||||
shader.uniformMatrix("u_projection", camera.getProjection());
|
||||
shader.uniformMatrix("u_view", camera.getView());
|
||||
shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView()));
|
||||
}
|
||||
|
||||
void PostProcessing::render(
|
||||
@@ -103,7 +123,11 @@ void PostProcessing::render(
|
||||
const Assets& assets,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
) {
|
||||
if (fbo == nullptr && gbuffer == nullptr) {
|
||||
throw std::runtime_error("'use(...)' was never called");
|
||||
@@ -118,25 +142,40 @@ void PostProcessing::render(
|
||||
const auto& vp = context.getViewport();
|
||||
refreshFbos(vp.x, vp.y);
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1);
|
||||
glBindTexture(GL_TEXTURE_2D, shadowMap2);
|
||||
|
||||
// Generating ssao
|
||||
if (gbuffer) {
|
||||
gbuffer->bindBuffers();
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
|
||||
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);
|
||||
configureEffect(
|
||||
context,
|
||||
ssaoEffect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
gbuffer->bindSSAO();
|
||||
quadMesh->draw();
|
||||
gbuffer->unbind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glActiveTexture(GL_TEXTURE0 + TARGET_SSAO);
|
||||
gbuffer->bindSSAOBuffer();
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -148,7 +187,18 @@ void PostProcessing::render(
|
||||
gbuffer ? "deferred_lighting" : "default"
|
||||
);
|
||||
auto& shader = effect.use();
|
||||
configureEffect(context, effect, shader, timer, camera, shadowMap);
|
||||
configureEffect(
|
||||
context,
|
||||
effect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
quadMesh->draw();
|
||||
return;
|
||||
}
|
||||
@@ -162,7 +212,18 @@ void PostProcessing::render(
|
||||
continue;
|
||||
}
|
||||
auto& shader = effect->use();
|
||||
configureEffect(context, *effect, shader, timer, camera, shadowMap);
|
||||
configureEffect(
|
||||
context,
|
||||
*effect,
|
||||
shader,
|
||||
timer,
|
||||
camera,
|
||||
shadowMap,
|
||||
shadowMap2,
|
||||
shadowMatrix,
|
||||
shadowMatrix2,
|
||||
shadowMapResolution
|
||||
);
|
||||
|
||||
if (currentPass > 1) {
|
||||
fbo->getTexture()->bind();
|
||||
|
||||
@@ -44,7 +44,11 @@ public:
|
||||
const Assets& assets,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
);
|
||||
|
||||
void setEffect(size_t slot, std::shared_ptr<PostEffect> effect);
|
||||
@@ -55,6 +59,7 @@ public:
|
||||
std::unique_ptr<ImageData> toImage();
|
||||
|
||||
Framebuffer* getFramebuffer() const;
|
||||
void bindDepthBuffer();
|
||||
private:
|
||||
void configureEffect(
|
||||
const DrawContext& context,
|
||||
@@ -62,7 +67,11 @@ private:
|
||||
Shader& shader,
|
||||
float timer,
|
||||
const Camera& camera,
|
||||
uint shadowMap
|
||||
uint shadowMap,
|
||||
uint shadowMap2,
|
||||
const glm::mat4& shadowMatrix,
|
||||
const glm::mat4& shadowMatrix2,
|
||||
uint shadowMapResolution
|
||||
);
|
||||
|
||||
void refreshFbos(uint width, uint height);
|
||||
|
||||
@@ -51,6 +51,12 @@ void Shader::uniformMatrix(const std::string& name, const glm::mat4& matrix) {
|
||||
);
|
||||
}
|
||||
|
||||
void Shader::uniformMatrix(const std::string& name, const glm::mat3& matrix) {
|
||||
glUniformMatrix3fv(
|
||||
getUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix)
|
||||
);
|
||||
}
|
||||
|
||||
void Shader::uniform1i(const std::string& name, int x){
|
||||
glUniform1i(getUniformLocation(name), x);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
|
||||
void use();
|
||||
void uniformMatrix(const std::string&, const glm::mat4& matrix);
|
||||
void uniformMatrix(const std::string&, const glm::mat3& matrix);
|
||||
void uniform1i(const std::string& name, int x);
|
||||
void uniform1f(const std::string& name, float x);
|
||||
void uniform2f(const std::string& name, float x, float y);
|
||||
|
||||
@@ -50,6 +50,16 @@ enum class CursorShape {
|
||||
LAST=NOT_ALLOWED
|
||||
};
|
||||
|
||||
namespace advanced_pipeline {
|
||||
inline constexpr int TARGET_COLOR = 0;
|
||||
inline constexpr int TARGET_SKYBOX = 1;
|
||||
inline constexpr int TARGET_POSITIONS = 2;
|
||||
inline constexpr int TARGET_NORMALS = 3;
|
||||
inline constexpr int TARGET_SSAO = 4;
|
||||
inline constexpr int TARGET_SHADOWS0 = 5;
|
||||
inline constexpr int TARGET_SHADOWS1 = 6;
|
||||
}
|
||||
|
||||
VC_ENUM_METADATA(CursorShape)
|
||||
{"arrow", CursorShape::ARROW},
|
||||
{"text", CursorShape::TEXT},
|
||||
|
||||
Reference in New Issue
Block a user