From abd5ac2dc86ef11950dc096b86b43a5eae5f2109 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sat, 4 Mar 2023 17:44:59 -0500 Subject: [PATCH] Fixed volumetric Post FX --- Editor/resources/Shaders/volumetric.shader | 30 ++++++--- Editor/src/Windows/EditorInterface.cpp | 9 ++- Nuake/src/Rendering/PostFX/Volumetric.cpp | 17 +++-- Nuake/src/Rendering/PostFX/Volumetric.h | 6 +- Nuake/src/Rendering/SceneRenderer.cpp | 74 +++++++++++++--------- Nuake/src/Rendering/SceneRenderer.h | 7 +- Nuake/src/Scene/Lighting/Environment.cpp | 1 + Nuake/src/Scene/Lighting/Environment.h | 3 + Nuake/src/Scene/Scene.cpp | 4 +- 9 files changed, 95 insertions(+), 56 deletions(-) diff --git a/Editor/resources/Shaders/volumetric.shader b/Editor/resources/Shaders/volumetric.shader index 53790de8..9345903a 100644 --- a/Editor/resources/Shaders/volumetric.shader +++ b/Editor/resources/Shaders/volumetric.shader @@ -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); } \ No newline at end of file diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index 0299de66..2b6e2147 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -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 diff --git a/Nuake/src/Rendering/PostFX/Volumetric.cpp b/Nuake/src/Rendering/PostFX/Volumetric.cpp index 939741e7..620b7681 100644 --- a/Nuake/src/Rendering/PostFX/Volumetric.cpp +++ b/Nuake/src/Rendering/PostFX/Volumetric.cpp @@ -31,22 +31,22 @@ namespace Nuake { mFinalFramebuffer->QueueResize(mSize); } - void Volumetric::Draw(Matrix4 projection, Matrix4 view, std::vector& lights) + void Volumetric::Draw(Matrix4 projection, Matrix4 view, const Vector3& camPos, std::vector& 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(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(); } diff --git a/Nuake/src/Rendering/PostFX/Volumetric.h b/Nuake/src/Rendering/PostFX/Volumetric.h index d607f2bb..fda79322 100644 --- a/Nuake/src/Rendering/PostFX/Volumetric.h +++ b/Nuake/src/Rendering/PostFX/Volumetric.h @@ -23,7 +23,7 @@ namespace Nuake { void SetDepth(Texture* depth); void Init(); void Resize(Vector2 size); - void Draw(Matrix4 projection, Matrix4 view, std::vector& lights); + void Draw(Matrix4 projection, Matrix4 view, const Vector3& camPos, std::vector& lights); inline int GetStepCount() const { return mStepCount;} @@ -35,9 +35,9 @@ namespace Nuake { if (amount > 0) mFogAmount = amount; } - Texture* GetFinalOutput() + Ref GetFinalOutput() { - return mFinalFramebuffer->GetTexture().get(); + return mFinalFramebuffer->GetTexture(); } }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index c1707bb1..d5e510a5 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -18,11 +18,6 @@ namespace Nuake { Ref shadedTexture = CreateRef(Vector2(1920, 1080), GL_RGB, GL_RGB16F, GL_FLOAT); mShadingBuffer->SetTexture(shadedTexture); - mBloom = CreateScope(4); - mBloom->SetSource(shadedTexture); - - mVolumetric = CreateScope(); - mSSR = CreateScope(); mToneMapBuffer = CreateScope(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(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 = 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 = 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(); diff --git a/Nuake/src/Rendering/SceneRenderer.h b/Nuake/src/Rendering/SceneRenderer.h index 6e6600df..36bf4216 100644 --- a/Nuake/src/Rendering/SceneRenderer.h +++ b/Nuake/src/Rendering/SceneRenderer.h @@ -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 mSSR; private: Matrix4 mProjection, mView; + Vector3 mCamPos; Scope mGBuffer; Scope mShadingBuffer; Scope mToneMapBuffer; - Scope mBloom; - Scope mVolumetric; + void ShadowPass(Scene& scene); void GBufferPass(Scene& scene); diff --git a/Nuake/src/Scene/Lighting/Environment.cpp b/Nuake/src/Scene/Lighting/Environment.cpp index c92bbc5a..c89b6e2c 100644 --- a/Nuake/src/Scene/Lighting/Environment.cpp +++ b/Nuake/src/Scene/Lighting/Environment.cpp @@ -9,6 +9,7 @@ namespace Nuake { m_AmbientColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); ProceduralSkybox = CreateRef(); mBloom = CreateScope(4); + mVolumetric = CreateScope(); } glm::vec4 Environment::GetAmbientColor() diff --git a/Nuake/src/Scene/Lighting/Environment.h b/Nuake/src/Scene/Lighting/Environment.h index bb939313..3da7d67a 100644 --- a/Nuake/src/Scene/Lighting/Environment.h +++ b/Nuake/src/Scene/Lighting/Environment.h @@ -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 @@ -34,6 +35,8 @@ namespace Nuake bool BloomEnabled = false; Scope mBloom; + Scope mVolumetric; + Vector3 ClearColor; glm::vec4 m_AmbientColor; diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 23dcf8c4..211c3850 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -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); }