From 3cbb12d1b4691fbdb49bc7c68695be71009f2de8 Mon Sep 17 00:00:00 2001 From: Johann Muszynski Date: Mon, 24 Jun 2024 17:36:48 +0300 Subject: [PATCH] temporal accumulation with EMA --- src/pt/deferred_renderer.cpp | 4 +++- src/pt/deferred_renderer.hpp | 7 ++++--- src/pt/deferred_renderer_resolve_pass.wgsl | 13 ++++++++++++- src/pt/shader_source.hpp | 13 ++++++++++++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/pt/deferred_renderer.cpp b/src/pt/deferred_renderer.cpp index b1457a1..1f94670 100644 --- a/src/pt/deferred_renderer.cpp +++ b/src/pt/deferred_renderer.cpp @@ -361,6 +361,7 @@ void DeferredRenderer::render( renderDesc.targetTextureView, framebufferSize, renderDesc.exposure, + frameCount, gui); } wgpuCommandEncoderWriteTimestamp( @@ -1970,10 +1971,11 @@ void DeferredRenderer::ResolvePass::render( WGPUTextureView targetTextureView, const Extent2f& fbsize, const float exposure, + const std::uint32_t frameCount, Gui& gui) { { - const Uniforms uniforms{glm::vec2(fbsize.x, fbsize.y), exposure, 0.f}; + const Uniforms uniforms{glm::vec2(fbsize.x, fbsize.y), exposure, frameCount}; wgpuQueueWriteBuffer( gpuContext.queue, mUniformBuffer.ptr(), 0, &uniforms, sizeof(Uniforms)); } diff --git a/src/pt/deferred_renderer.hpp b/src/pt/deferred_renderer.hpp index ec10102..b656605 100644 --- a/src/pt/deferred_renderer.hpp +++ b/src/pt/deferred_renderer.hpp @@ -245,9 +245,9 @@ class DeferredRenderer struct Uniforms { - glm::vec2 framebufferSize; - float exposure; - float _padding; + glm::vec2 framebufferSize; + float exposure; + std::uint32_t frameCount; }; public: @@ -270,6 +270,7 @@ class DeferredRenderer WGPUTextureView targetTextureView, const Extent2f& framebufferSize, float exposure, + std::uint32_t frameCount, Gui& gui); }; diff --git a/src/pt/deferred_renderer_resolve_pass.wgsl b/src/pt/deferred_renderer_resolve_pass.wgsl index 527e27f..18e6c24 100644 --- a/src/pt/deferred_renderer_resolve_pass.wgsl +++ b/src/pt/deferred_renderer_resolve_pass.wgsl @@ -20,6 +20,7 @@ fn vsMain(in: VertexInput) -> VertexOutput { struct Uniforms { framebufferSize: vec2f, exposure: f32, + frameCount: u32, } // TODO: consider merging these into one bind group @@ -35,7 +36,17 @@ fn fsMain(in: VertexOutput) -> @location(0) vec4f { let textureIdx = vec2u(floor(uv * uniforms.framebufferSize)); let sampleBufferIdx = textureIdx.y * u32(uniforms.framebufferSize.x) + textureIdx.x; let sample: array = sampleBuffer[sampleBufferIdx]; - let color = vec3f(sample[0], sample[1], sample[2]); + let currentColor = vec3f(sample[0], sample[1], sample[2]); + var color = vec3f(0f); + if uniforms.frameCount == 0u { + accumulationBuffer[sampleBufferIdx] = sample; + color = currentColor; + } else { + let previousSample: array = accumulationBuffer[sampleBufferIdx]; + let previousColor = vec3f(previousSample[0], previousSample[1], previousSample[2]); + color = 0.1 * currentColor + 0.9 * previousColor; + accumulationBuffer[sampleBufferIdx] = array(color.r, color.g, color.b); + } let rgb = acesFilmic(uniforms.exposure * color); let srgb = pow(rgb, vec3(1f / 2.2f)); diff --git a/src/pt/shader_source.hpp b/src/pt/shader_source.hpp index 88680b3..144dc3f 100644 --- a/src/pt/shader_source.hpp +++ b/src/pt/shader_source.hpp @@ -1295,6 +1295,7 @@ fn vsMain(in: VertexInput) -> VertexOutput { struct Uniforms { framebufferSize: vec2f, exposure: f32, + frameCount: u32, } // TODO: consider merging these into one bind group @@ -1310,7 +1311,17 @@ fn fsMain(in: VertexOutput) -> @location(0) vec4f { let textureIdx = vec2u(floor(uv * uniforms.framebufferSize)); let sampleBufferIdx = textureIdx.y * u32(uniforms.framebufferSize.x) + textureIdx.x; let sample: array = sampleBuffer[sampleBufferIdx]; - let color = vec3f(sample[0], sample[1], sample[2]); + let currentColor = vec3f(sample[0], sample[1], sample[2]); + var color = vec3f(0f); + if uniforms.frameCount == 0u { + accumulationBuffer[sampleBufferIdx] = sample; + color = currentColor; + } else { + let previousSample: array = accumulationBuffer[sampleBufferIdx]; + let previousColor = vec3f(previousSample[0], previousSample[1], previousSample[2]); + color = 0.1 * currentColor + 0.9 * previousColor; + accumulationBuffer[sampleBufferIdx] = array(color.r, color.g, color.b); + } let rgb = acesFilmic(uniforms.exposure * color); let srgb = pow(rgb, vec3(1f / 2.2f));