Added SSAO

This commit is contained in:
Antoine Pilote
2023-03-05 13:00:12 -05:00
parent e23f6ac14e
commit 47985f507a
12 changed files with 379 additions and 11 deletions

View File

@@ -1,5 +1,143 @@
#include "SSAO.h"
#include "src/Core/Core.h"
#include "src/Rendering/Textures/Texture.h"
#include <src/Rendering/Shaders/Shader.h>
#include "src/Rendering/Shaders/ShaderManager.h"
#include "src/Rendering/Renderer.h"
namespace Nuake {
#include <GL\glew.h>
#include <random>
#include <src/Vendors/imgui/imgui.h>
namespace Nuake
{
SSAO::SSAO()
{
GenerateKernel();
GenerateNoise();
_size = { 1280, 720 };
_ssaoFramebuffer = CreateRef<FrameBuffer>(false, Vector2(_size));
auto& renderTarget = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
_ssaoFramebuffer->SetTexture(renderTarget, GL_COLOR_ATTACHMENT0);
_ssaoBlurFramebuffer = CreateRef<FrameBuffer>(false, Vector2(_size));
auto& renderTargetBlur = CreateRef<Texture>(_size, GL_RGBA, GL_RGBA16F, GL_FLOAT);
_ssaoBlurFramebuffer->SetTexture(renderTargetBlur);
}
void SSAO::Resize(const Vector2& size)
{
if (_size == size)
return;
_size = size;
_ssaoFramebuffer->QueueResize(size);
_ssaoBlurFramebuffer->QueueResize(size);
}
void SSAO::GenerateKernel()
{
std::uniform_real_distribution<float> randomFloats(0.0, 1.0); // random floats between [0.0, 1.0]
std::default_random_engine generator;
std::vector<glm::vec3> ssaoKernel;
for (unsigned int i = 0; i < 64; ++i)
{
glm::vec3 sample(
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator)
);
sample = glm::normalize(sample);
sample *= randomFloats(generator);
float scale = (float)i / 64.0;
scale = lerp(0.1f, 1.0f, scale * scale);
sample *= scale;
_ssaoKernel.push_back(sample);
}
}
void SSAO::GenerateNoise()
{
std::uniform_real_distribution<float> randomFloats(0.0, 1.0);
std::default_random_engine generator;
for (unsigned int i = 0; i < 16; i++)
{
glm::vec3 noise(
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0,
0.0f);
_ssaoNoise.push_back(noise);
}
_ssaoNoiseTexture = CreateRef<Texture>(Vector2(4, 4), GL_RGB, GL_RGBA16F, GL_FLOAT, &_ssaoNoise[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
void SSAO::Draw(FrameBuffer* gBuffer, const Matrix4& projection, const Matrix4& view)
{
_ssaoFramebuffer->Bind();
{
_ssaoFramebuffer->Clear();
const auto& depthTexture = gBuffer->GetTexture(GL_DEPTH_ATTACHMENT);
const auto& normalTexture = gBuffer->GetTexture(GL_COLOR_ATTACHMENT1);
Shader* shader = ShaderManager::GetShader("resources/Shaders/ssao.shader");
shader->Bind();
shader->SetUniformMat4f("u_Projection", projection);
shader->SetUniformMat4f("u_View", view);
shader->SetUniformTex("u_Depth", depthTexture.get(), 2);
shader->SetUniformTex("u_Normal", normalTexture.get(), 3);
shader->SetUniformTex("u_Noise", _ssaoNoiseTexture.get(), 6);
shader->SetUniform1i("u_KernelSize", 64);
shader->SetUniform1f("u_Radius", Radius);
shader->SetUniform1f("u_Bias", Bias);
shader->SetUniformVec2("u_NoiseScale", Vector2(_size.x / 4, _size.y / 4) );
int i = 0;
for (const auto& k : _ssaoKernel)
{
const std::string& uniformName = "u_Samples[" + std::to_string(i) + "]";
shader->SetUniform3f(uniformName, k.x, k.y, k.z);
i++;
}
//shader->SetUniform1fv("u_Samples", 64 * 3, (float*)&(_ssaoKernel.begin()));
Renderer::DrawQuad(Matrix4(1.0));
}
_ssaoFramebuffer->Unbind();
_ssaoBlurFramebuffer->Bind();
{
Shader* shader = ShaderManager::GetShader("resources/Shaders/blur.shader");
shader->Bind();
shader->SetUniformTex("u_Input", _ssaoFramebuffer->GetTexture().get(), 2);
Renderer::DrawQuad(Matrix4(1.0));
}
_ssaoBlurFramebuffer->Unbind();
/*
if (ImGui::Begin("SSAO debug"))
{
ImGui::Image((void*)(uintptr_t)(_ssaoFramebuffer->GetTexture(GL_COLOR_ATTACHMENT0)->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::End();
*/
}
Ref<FrameBuffer> SSAO::GetOuput() const
{
return _ssaoBlurFramebuffer;
}
}

View File

@@ -1,8 +1,38 @@
#pragma once
#include "src/Core/Maths.h"
#include "src/Core/Core.h"
#include "src/Rendering/Buffers/Framebuffer.h"
#include <vector>
namespace Nuake {
class SSAO {
namespace Nuake
{
class SSAO
{
private:
std::vector<glm::f32vec3> _ssaoKernel;
std::vector<Vector3> _ssaoNoise;
Ref<FrameBuffer> _ssaoFramebuffer;
Ref<FrameBuffer> _ssaoBlurFramebuffer;
Ref<Texture> _ssaoNoiseTexture;
Vector2 _size;
void GenerateKernel();
void GenerateNoise();
float lerp(float a, float b, float f)
{
return a + f * (b - a);
}
public:
float Radius = 0.07f;
float Bias = 0.003f;
void Resize(const Vector2& size);
SSAO();
void Draw(FrameBuffer* gBuffer, const Matrix4& projection, const Matrix4& view);
Ref<FrameBuffer> GetOuput() const;
};
}

View File

@@ -64,6 +64,7 @@ namespace Nuake {
Renderer::DrawQuad();
mFinalFramebuffer->Unbind();
/*
if (ImGui::Begin("Volumetric debug"))
{
ImGui::Image((void*)(uintptr_t)(mFinalFramebuffer->GetTexture()->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
@@ -73,6 +74,7 @@ namespace Nuake {
{
ImGui::Image((void*)(uintptr_t)(mDepth->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
}
*/
ImGui::End();
}
}

View File

@@ -90,7 +90,10 @@ namespace Nuake {
}
finalOutput = framebuffer.GetTexture().get();
// SSAO
sceneEnv->mSSAO->Resize(framebuffer.GetSize());
sceneEnv->mSSAO->Draw(mGBuffer.get(), mProjection, mView);
// Copy final output to target framebuffer
mToneMapBuffer->QueueResize(framebuffer.GetSize());
mToneMapBuffer->Bind();
@@ -253,6 +256,8 @@ namespace Nuake {
shadingShader->SetUniformMat4f("u_View", mView);
shadingShader->SetUniformVec3("u_EyePosition", scene.GetCurrentCamera()->Translation);
shadingShader->SetUniformTex("m_SSAO", scene.GetEnvironment()->mSSAO->GetOuput()->GetTexture().get(), 9);
Ref<Environment> env = scene.GetEnvironment();
auto view = scene.m_Registry.view<TransformComponent, LightComponent, ParentComponent>();

View File

@@ -36,7 +36,7 @@ namespace Nuake
std::cout << "Error: failed to load texture: " << path << std::endl;
}
Texture::Texture(glm::vec2 size, GLenum format, GLenum format2, GLenum format3)
Texture::Texture(glm::vec2 size, GLenum format, GLenum format2, GLenum format3, void* data)
{
m_RendererId = 0;
m_Format = format;
@@ -54,7 +54,7 @@ namespace Nuake
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
glTexImage2D(GL_TEXTURE_2D, 0, format2, size.x, size.y, 0, format, format3, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, format2, size.x, size.y, 0, format, format3, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

View File

@@ -27,7 +27,7 @@ namespace Nuake
public:
Texture(const std::string& path);
Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
Texture(glm::vec2 size, GLenum format, GLenum format2 = 0, GLenum format3 = 0);
Texture(glm::vec2 size, GLenum format, GLenum format2 = 0, GLenum format3 = 0, void* data = NULL);
Texture(Vector2 size, unsigned char* data, int len);
~Texture();

View File

@@ -10,6 +10,7 @@ namespace Nuake {
ProceduralSkybox = CreateRef<ProceduralSky>();
mBloom = CreateScope<Bloom>(4);
mVolumetric = CreateScope<Volumetric>();
mSSAO = CreateScope<SSAO>();
}
glm::vec4 Environment::GetAmbientColor()

View File

@@ -3,8 +3,10 @@
#include "src/Core/Core.h"
#include "src/Scene/Environment/ProceduralSky.h"
#include "src/Resource/Serializable.h"
#include "src/Rendering/PostFX/Bloom.h"
#include "src/Rendering/PostFX/Volumetric.h"
#include "src/Rendering/PostFX/SSAO.h"
#include <vector>
@@ -26,7 +28,7 @@ namespace Nuake
Color AmbientColor = Color(0, 0, 0, 1);
Ref<ProceduralSky> ProceduralSkybox;
bool VolumetricEnabled = false;
bool VolumetricEnabled = true;
float VolumetricFog = 0.90f;
float VolumetricStepCount = 50.f;
@@ -37,6 +39,9 @@ namespace Nuake
Scope<Bloom> mBloom;
Scope<Volumetric> mVolumetric;
bool SSAOEnabled = true;
Scope<SSAO> mSSAO;
Vector3 ClearColor;
glm::vec4 m_AmbientColor;