From 31c71e542ea2e10106f9fcbeac0bd9aa0e8be6d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sun, 12 Dec 2021 23:04:05 +0100 Subject: [PATCH] Examples/DeferredShading: Improve bloom quality --- bin/resources/bloom_bright.nzsl | 29 +-- bin/resources/bloom_final.nzsl | 8 +- bin/resources/gamma.nzsl | 4 +- bin/resources/gaussian_blur.nzsl | 32 ++-- bin/resources/tone_mapping.nzsl | 4 +- examples/DeferredShading/main.cpp | 287 ++++++++++++++++++++++-------- 6 files changed, 250 insertions(+), 114 deletions(-) diff --git a/bin/resources/bloom_bright.nzsl b/bin/resources/bloom_bright.nzsl index 3a97698c7..278ea186c 100644 --- a/bin/resources/bloom_bright.nzsl +++ b/bin/resources/bloom_bright.nzsl @@ -20,7 +20,8 @@ external struct FragIn { - [builtin(fragcoord)] fragcoord: vec4 + [builtin(fragcoord)] fragcoord: vec4, + [location(0)] uv: vec2 } struct FragOut @@ -30,31 +31,38 @@ struct FragOut struct VertIn { - [location(0)] pos: vec3 + [location(0)] pos: vec2, + [location(1)] uv: vec2 } struct VertOut { - [builtin(position)] position: vec4 + [builtin(position)] position: vec4, + [location(0)] uv: vec2 } [entry(frag)] fn main(input: FragIn) -> FragOut { - let BrightLuminance = 0.8; + /*let BrightLuminance = 0.8; let BrightMiddleGrey = 0.5; let BrightThreshold = 0.7; - let fragcoord = input.fragcoord.xy * viewerData.invRenderTargetSize * 10.0; - - let color = colorTexture.Sample(fragcoord).rgb; + let color = colorTexture.Sample(input.uv).rgb; color *= BrightMiddleGrey / BrightLuminance; color *= vec3(1.0, 1.0, 1.0) + (color / (BrightThreshold*BrightThreshold)); color -= vec3(0.5, 0.5, 0.5); - color /= vec3(1.0, 1.0, 1.0) + color; + color /= vec3(1.0, 1.0, 1.0) + color;*/ let output: FragOut; - output.color = vec4(max(color, vec3(0.0, 0.0, 0.0)), 1.0); + //output.color = vec4(max(color, vec3(0.0, 0.0, 0.0)), 1.0); + + let color = colorTexture.Sample(input.uv).rgb; + let brightness = dot(color, vec3(0.2126, 0.7152, 0.0722)); + if (brightness > 1.0) + output.color = vec4(color, 1.0); + else + output.color = vec4(0.0, 0.0, 0.0, 1.0); return output; } @@ -63,7 +71,8 @@ fn main(input: FragIn) -> FragOut fn main(input: VertIn) -> VertOut { let output: VertOut; - output.position = vec4(input.pos, 1.0); + output.position = vec4(input.pos, 0.0, 1.0); + output.uv = input.uv; return output; } diff --git a/bin/resources/bloom_final.nzsl b/bin/resources/bloom_final.nzsl index b8a645713..9fc2ab92a 100644 --- a/bin/resources/bloom_final.nzsl +++ b/bin/resources/bloom_final.nzsl @@ -15,7 +15,7 @@ struct ViewerData external { [set(0), binding(0)] viewerData: uniform, - [set(0), binding(1)] colorTexture: sampler2D, + //[set(0), binding(1)] colorTexture: sampler2D, [set(0), binding(2)] bloomTexture: sampler2D, } @@ -31,7 +31,7 @@ struct FragOut struct VertIn { - [location(0)] pos: vec3 + [location(0)] pos: vec2 } struct VertOut @@ -45,7 +45,7 @@ fn main(input: FragIn) -> FragOut let fragcoord = input.fragcoord.xy * viewerData.invRenderTargetSize; let output: FragOut; - output.color = colorTexture.Sample(fragcoord) + bloomTexture.Sample(fragcoord); + output.color = /*colorTexture.Sample(fragcoord) + */bloomTexture.Sample(fragcoord); return output; } @@ -54,7 +54,7 @@ fn main(input: FragIn) -> FragOut fn main(input: VertIn) -> VertOut { let output: VertOut; - output.position = vec4(input.pos, 1.0); + output.position = vec4(input.pos, 0.0, 1.0); return output; } diff --git a/bin/resources/gamma.nzsl b/bin/resources/gamma.nzsl index beb9ffce6..7db7e075b 100644 --- a/bin/resources/gamma.nzsl +++ b/bin/resources/gamma.nzsl @@ -15,7 +15,7 @@ struct FragOut struct VertIn { - [location(0)] pos: vec3, + [location(0)] pos: vec2, [location(1)] uv: vec2 } @@ -40,7 +40,7 @@ fn main(input: FragIn) -> FragOut fn main(input: VertIn) -> VertOut { let output: VertOut; - output.position = vec4(input.pos, 1.0); + output.position = vec4(input.pos, 0.0, 1.0); output.vertUV = input.uv; return output; } diff --git a/bin/resources/gaussian_blur.nzsl b/bin/resources/gaussian_blur.nzsl index 63c3e2c3d..4e6fea80a 100644 --- a/bin/resources/gaussian_blur.nzsl +++ b/bin/resources/gaussian_blur.nzsl @@ -12,10 +12,18 @@ struct ViewerData eyePosition: vec3 } +[layout(std140)] +struct BlurData +{ + direction: vec2, + sizeFactor: f32 +} + external { [set(0), binding(0)] viewerData: uniform, [set(0), binding(1)] colorTexture: sampler2D, + [set(0), binding(2)] blurData: uniform } struct FragIn @@ -30,7 +38,7 @@ struct FragOut struct VertIn { - [location(0)] pos: vec3 + [location(0)] pos: vec2 } struct VertOut @@ -41,26 +49,16 @@ struct VertOut [entry(frag)] fn main(input: FragIn) -> FragOut { - let invTargetSize = viewerData.invRenderTargetSize * 10.0; + let invTargetSize = viewerData.invRenderTargetSize * blurData.sizeFactor; let fragcoord = input.fragcoord.xy * invTargetSize; let color = colorTexture.Sample(fragcoord).rgb * 0.2270270270; - - let filter = vec2(1.0, 0.0); - color += colorTexture.Sample(fragcoord + filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162; - color += colorTexture.Sample(fragcoord - filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162; + color += colorTexture.Sample(fragcoord + blurData.direction * 1.3846153846 * invTargetSize).rgb * 0.3162162162; + color += colorTexture.Sample(fragcoord - blurData.direction * 1.3846153846 * invTargetSize).rgb * 0.3162162162; - color += colorTexture.Sample(fragcoord + filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703; - color += colorTexture.Sample(fragcoord - filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703; - - filter = vec2(0.0, 1.0); - - color += colorTexture.Sample(fragcoord + filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162; - color += colorTexture.Sample(fragcoord - filter * 1.3846153846 * invTargetSize).rgb * 0.3162162162; - - color += colorTexture.Sample(fragcoord + filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703; - color += colorTexture.Sample(fragcoord - filter * 3.2307692308 * invTargetSize).rgb * 0.0702702703; + color += colorTexture.Sample(fragcoord + blurData.direction * 3.2307692308 * invTargetSize).rgb * 0.0702702703; + color += colorTexture.Sample(fragcoord - blurData.direction * 3.2307692308 * invTargetSize).rgb * 0.0702702703; let output: FragOut; output.color = vec4(color, 1.0); @@ -72,7 +70,7 @@ fn main(input: FragIn) -> FragOut fn main(input: VertIn) -> VertOut { let output: VertOut; - output.position = vec4(input.pos, 1.0); + output.position = vec4(input.pos, 0.0, 1.0); return output; } diff --git a/bin/resources/tone_mapping.nzsl b/bin/resources/tone_mapping.nzsl index 4938797b5..152a6f2ee 100644 --- a/bin/resources/tone_mapping.nzsl +++ b/bin/resources/tone_mapping.nzsl @@ -30,7 +30,7 @@ struct FragOut struct VertIn { - [location(0)] pos: vec3 + [location(0)] pos: vec2 } struct VertOut @@ -60,7 +60,7 @@ fn main(input: FragIn) -> FragOut fn main(input: VertIn) -> VertOut { let output: VertOut; - output.position = vec4(input.pos, 1.0); + output.position = vec4(input.pos, 0.0, 1.0); return output; } diff --git a/examples/DeferredShading/main.cpp b/examples/DeferredShading/main.cpp index 4ae8375ef..5a70d7913 100644 --- a/examples/DeferredShading/main.cpp +++ b/examples/DeferredShading/main.cpp @@ -11,6 +11,8 @@ NAZARA_REQUEST_DEDICATED_GPU() +constexpr std::size_t BloomSubdivisionCount = 5; + /* [layout(std140)] struct PointLight @@ -325,7 +327,7 @@ int main() } - const std::shared_ptr& fullscreenVertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_UV); + const std::shared_ptr& fullscreenVertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XY_UV); unsigned int offscreenWidth = windowSize.x; @@ -353,15 +355,60 @@ int main() fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_bright.nzsl", {})); std::shared_ptr bloomBrightShaderBinding; - std::shared_ptr gaussianBlurShaderBinding; std::shared_ptr bloomBrightPipeline = device->InstantiateRenderPipeline(fullscreenPipelineInfoViewer); // Gaussian Blur - fullscreenPipelineInfoViewer.shaderModules.clear(); - fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gaussian_blur.nzsl", {})); - std::shared_ptr gaussianBlurPipeline = device->InstantiateRenderPipeline(fullscreenPipelineInfoViewer); + Nz::RenderPipelineLayoutInfo gaussianBlurPipelineLayoutInfo = fullscreenPipelineLayoutInfoViewer; + + gaussianBlurPipelineLayoutInfo.bindings.push_back({ + 0, 2, + Nz::ShaderBindingType::UniformBuffer, + Nz::ShaderStageType::Fragment, + }); + + Nz::RenderPipelineInfo gaussianBlurPipelineInfo = fullscreenPipelineInfoViewer; + gaussianBlurPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(gaussianBlurPipelineLayoutInfo); + + Nz::FieldOffsets gaussianBlurDataOffsets(Nz::StructLayout::Std140); + std::size_t gaussianBlurDataDirection = gaussianBlurDataOffsets.AddField(Nz::StructFieldType::Float2); + std::size_t gaussianBlurDataSize = gaussianBlurDataOffsets.AddField(Nz::StructFieldType::Float1); + + gaussianBlurPipelineInfo.shaderModules.clear(); + gaussianBlurPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gaussian_blur.nzsl", {})); + + std::shared_ptr gaussianBlurPipeline = device->InstantiateRenderPipeline(gaussianBlurPipelineInfo); + std::vector> gaussianBlurShaderBinding(BloomSubdivisionCount * 2); + + std::vector gaussianBlurData(gaussianBlurDataOffsets.GetSize()); + std::vector> gaussianBlurUbos; + + float sizeFactor = 2.f; + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) + { + Nz::AccessByOffset(gaussianBlurData.data(), gaussianBlurDataDirection) = Nz::Vector2f(1.f, 0.f); + Nz::AccessByOffset(gaussianBlurData.data(), gaussianBlurDataSize) = sizeFactor; + + std::shared_ptr horizontalBlurData = device->InstantiateBuffer(Nz::BufferType::Uniform); + if (!horizontalBlurData->Initialize(gaussianBlurDataOffsets.GetSize(), Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic)) + return __LINE__; + + horizontalBlurData->Fill(gaussianBlurData.data(), 0, gaussianBlurDataOffsets.GetSize()); + + Nz::AccessByOffset(gaussianBlurData.data(), gaussianBlurDataDirection) = Nz::Vector2f(0.f, 1.f); + + std::shared_ptr verticalBlurData = device->InstantiateBuffer(Nz::BufferType::Uniform); + if (!verticalBlurData->Initialize(gaussianBlurDataOffsets.GetSize(), Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic)) + return __LINE__; + + verticalBlurData->Fill(gaussianBlurData.data(), 0, gaussianBlurDataOffsets.GetSize()); + + sizeFactor *= 2.f; + + gaussianBlurUbos.push_back(horizontalBlurData); + gaussianBlurUbos.push_back(verticalBlurData); + } // Tone mapping std::shared_ptr toneMappingShaderBinding; @@ -373,14 +420,16 @@ int main() // Bloom blend + std::shared_ptr bloomBlitBinding; + Nz::RenderPipelineLayoutInfo bloomBlendPipelineLayoutInfo; Nz::Graphics::FillViewerPipelineLayout(bloomBlendPipelineLayoutInfo, 0); - bloomBlendPipelineLayoutInfo.bindings.push_back({ + /*bloomBlendPipelineLayoutInfo.bindings.push_back({ 0, 1, Nz::ShaderBindingType::Texture, Nz::ShaderStageType::Fragment, - }); + });*/ bloomBlendPipelineLayoutInfo.bindings.push_back({ 0, 2, @@ -390,6 +439,9 @@ int main() Nz::RenderPipelineInfo bloomBlendPipelineInfo; + bloomBlendPipelineInfo.blending = true; + bloomBlendPipelineInfo.blend.dstColor = Nz::BlendFunc::One; + bloomBlendPipelineInfo.blend.srcColor = Nz::BlendFunc::One; bloomBlendPipelineInfo.primitiveMode = Nz::PrimitiveMode::TriangleList; bloomBlendPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(bloomBlendPipelineLayoutInfo); bloomBlendPipelineInfo.vertexBuffers.push_back({ @@ -401,7 +453,7 @@ int main() std::shared_ptr bloomBlendPipeline = device->InstantiateRenderPipeline(bloomBlendPipelineInfo); - std::shared_ptr bloomBlendShaderBinding; + std::vector> bloomBlendShaderBinding(BloomSubdivisionCount); // Fullscreen data @@ -476,18 +528,18 @@ int main() std::vector> lightingShaderBindings; - std::array vertexData = { + std::array vertexData = { { { - Nz::Vector3f(-1.f, 1.f, 0.0f), + Nz::Vector2f(-1.f, 1.f), Nz::Vector2f(0.0f, 1.0f), }, { - Nz::Vector3f(-1.f, -3.f, 0.0f), + Nz::Vector2f(-1.f, -3.f), Nz::Vector2f(0.0f, -1.0f), }, { - Nz::Vector3f(3.f, 1.f, 0.0f), + Nz::Vector2f(3.f, 1.f), Nz::Vector2f(2.0f, 1.0f), } } @@ -558,9 +610,9 @@ int main() std::size_t positionTexture; std::size_t depthBuffer1; std::size_t depthBuffer2; + std::size_t bloomBrightOutput; std::size_t bloomOutput; - std::size_t bloomTextureA; - std::size_t bloomTextureB; + std::vector bloomTextures(BloomSubdivisionCount * 2); std::size_t lightOutput; std::size_t toneMappingOutput; @@ -625,19 +677,33 @@ int main() Nz::PixelFormat::RGBA16F }); - bloomTextureA = graph.AddAttachment({ - "Bloom texture A", + unsigned int bloomSize = 50'000; + bloomBrightOutput = graph.AddAttachment({ + "Bloom bright output", Nz::PixelFormat::RGBA16F, - 10'000, - 10'000 + bloomSize, + bloomSize }); - bloomTextureB = graph.AddAttachment({ - "Bloom texture B", - Nz::PixelFormat::RGBA16F, - 10'000, - 10'000 - }); + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) + { + bloomTextures[i * 2 + 0] = graph.AddAttachment({ + "Bloom texture #" + std::to_string(i), + Nz::PixelFormat::RGBA16F, + bloomSize, + bloomSize + }); + + + bloomTextures[i * 2 + 1] = graph.AddAttachment({ + "Bloom texture #" + std::to_string(i), + Nz::PixelFormat::RGBA16F, + bloomSize, + bloomSize + }); + + bloomSize /= 2; + } toneMappingOutput = graph.AddAttachment({ "Tone mapping", @@ -768,39 +834,73 @@ int main() }); bloomBrightPass.AddInput(lightOutput); - bloomBrightPass.AddOutput(bloomTextureA); + bloomBrightPass.AddOutput(bloomBrightOutput); - Nz::FramePass& bloomBlurPass = graph.AddPass("Bloom pass - gaussian blur"); - bloomBlurPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder, const Nz::Recti& renderArea) + std::size_t bloomTextureIndex = 0; + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) { - builder.SetScissor(renderArea); - builder.SetViewport(renderArea); + Nz::FramePass& bloomBlurPassHorizontal = graph.AddPass("Bloom pass - gaussian blur #" + std::to_string(i) + " - horizontal"); + bloomBlurPassHorizontal.SetCommandCallback([&, i](Nz::CommandBufferBuilder& builder, const Nz::Recti& renderArea) + { + builder.SetScissor(renderArea); + builder.SetViewport(renderArea); - builder.BindShaderBinding(0, *gaussianBlurShaderBinding); - builder.BindPipeline(*gaussianBlurPipeline); - builder.BindVertexBuffer(0, *fullscreenVertexBuffer); + builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 0]); + builder.BindPipeline(*gaussianBlurPipeline); + builder.BindVertexBuffer(0, *fullscreenVertexBuffer); - builder.Draw(3); - }); - bloomBlurPass.SetExecutionCallback([&] - { - return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip; - }); + builder.Draw(3); + }); + + bloomBlurPassHorizontal.SetExecutionCallback([&] + { + return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip; + }); + + bloomBlurPassHorizontal.AddInput((i == 0) ? bloomBrightOutput : bloomTextures[bloomTextureIndex++]); + bloomBlurPassHorizontal.AddOutput(bloomTextures[bloomTextureIndex]); + + Nz::FramePass& bloomBlurPassVertical = graph.AddPass("Bloom pass - gaussian blur #" + std::to_string(i) + " - vertical"); + bloomBlurPassVertical.SetCommandCallback([&, i](Nz::CommandBufferBuilder& builder, const Nz::Recti& renderArea) + { + builder.SetScissor(renderArea); + builder.SetViewport(renderArea); + + builder.BindShaderBinding(0, *gaussianBlurShaderBinding[i * 2 + 1]); + builder.BindPipeline(*gaussianBlurPipeline); + builder.BindVertexBuffer(0, *fullscreenVertexBuffer); + + builder.Draw(3); + }); + + bloomBlurPassVertical.SetExecutionCallback([&] + { + return (bloomEnabled) ? Nz::FramePassExecution::Execute : Nz::FramePassExecution::Skip; + }); + + bloomBlurPassVertical.AddInput(bloomTextures[bloomTextureIndex++]); + bloomBlurPassVertical.AddOutput(bloomTextures[bloomTextureIndex]); + } - bloomBlurPass.AddInput(bloomTextureA); - bloomBlurPass.AddOutput(bloomTextureB); - Nz::FramePass& bloomBlendPass = graph.AddPass("Bloom pass - blend"); bloomBlendPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder, const Nz::Recti& renderArea) { builder.SetScissor(renderArea); builder.SetViewport(renderArea); - - builder.BindShaderBinding(0, *bloomBlendShaderBinding); - builder.BindPipeline(*bloomBlendPipeline); builder.BindVertexBuffer(0, *fullscreenVertexBuffer); + // Blit light output + builder.BindPipeline(*Nz::Graphics::Instance()->GetBlitPipeline(false)); + builder.BindShaderBinding(0, *bloomBlitBinding); builder.Draw(3); + + // Blend bloom + builder.BindPipeline(*bloomBlendPipeline); + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) + { + builder.BindShaderBinding(0, *bloomBlendShaderBinding[i]); + builder.Draw(3); + } }); bloomBlendPass.SetExecutionCallback([&] @@ -809,7 +909,9 @@ int main() }); bloomBlendPass.AddInput(lightOutput); - bloomBlendPass.AddInput(bloomTextureB); + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) + bloomBlendPass.AddInput(bloomTextures[i * 2 + 1]); + bloomBlendPass.AddOutput(bloomOutput); Nz::FramePass& toneMappingPass = graph.AddPass("Tone mapping"); @@ -1048,50 +1150,77 @@ int main() } }); - frame.PushForRelease(std::move(gaussianBlurShaderBinding)); + std::size_t bloomTextureIndex = 0; + for (std::size_t i = 0; i < BloomSubdivisionCount; ++i) + { + for (std::size_t j = 0; j < 2; ++j) + { + frame.PushForRelease(std::move(gaussianBlurShaderBinding[i * 2 + j])); - gaussianBlurShaderBinding = fullscreenPipelineInfoViewer.pipelineLayout->AllocateShaderBinding(0); - gaussianBlurShaderBinding->Update({ - { - 0, - Nz::ShaderBinding::UniformBufferBinding { - viewerInstance.GetViewerBuffer().get(), - 0, viewerInstance.GetViewerBuffer()->GetSize() - } - }, - { - 1, - Nz::ShaderBinding::TextureBinding { - bakedGraph.GetAttachmentTexture(bloomTextureA).get(), - textureSampler.get() - } + gaussianBlurShaderBinding[i * 2 + j] = gaussianBlurPipeline->GetPipelineInfo().pipelineLayout->AllocateShaderBinding(0); + gaussianBlurShaderBinding[i * 2 + j]->Update({ + { + 0, + Nz::ShaderBinding::UniformBufferBinding { + viewerInstance.GetViewerBuffer().get(), + 0, viewerInstance.GetViewerBuffer()->GetSize() + } + }, + { + 1, + Nz::ShaderBinding::TextureBinding { + bakedGraph.GetAttachmentTexture((i == 0 && j == 0) ? bloomBrightOutput : bloomTextures[bloomTextureIndex++]).get(), + textureSampler.get() + } + }, + { + 2, + Nz::ShaderBinding::UniformBufferBinding { + gaussianBlurUbos[i * 2 + j].get(), + 0, gaussianBlurUbos[i * 2 + j]->GetSize() + } + } + }); } - }); - frame.PushForRelease(std::move(bloomBlendShaderBinding)); + frame.PushForRelease(std::move(bloomBlendShaderBinding[i])); - bloomBlendShaderBinding = bloomBlendPipelineInfo.pipelineLayout->AllocateShaderBinding(0); - bloomBlendShaderBinding->Update({ + bloomBlendShaderBinding[i] = bloomBlendPipelineInfo.pipelineLayout->AllocateShaderBinding(0); + bloomBlendShaderBinding[i]->Update({ + { + 0, + Nz::ShaderBinding::UniformBufferBinding { + viewerInstance.GetViewerBuffer().get(), + 0, viewerInstance.GetViewerBuffer()->GetSize() + } + }, + /*{ + 1, + Nz::ShaderBinding::TextureBinding { + bakedGraph.GetAttachmentTexture(lightOutput).get(), + textureSampler.get() + } + },*/ + { + 2, + Nz::ShaderBinding::TextureBinding { + bakedGraph.GetAttachmentTexture(bloomTextures[i * 2 + 1]).get(), + textureSampler.get() + } + } + }); + } + + frame.PushForRelease(std::move(bloomBlitBinding)); + + bloomBlitBinding = Nz::Graphics::Instance()->GetBlitPipelineLayout()->AllocateShaderBinding(0); + bloomBlitBinding->Update({ { 0, - Nz::ShaderBinding::UniformBufferBinding { - viewerInstance.GetViewerBuffer().get(), - 0, viewerInstance.GetViewerBuffer()->GetSize() - } - }, - { - 1, Nz::ShaderBinding::TextureBinding { bakedGraph.GetAttachmentTexture(lightOutput).get(), textureSampler.get() } - }, - { - 2, - Nz::ShaderBinding::TextureBinding { - bakedGraph.GetAttachmentTexture(bloomTextureB).get(), - textureSampler.get() - } } });