//// AntialiasingEffect.cpp// libraries/render-utils/src///// Created by Raffi Bedikian on 8/30/15// Copyright 2015 High Fidelity, Inc.// Copyright 2024 Overte e.V.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include "AntialiasingEffect.h" #include <glm/gtc/random.hpp> #include <SharedUtil.h>#include <gpu/Context.h>#include <shaders/Shaders.h>#include <graphics/ShaderConstants.h> #include "render-utils/ShaderConstants.h"#include "StencilMaskPass.h"#include "RandomAndNoise.h" namespace ru { using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer;} namespace gr { using graphics::slot::texture::Texture; using graphics::slot::buffer::Buffer;} gpu::PipelinePointer Antialiasing::_antialiasingPipeline;gpu::PipelinePointer Antialiasing::_intensityPipeline;gpu::PipelinePointer Antialiasing::_blendPipeline;gpu::PipelinePointer Antialiasing::_debugBlendPipeline; #define TAA_JITTER_SEQUENCE_LENGTH 16 void AntialiasingSetupConfig::setIndex(int current) { _index = (current + TAA_JITTER_SEQUENCE_LENGTH) % TAA_JITTER_SEQUENCE_LENGTH; emit dirty();} void AntialiasingSetupConfig::setState(State state) { _state = (State)((int)state % (int)State::STATE_COUNT); switch (_state) { case State::NONE: { none(); break; } case State::PAUSE: { pause(); break; } case State::PLAY: default: { play(); break; } } emit dirty();} int AntialiasingSetupConfig::prev() { setIndex(_index - 1); return _index;} int AntialiasingSetupConfig::next() { setIndex(_index + 1); return _index;} AntialiasingSetupConfig::State AntialiasingSetupConfig::none() { _state = State::NONE; stop = true; freeze = false; setIndex(-1); return _state;} AntialiasingSetupConfig::State AntialiasingSetupConfig::pause() { _state = State::PAUSE; stop = false; freeze = true; setIndex(0); return _state;} AntialiasingSetupConfig::State AntialiasingSetupConfig::play() { _state = State::PLAY; stop = false; freeze = false; setIndex(0); return _state;} void AntialiasingSetupConfig::setAAMode(Mode mode) { this->mode = (Mode)glm::clamp((int)mode, 0, (int)AntialiasingSetupConfig::Mode::MODE_COUNT); emit dirty();} AntialiasingSetup::AntialiasingSetup() { _sampleSequence.reserve(TAA_JITTER_SEQUENCE_LENGTH + 1); // Fill in with jitter samples for (int i = 0; i < TAA_JITTER_SEQUENCE_LENGTH; i++) { _sampleSequence.emplace_back(glm::vec2(halton::evaluate<2>(i), halton::evaluate<3>(i)) - vec2(0.5f)); }} void AntialiasingSetup::configure(const Config& config) { _isStopped = config.stop; _isFrozen = config.freeze; if (config.freeze) { _freezedSampleIndex = config.getIndex(); } _scale = config.scale; _mode = config.mode;} void AntialiasingSetup::run(const render::RenderContextPointer& renderContext, Output& output) { assert(renderContext->args); if (!_isStopped && _mode == AntialiasingSetupConfig::Mode::TAA) { RenderArgs* args = renderContext->args; gpu::doInBatch("AntialiasingSetup::run", args->_context, [&](gpu::Batch& batch) { auto offset = 0; auto count = _sampleSequence.size(); if (_isFrozen) { count = 1; offset = _freezedSampleIndex; } batch.setProjectionJitterSequence(_sampleSequence.data() + offset, count); batch.setProjectionJitterScale(_scale); }); } output = _mode;} Antialiasing::Antialiasing(bool isSharpenEnabled) : _isSharpenEnabled{ isSharpenEnabled } {} Antialiasing::~Antialiasing() { _antialiasingBuffers.clear();} const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { if (!_antialiasingPipeline) { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::taa); gpu::StatePointer state = std::make_shared<gpu::State>(); // Good to go add the brand new pipeline _antialiasingPipeline = gpu::Pipeline::create(program, state); } return _antialiasingPipeline;} const gpu::PipelinePointer& Antialiasing::getIntensityPipeline() { if (!_intensityPipeline) { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::drawWhite); gpu::StatePointer state = std::make_shared<gpu::State>(); PrepareStencil::testNoAA(*state); // Good to go add the brand new pipeline _intensityPipeline = gpu::Pipeline::create(program, state); } return _intensityPipeline;} const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { if (!_blendPipeline) { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::aa_blend); gpu::StatePointer state = std::make_shared<gpu::State>(); // Good to go add the brand new pipeline _blendPipeline = gpu::Pipeline::create(program, state); } return _blendPipeline;} const gpu::PipelinePointer& Antialiasing::getDebugBlendPipeline() { if (!_debugBlendPipeline) { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::taa_blend); gpu::StatePointer state = std::make_shared<gpu::State>(); PrepareStencil::testNoAA(*state); // Good to go add the brand new pipeline _debugBlendPipeline = gpu::Pipeline::create(program, state); } return _debugBlendPipeline;} void Antialiasing::configure(const Config& config) { _sharpen = config.sharpen * 0.25f; if (!_isSharpenEnabled) { _sharpen = 0.0f; } _params.edit().setSharpenedOutput(_sharpen > 0.0f); _params.edit().blend = config.blend * config.blend; _params.edit().covarianceGamma = config.covarianceGamma; _params.edit().setConstrainColor(config.constrainColor); _params.edit().setFeedbackColor(config.feedbackColor); _params.edit().debugShowVelocityThreshold = config.debugShowVelocityThreshold; _params.edit().regionInfo.x = config.debugX; _debugFXAAX = config.debugFXAAX; _params.edit().setBicubicHistoryFetch(config.bicubicHistoryFetch); _params.edit().setDebug(config.debug); _params.edit().setShowDebugCursor(config.showCursorPixel); _params.edit().setDebugCursor(config.debugCursorTexcoord); _params.edit().setDebugOrbZoom(config.debugOrbZoom); _params.edit().setShowClosestFragment(config.showClosestFragment);} void Antialiasing::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { assert(renderContext->args); RenderArgs* args = renderContext->args; auto& deferredFrameTransform = inputs.get0(); const auto& deferredFrameBuffer = inputs.get1(); const auto& sourceBuffer = deferredFrameBuffer->getLightingFramebuffer(); const auto& linearDepthBuffer = inputs.get2(); const auto& velocityTexture = deferredFrameBuffer->getDeferredVelocityTexture(); const auto& mode = inputs.get3(); _params.edit().regionInfo.z = mode == AntialiasingSetupConfig::Mode::TAA ? _debugFXAAX : 0.0f; int width = sourceBuffer->getWidth(); int height = sourceBuffer->getHeight(); if (_antialiasingBuffers._swapChain && _antialiasingBuffers._swapChain->get(0) && _antialiasingBuffers._swapChain->get(0)->getSize() != uvec2(width, height)) { _antialiasingBuffers.clear(); } if (!_antialiasingBuffers._swapChain || !_intensityFramebuffer) { std::vector<gpu::FramebufferPointer> antiAliasingBuffers; // Link the antialiasing FBO to texture auto format = gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA); auto defaultSampler = Sampler(Sampler::FILTER_MIN_MAG_LINEAR, Sampler::WRAP_CLAMP); for (int i = 0; i < 2; i++) { antiAliasingBuffers.emplace_back(gpu::Framebuffer::create("antialiasing")); const auto& antiAliasingBuffer = antiAliasingBuffers.back(); _antialiasingBuffers._textures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); antiAliasingBuffer->setRenderBuffer(0, _antialiasingBuffers._textures[i]); } _antialiasingBuffers._swapChain = std::make_shared<gpu::FramebufferSwapChain>(antiAliasingBuffers); _intensityTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_R_8, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); _intensityFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("taaIntensity")); _intensityFramebuffer->setRenderBuffer(0, _intensityTexture); _intensityFramebuffer->setStencilBuffer(deferredFrameBuffer->getDeferredFramebuffer()->getDepthStencilBuffer(), deferredFrameBuffer->getDeferredFramebuffer()->getDepthStencilBufferFormat()); } output = _intensityTexture; gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { PROFILE_RANGE_BATCH(batch, "TAA"); batch.enableStereo(false); batch.setViewportTransform(args->_viewport); // Set the intensity buffer to 1 except when the stencil is masked as NoAA, where it should be 0 // This is a bit of a hack as it is not possible and not portable to use the stencil value directly // as a texture batch.setFramebuffer(_intensityFramebuffer); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, gpu::Vec4(0.0f)); batch.setResourceTexture(0, nullptr); batch.setPipeline(getIntensityPipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4); // TAA step if (!_params->isFXAAEnabled()) { batch.setResourceFramebufferSwapChainTexture(ru::Texture::TaaHistory, _antialiasingBuffers._swapChain, 0); batch.setResourceTexture(ru::Texture::TaaVelocity, velocityTexture); } else { batch.setResourceTexture(ru::Texture::TaaHistory, nullptr); batch.setResourceTexture(ru::Texture::TaaVelocity, nullptr); } batch.setResourceTexture(ru::Texture::TaaSource, sourceBuffer->getRenderBuffer(0)); batch.setResourceTexture(ru::Texture::TaaIntensity, _intensityTexture); // This is only used during debug batch.setResourceTexture(ru::Texture::TaaDepth, linearDepthBuffer->getLinearDepthTexture()); batch.setUniformBuffer(ru::Buffer::TaaParams, _params); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, deferredFrameTransform->getFrameTransformBuffer()); batch.setFramebufferSwapChain(_antialiasingBuffers._swapChain, 1); batch.setPipeline(getAntialiasingPipeline()); batch.draw(gpu::TRIANGLE_STRIP, 4); // Blend step batch.setResourceTexture(ru::Texture::TaaSource, nullptr); batch.setFramebuffer(sourceBuffer); if (_params->isDebug()) { batch.setPipeline(getDebugBlendPipeline()); batch.setResourceFramebufferSwapChainTexture(ru::Texture::TaaNext, _antialiasingBuffers._swapChain, 1); } else { batch.setPipeline(getBlendPipeline()); // Must match the binding point in the aa_blend.slf shader batch.setResourceFramebufferSwapChainTexture(0, _antialiasingBuffers._swapChain, 1); // Disable sharpen if FXAA if (!_blendParamsBuffer) { _blendParamsBuffer = std::make_shared<gpu::Buffer>(gpu::Buffer::UniformBuffer, sizeof(glm::vec4), nullptr); } _blendParamsBuffer->setSubData(0, _sharpen * _params.get().regionInfo.z); batch.setUniformBuffer(0, _blendParamsBuffer); } batch.draw(gpu::TRIANGLE_STRIP, 4); batch.advance(_antialiasingBuffers._swapChain); batch.setUniformBuffer(ru::Buffer::TaaParams, nullptr); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, nullptr); batch.setResourceTexture(ru::Texture::TaaDepth, nullptr); batch.setResourceTexture(ru::Texture::TaaHistory, nullptr); batch.setResourceTexture(ru::Texture::TaaVelocity, nullptr); batch.setResourceTexture(ru::Texture::TaaNext, nullptr); // Reset jitter sequence batch.setProjectionJitterSequence(nullptr, 0); });}
//
// AntialiasingEffect.cpp
// libraries/render-utils/src/
//
// Created by Raffi Bedikian on 8/30/15
// Copyright 2015 High Fidelity, Inc.
// Copyright 2024 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AntialiasingEffect.h"
#include <glm/gtc/random.hpp>
#include <SharedUtil.h>
#include <gpu/Context.h>
#include <shaders/Shaders.h>
#include <graphics/ShaderConstants.h>
#include "render-utils/ShaderConstants.h"
#include "StencilMaskPass.h"
#include "RandomAndNoise.h"
namespace ru {
using render_utils::slot::texture::Texture;
using render_utils::slot::buffer::Buffer;
}
namespace gr {
using graphics::slot::texture::Texture;
using graphics::slot::buffer::Buffer;
}
gpu::PipelinePointer Antialiasing::_antialiasingPipeline;
gpu::PipelinePointer Antialiasing::_intensityPipeline;
gpu::PipelinePointer Antialiasing::_blendPipeline;
gpu::PipelinePointer Antialiasing::_debugBlendPipeline;
#define TAA_JITTER_SEQUENCE_LENGTH 16
void AntialiasingSetupConfig::setIndex(int current) {
_index = (current + TAA_JITTER_SEQUENCE_LENGTH) % TAA_JITTER_SEQUENCE_LENGTH;
emit dirty();
}
void AntialiasingSetupConfig::setState(State state) {
_state = (State)((int)state % (int)State::STATE_COUNT);
switch (_state) {
case State::NONE: {
none();
break;
}
case State::PAUSE: {
pause();
break;
}
case State::PLAY:
default: {
play();
break;
}
}
emit dirty();
}
int AntialiasingSetupConfig::prev() {
setIndex(_index - 1);
return _index;
}
int AntialiasingSetupConfig::next() {
setIndex(_index + 1);
return _index;
}
AntialiasingSetupConfig::State AntialiasingSetupConfig::none() {
_state = State::NONE;
stop = true;
freeze = false;
setIndex(-1);
return _state;
}
AntialiasingSetupConfig::State AntialiasingSetupConfig::pause() {
_state = State::PAUSE;
stop = false;
freeze = true;
setIndex(0);
return _state;
}
AntialiasingSetupConfig::State AntialiasingSetupConfig::play() {
_state = State::PLAY;
stop = false;
freeze = false;
setIndex(0);
return _state;
}
void AntialiasingSetupConfig::setAAMode(Mode mode) {
this->mode = (Mode)glm::clamp((int)mode, 0, (int)AntialiasingSetupConfig::Mode::MODE_COUNT);
emit dirty();
}
AntialiasingSetup::AntialiasingSetup() {
_sampleSequence.reserve(TAA_JITTER_SEQUENCE_LENGTH + 1);
// Fill in with jitter samples
for (int i = 0; i < TAA_JITTER_SEQUENCE_LENGTH; i++) {
_sampleSequence.emplace_back(glm::vec2(halton::evaluate<2>(i), halton::evaluate<3>(i)) - vec2(0.5f));
}
}
void AntialiasingSetup::configure(const Config& config) {
_isStopped = config.stop;
_isFrozen = config.freeze;
if (config.freeze) {
_freezedSampleIndex = config.getIndex();
}
_scale = config.scale;
_mode = config.mode;
}
void AntialiasingSetup::run(const render::RenderContextPointer& renderContext, Output& output) {
assert(renderContext->args);
if (!_isStopped && _mode == AntialiasingSetupConfig::Mode::TAA) {
RenderArgs* args = renderContext->args;
gpu::doInBatch("AntialiasingSetup::run", args->_context, [&](gpu::Batch& batch) {
auto offset = 0;
auto count = _sampleSequence.size();
if (_isFrozen) {
count = 1;
offset = _freezedSampleIndex;
}
batch.setProjectionJitterSequence(_sampleSequence.data() + offset, count);
batch.setProjectionJitterScale(_scale);
});
}
output = _mode;
}
Antialiasing::Antialiasing(bool isSharpenEnabled) :
_isSharpenEnabled{ isSharpenEnabled } {
}
Antialiasing::~Antialiasing() {
_antialiasingBuffers.clear();
}
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
if (!_antialiasingPipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::taa);
gpu::StatePointer state = std::make_shared<gpu::State>();
// Good to go add the brand new pipeline
_antialiasingPipeline = gpu::Pipeline::create(program, state);
}
return _antialiasingPipeline;
}
const gpu::PipelinePointer& Antialiasing::getIntensityPipeline() {
if (!_intensityPipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::drawWhite);
gpu::StatePointer state = std::make_shared<gpu::State>();
PrepareStencil::testNoAA(*state);
// Good to go add the brand new pipeline
_intensityPipeline = gpu::Pipeline::create(program, state);
}
return _intensityPipeline;
}
const gpu::PipelinePointer& Antialiasing::getBlendPipeline() {
if (!_blendPipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::aa_blend);
gpu::StatePointer state = std::make_shared<gpu::State>();
// Good to go add the brand new pipeline
_blendPipeline = gpu::Pipeline::create(program, state);
}
return _blendPipeline;
}
const gpu::PipelinePointer& Antialiasing::getDebugBlendPipeline() {
if (!_debugBlendPipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::taa_blend);
gpu::StatePointer state = std::make_shared<gpu::State>();
PrepareStencil::testNoAA(*state);
// Good to go add the brand new pipeline
_debugBlendPipeline = gpu::Pipeline::create(program, state);
}
return _debugBlendPipeline;
}
void Antialiasing::configure(const Config& config) {
_sharpen = config.sharpen * 0.25f;
if (!_isSharpenEnabled) {
_sharpen = 0.0f;
}
_params.edit().setSharpenedOutput(_sharpen > 0.0f);
_params.edit().blend = config.blend * config.blend;
_params.edit().covarianceGamma = config.covarianceGamma;
_params.edit().setConstrainColor(config.constrainColor);
_params.edit().setFeedbackColor(config.feedbackColor);
_params.edit().debugShowVelocityThreshold = config.debugShowVelocityThreshold;
_params.edit().regionInfo.x = config.debugX;
_debugFXAAX = config.debugFXAAX;
_params.edit().setBicubicHistoryFetch(config.bicubicHistoryFetch);
_params.edit().setDebug(config.debug);
_params.edit().setShowDebugCursor(config.showCursorPixel);
_params.edit().setDebugCursor(config.debugCursorTexcoord);
_params.edit().setDebugOrbZoom(config.debugOrbZoom);
_params.edit().setShowClosestFragment(config.showClosestFragment);
}
void Antialiasing::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) {
assert(renderContext->args);
RenderArgs* args = renderContext->args;
auto& deferredFrameTransform = inputs.get0();
const auto& deferredFrameBuffer = inputs.get1();
const auto& sourceBuffer = deferredFrameBuffer->getLightingFramebuffer();
const auto& linearDepthBuffer = inputs.get2();
const auto& velocityTexture = deferredFrameBuffer->getDeferredVelocityTexture();
const auto& mode = inputs.get3();
_params.edit().regionInfo.z = mode == AntialiasingSetupConfig::Mode::TAA ? _debugFXAAX : 0.0f;
int width = sourceBuffer->getWidth();
int height = sourceBuffer->getHeight();
if (_antialiasingBuffers._swapChain && _antialiasingBuffers._swapChain->get(0) && _antialiasingBuffers._swapChain->get(0)->getSize() != uvec2(width, height)) {
_antialiasingBuffers.clear();
}
if (!_antialiasingBuffers._swapChain || !_intensityFramebuffer) {
std::vector<gpu::FramebufferPointer> antiAliasingBuffers;
// Link the antialiasing FBO to texture
auto format = gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA);
auto defaultSampler = Sampler(Sampler::FILTER_MIN_MAG_LINEAR, Sampler::WRAP_CLAMP);
for (int i = 0; i < 2; i++) {
antiAliasingBuffers.emplace_back(gpu::Framebuffer::create("antialiasing"));
const auto& antiAliasingBuffer = antiAliasingBuffers.back();
_antialiasingBuffers._textures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler);
antiAliasingBuffer->setRenderBuffer(0, _antialiasingBuffers._textures[i]);
}
_antialiasingBuffers._swapChain = std::make_shared<gpu::FramebufferSwapChain>(antiAliasingBuffers);
_intensityTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_R_8, width, height, gpu::Texture::SINGLE_MIP, defaultSampler);
_intensityFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("taaIntensity"));
_intensityFramebuffer->setRenderBuffer(0, _intensityTexture);
_intensityFramebuffer->setStencilBuffer(deferredFrameBuffer->getDeferredFramebuffer()->getDepthStencilBuffer(), deferredFrameBuffer->getDeferredFramebuffer()->getDepthStencilBufferFormat());
}
output = _intensityTexture;
gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) {
PROFILE_RANGE_BATCH(batch, "TAA");
batch.enableStereo(false);
batch.setViewportTransform(args->_viewport);
// Set the intensity buffer to 1 except when the stencil is masked as NoAA, where it should be 0
// This is a bit of a hack as it is not possible and not portable to use the stencil value directly
// as a texture
batch.setFramebuffer(_intensityFramebuffer);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, gpu::Vec4(0.0f));
batch.setResourceTexture(0, nullptr);
batch.setPipeline(getIntensityPipeline());
batch.draw(gpu::TRIANGLE_STRIP, 4);
// TAA step
if (!_params->isFXAAEnabled()) {
batch.setResourceFramebufferSwapChainTexture(ru::Texture::TaaHistory, _antialiasingBuffers._swapChain, 0);
batch.setResourceTexture(ru::Texture::TaaVelocity, velocityTexture);
} else {
batch.setResourceTexture(ru::Texture::TaaHistory, nullptr);
batch.setResourceTexture(ru::Texture::TaaVelocity, nullptr);
}
batch.setResourceTexture(ru::Texture::TaaSource, sourceBuffer->getRenderBuffer(0));
batch.setResourceTexture(ru::Texture::TaaIntensity, _intensityTexture);
// This is only used during debug
batch.setResourceTexture(ru::Texture::TaaDepth, linearDepthBuffer->getLinearDepthTexture());
batch.setUniformBuffer(ru::Buffer::TaaParams, _params);
batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, deferredFrameTransform->getFrameTransformBuffer());
batch.setFramebufferSwapChain(_antialiasingBuffers._swapChain, 1);
batch.setPipeline(getAntialiasingPipeline());
batch.draw(gpu::TRIANGLE_STRIP, 4);
// Blend step
batch.setResourceTexture(ru::Texture::TaaSource, nullptr);
batch.setFramebuffer(sourceBuffer);
if (_params->isDebug()) {
batch.setPipeline(getDebugBlendPipeline());
batch.setResourceFramebufferSwapChainTexture(ru::Texture::TaaNext, _antialiasingBuffers._swapChain, 1);
} else {
batch.setPipeline(getBlendPipeline());
// Must match the binding point in the aa_blend.slf shader
batch.setResourceFramebufferSwapChainTexture(0, _antialiasingBuffers._swapChain, 1);
// Disable sharpen if FXAA
if (!_blendParamsBuffer) {
_blendParamsBuffer = std::make_shared<gpu::Buffer>(gpu::Buffer::UniformBuffer, sizeof(glm::vec4), nullptr);
}
_blendParamsBuffer->setSubData(0, _sharpen * _params.get().regionInfo.z);
batch.setUniformBuffer(0, _blendParamsBuffer);
}
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.advance(_antialiasingBuffers._swapChain);
batch.setUniformBuffer(ru::Buffer::TaaParams, nullptr);
batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, nullptr);
batch.setResourceTexture(ru::Texture::TaaDepth, nullptr);
batch.setResourceTexture(ru::Texture::TaaHistory, nullptr);
batch.setResourceTexture(ru::Texture::TaaVelocity, nullptr);
batch.setResourceTexture(ru::Texture::TaaNext, nullptr);
// Reset jitter sequence
batch.setProjectionJitterSequence(nullptr, 0);
});
}