Fixed volumetric Post FX

This commit is contained in:
Antoine Pilote
2023-03-04 17:44:59 -05:00
parent 8195d6879b
commit abd5ac2dc8
9 changed files with 95 additions and 56 deletions

View File

@@ -31,13 +31,13 @@ uniform vec3 u_CamPosition;
uniform int u_StepCount;
uniform float u_FogAmount;
const int MAX_LIGHT = 25;
const int MAX_LIGHT = 20;
uniform int u_LightCount;
struct Light {
mat4 transform;
vec3 color;
vec3 direction;
int shadowmap;
sampler2D shadowmap;
};
uniform Light u_Lights[MAX_LIGHT];
@@ -62,7 +62,8 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
vec3 rayVector = FragPos - startPosition; // Ray Direction
float rayLength = length(rayVector); // Length of the raymarched
if(rayLength > 100)
return vec3(0);
float stepLength = rayLength / u_StepCount; // Step length
vec3 rayDirection = rayVector / rayLength;
vec3 step = rayDirection * stepLength; // Normalized to step length direction
@@ -76,15 +77,21 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
vec4 fragPosLightSpace = light.transform * vec4(currentPosition, 1.0f);
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
float currentDepth = projCoords.z;
float closestDepth = texture(lightShadowmap, projCoords.xy).r;
if (closestDepth > currentDepth)
accumFog += (ComputeScattering(dot(rayDirection, normalize(light.direction))).xxx * light.color);
float closestDepth = texture(light.shadowmap, projCoords.xy).r;
if (closestDepth > currentDepth && closestDepth < 999)
{
//accumFog = vec3(light.color);
accumFog += (ComputeScattering(dot(rayDirection, light.direction)).xxx * light.color * 10.0);
//accumFog = vec3(projCoords.x, projCoords.y, 1.0);
}
currentPosition += step; //* ditherPattern[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4];
//accumFog = vec3(projCoords);
}
accumFog /= u_StepCount;
@@ -116,6 +123,11 @@ void main()
{
fog += ComputeVolumetric(globalFragmentPosition, u_Lights[i]);
}
FragColor = vec4(mix(fog, ComputeVolumetric(globalFragmentPosition, u_Lights[0]), 0.9f), 1.0);
FragColor = vec4(fog, 1.0f);
//FragColor = vec4(mix(fog, ComputeVolumetric(globalFragmentPosition, u_Lights[0]), 0.9f), 0.01);
//FragColor = vec4(globalFragmentPosition * 10.0, 1.0f);
//FragColor = vec4(globalFragmentPosition.xyz * 100.0, 1.0f);
//FragColor = vec4(worldSpacePosition.x, worldSpacePosition.y, worldSpacePosition.z, 1);
//FragColor = vec4(ComputeVolumetric(globalFragmentPosition, u_Lights[0]), 1.0);
}

View File

@@ -570,7 +570,9 @@ namespace Nuake {
ImGui::Text("Volumetric Scattering");
ImGui::TableNextColumn();
ImGui::DragFloat("##Volumetric Scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f);
float fogAmount = env->mVolumetric->GetFogAmount();
ImGui::DragFloat("##Volumetric Scattering", &fogAmount, .001f, 0.f, 1.0f);
env->mVolumetric->SetFogAmount(fogAmount);
ImGui::TableNextColumn();
// Reset button
@@ -586,7 +588,10 @@ namespace Nuake {
ImGui::Text("Step count");
ImGui::TableNextColumn();
ImGui::DragFloat("##Volumetric Step Count", &env->VolumetricStepCount, 1.f, 0.0f);
int stepCount = env->mVolumetric->GetStepCount();
ImGui::DragInt("##Volumetric Step Count", &stepCount, 1.f, 0.0f);
env->mVolumetric->SetStepCount(stepCount);
ImGui::TableNextColumn();
// Reset button

View File

@@ -31,22 +31,22 @@ namespace Nuake {
mFinalFramebuffer->QueueResize(mSize);
}
void Volumetric::Draw(Matrix4 projection, Matrix4 view, std::vector<LightComponent>& lights)
void Volumetric::Draw(Matrix4 projection, Matrix4 view, const Vector3& camPos, std::vector<LightComponent>& lights)
{
mFinalFramebuffer->Bind();
mFinalFramebuffer->Clear();
RenderCommand::Disable(RendererEnum::FACE_CULL);
Vector3 cameraPosition = view[3];
Vector3 cameraPosition = Vector3(view[3]);
Shader* volumetricShader = ShaderManager::GetShader("resources/Shaders/volumetric.shader");
volumetricShader->Bind();
volumetricShader->SetUniformMat4f("u_Projection", projection);
volumetricShader->SetUniformMat4f("u_View", view);
volumetricShader->SetUniformTex("u_Depth", mDepth, 1);
volumetricShader->SetUniformVec3("u_CamPosition", cameraPosition);
volumetricShader->SetUniformVec3("u_CamPosition", camPos);
volumetricShader->SetUniform1i("u_StepCount", mStepCount);
volumetricShader->SetUniform1f("u_FogAmount", mFogAmount);
volumetricShader->SetUniform1i("u_LightCount", 1);
volumetricShader->SetUniform1i("u_LightCount", static_cast<int>(lights.size()));
for (uint16_t i = 0; i < lights.size(); i++)
{
@@ -57,7 +57,7 @@ namespace Nuake {
volumetricShader->SetUniformVec3(u_light + "color", light.Color);
volumetricShader->SetUniformVec3(u_light + "direction", light.GetDirection());
volumetricShader->SetUniformTex("lightShadowmap", light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT).get(), 2 + i);
volumetricShader->SetUniformTex(u_light + "shadowmap", light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT).get(), 5 + i);
}
@@ -66,7 +66,12 @@ namespace Nuake {
if (ImGui::Begin("Volumetric debug"))
{
ImGui::Image((void*)mFinalFramebuffer->GetTexture()->GetID(), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
ImGui::Image((void*)(uintptr_t)(mFinalFramebuffer->GetTexture()->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::End();
if (ImGui::Begin("Volumetric debug depth"))
{
ImGui::Image((void*)(uintptr_t)(mDepth->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::End();
}

View File

@@ -23,7 +23,7 @@ namespace Nuake {
void SetDepth(Texture* depth);
void Init();
void Resize(Vector2 size);
void Draw(Matrix4 projection, Matrix4 view, std::vector<LightComponent>& lights);
void Draw(Matrix4 projection, Matrix4 view, const Vector3& camPos, std::vector<LightComponent>& lights);
inline int GetStepCount() const { return mStepCount;}
@@ -35,9 +35,9 @@ namespace Nuake {
if (amount > 0) mFogAmount = amount;
}
Texture* GetFinalOutput()
Ref<Texture> GetFinalOutput()
{
return mFinalFramebuffer->GetTexture().get();
return mFinalFramebuffer->GetTexture();
}
};
}

View File

@@ -18,11 +18,6 @@ namespace Nuake {
Ref<Texture> shadedTexture = CreateRef<Texture>(Vector2(1920, 1080), GL_RGB, GL_RGB16F, GL_FLOAT);
mShadingBuffer->SetTexture(shadedTexture);
mBloom = CreateScope<Bloom>(4);
mBloom->SetSource(shadedTexture);
mVolumetric = CreateScope<Volumetric>();
mSSR = CreateScope<SSR>();
mToneMapBuffer = CreateScope<FrameBuffer>(false, Vector2(1920, 1080));
@@ -34,10 +29,11 @@ namespace Nuake {
}
void SceneRenderer::BeginRenderScene(const Matrix4& projection, const Matrix4& view)
void SceneRenderer::BeginRenderScene(const Matrix4& projection, const Matrix4& view, const Vector3& camPos)
{
mProjection = projection;
mView = view;
mCamPos = camPos;
}
void SceneRenderer::RenderScene(Scene& scene, FrameBuffer& framebuffer)
@@ -46,16 +42,18 @@ namespace Nuake {
mGBuffer->QueueResize(framebuffer.GetSize());
GBufferPass(scene);
mShadingBuffer->QueueResize(framebuffer.GetSize());
ShadingPass(scene);
auto& sceneEnv = scene.GetEnvironment();
Texture* finalOutput = mShadingBuffer->GetTexture().get();
if (scene.GetEnvironment()->BloomEnabled)
{
scene.GetEnvironment()->mBloom->SetSource(mShadingBuffer->GetTexture());
scene.GetEnvironment()->mBloom->Resize(framebuffer.GetSize());
scene.GetEnvironment()->mBloom->Draw();
sceneEnv->mBloom->SetSource(mShadingBuffer->GetTexture());
sceneEnv->mBloom->Resize(framebuffer.GetSize());
sceneEnv->mBloom->Draw();
finalOutput = scene.GetEnvironment()->mBloom->GetOutput().get();
}
@@ -65,18 +63,33 @@ namespace Nuake {
for (auto l : view)
{
auto& lc = view.get<LightComponent>(l);
if (lc.Type == Directional && lc.IsVolumetric)
if (lc.Type == Directional && lc.IsVolumetric && lc.CastShadows)
lightList.push_back(lc);
}
if (scene.GetEnvironment()->VolumetricEnabled)
{
mVolumetric->Resize(framebuffer.GetSize());
mVolumetric->SetDepth(mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get());
mVolumetric->Draw(mProjection , mView, lightList);
sceneEnv->mVolumetric->Resize(framebuffer.GetSize());
sceneEnv->mVolumetric->SetDepth(mGBuffer->GetTexture(GL_DEPTH_ATTACHMENT).get());
sceneEnv->mVolumetric->Draw(mProjection , mView, mCamPos, lightList);
finalOutput = mVolumetric->GetFinalOutput();
//finalOutput = mVolumetric->GetFinalOutput().get();
// combine
framebuffer.Bind();
{
RenderCommand::Clear();
Shader* shader = ShaderManager::GetShader("resources/Shaders/combine.shader");
shader->Bind();
shader->SetUniformTex("u_Source", finalOutput, 0);
shader->SetUniformTex("u_Source2", sceneEnv->mVolumetric->GetFinalOutput().get(), 1);
Renderer::DrawQuad();
}
framebuffer.Unbind();
}
finalOutput = framebuffer.GetTexture().get();
// Copy final output to target framebuffer
mToneMapBuffer->QueueResize(framebuffer.GetSize());
@@ -93,21 +106,10 @@ namespace Nuake {
}
mToneMapBuffer->Unbind();
RenderCommand::Disable(RendererEnum::FACE_CULL);
Ref<Environment> environment = scene.GetEnvironment();
if (environment->CurrentSkyType == SkyType::ProceduralSky)
{
environment->ProceduralSkybox->Draw(mProjection, mView, environment->Exposure);
}
else if (environment->CurrentSkyType == SkyType::ClearColor)
{
RenderCommand::SetClearColor(environment->AmbientColor);
RenderCommand::Clear();
}
RenderCommand::Enable(RendererEnum::FACE_CULL);
//mSSR->Resize(framebuffer.GetSize());
//mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera());
mSSR->Resize(framebuffer.GetSize());
mSSR->Draw(mGBuffer.get(), framebuffer.GetTexture(), mView, mProjection, scene.GetCurrentCamera());
framebuffer.Bind();
{
@@ -116,7 +118,7 @@ namespace Nuake {
shader->Bind();
shader->SetUniformTex("u_Source", mToneMapBuffer->GetTexture().get(), 0);
shader->SetUniformTex("u_Source2", mToneMapBuffer->GetTexture().get(), 1);
shader->SetUniformTex("u_Source2", mSSR->OutputFramebuffer->GetTexture().get(), 1);
Renderer::DrawQuad();
}
framebuffer.Unbind();
@@ -232,6 +234,18 @@ namespace Nuake {
mShadingBuffer->Clear();
{
RenderCommand::Disable(RendererEnum::DEPTH_TEST);
RenderCommand::Disable(RendererEnum::FACE_CULL);
Ref<Environment> environment = scene.GetEnvironment();
if (environment->CurrentSkyType == SkyType::ProceduralSky)
{
environment->ProceduralSkybox->Draw(mProjection, mView);
}
else if (environment->CurrentSkyType == SkyType::ClearColor)
{
RenderCommand::SetClearColor(environment->AmbientColor);
RenderCommand::Clear();
}
RenderCommand::Enable(RendererEnum::FACE_CULL);
Shader* shadingShader = ShaderManager::GetShader("resources/Shaders/deferred.shader");
shadingShader->Bind();

View File

@@ -14,19 +14,18 @@ namespace Nuake {
void Init();
void Cleanup();
void BeginRenderScene(const Matrix4& projection, const Matrix4& view);
void BeginRenderScene(const Matrix4& projection, const Matrix4& view, const Vector3& camPos);
void RenderScene(Scene& scene, FrameBuffer& framebuffer);
Scope<SSR> mSSR;
private:
Matrix4 mProjection, mView;
Vector3 mCamPos;
Scope<FrameBuffer> mGBuffer;
Scope<FrameBuffer> mShadingBuffer;
Scope<FrameBuffer> mToneMapBuffer;
Scope<Bloom> mBloom;
Scope<Volumetric> mVolumetric;
void ShadowPass(Scene& scene);
void GBufferPass(Scene& scene);

View File

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

View File

@@ -4,6 +4,7 @@
#include "src/Scene/Environment/ProceduralSky.h"
#include "src/Resource/Serializable.h"
#include "src/Rendering/PostFX/Bloom.h"
#include "src/Rendering/PostFX/Volumetric.h"
#include <vector>
@@ -34,6 +35,8 @@ namespace Nuake
bool BloomEnabled = false;
Scope<Bloom> mBloom;
Scope<Volumetric> mVolumetric;
Vector3 ClearColor;
glm::vec4 m_AmbientColor;

View File

@@ -144,13 +144,13 @@ namespace Nuake {
if (!cam)
return;
mSceneRenderer->BeginRenderScene(cam->GetPerspective(), cam->GetTransform());
mSceneRenderer->BeginRenderScene(cam->GetPerspective(), cam->GetTransform(), cam->Translation);
mSceneRenderer->RenderScene(*this, framebuffer);
}
void Scene::Draw(FrameBuffer& framebuffer, const Matrix4& projection, const Matrix4& view)
{
mSceneRenderer->BeginRenderScene(m_EditorCamera->GetPerspective(), m_EditorCamera->GetTransform());
mSceneRenderer->BeginRenderScene(m_EditorCamera->GetPerspective(), m_EditorCamera->GetTransform(), m_EditorCamera->Translation);
mSceneRenderer->RenderScene(*this, framebuffer);
}