Fix TAA jitter in post-resolve passes such as editor primitives and debug gizmos
This commit is contained in:
@@ -739,6 +739,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
}
|
||||
Context->LastViewPos = view.Position;
|
||||
Context->LastViewProj = view.Projection;
|
||||
TaaJitterRemoveContext taaJitterRemove(view);
|
||||
|
||||
// Fallback to task buffers
|
||||
if (target == nullptr && renderContext.Task)
|
||||
@@ -766,7 +767,7 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
|
||||
const auto cb = DebugDrawShader->GetShader()->GetCB(0);
|
||||
Data data;
|
||||
Matrix vp;
|
||||
Matrix::Multiply(view.View, view.NonJitteredProjection, vp);
|
||||
Matrix::Multiply(view.View, view.Projection, vp);
|
||||
Matrix::Transpose(vp, data.ViewProjection);
|
||||
data.EnableDepthTest = enableDepthTest;
|
||||
context->UpdateCB(cb, &data);
|
||||
|
||||
@@ -18,6 +18,7 @@ void RenderView::Prepare(RenderContext& renderContext)
|
||||
// Check if use TAA (need to modify the projection matrix)
|
||||
Float2 taaJitter;
|
||||
NonJitteredProjection = Projection;
|
||||
IsTaaResolved = false;
|
||||
if (renderContext.List->Setup.UseTemporalAAJitter)
|
||||
{
|
||||
// Move to the next frame
|
||||
@@ -82,6 +83,18 @@ void RenderView::PrepareCache(const RenderContext& renderContext, float width, f
|
||||
MainScreenSize = mainView->ScreenSize;
|
||||
}
|
||||
|
||||
void RenderView::UpdateCachedData()
|
||||
{
|
||||
Matrix::Invert(View, IV);
|
||||
Matrix::Invert(Projection, IP);
|
||||
Matrix viewProjection;
|
||||
Matrix::Multiply(View, Projection, viewProjection);
|
||||
Frustum.SetMatrix(viewProjection);
|
||||
Matrix::Invert(viewProjection, IVP);
|
||||
CullingFrustum = Frustum;
|
||||
NonJitteredProjection = Projection;
|
||||
}
|
||||
|
||||
void RenderView::SetUp(const Matrix& viewProjection)
|
||||
{
|
||||
// Copy data
|
||||
@@ -201,3 +214,27 @@ void RenderView::GetWorldMatrix(const Transform& transform, Matrix& world) const
|
||||
const Float3 translation = transform.Translation - Origin;
|
||||
Matrix::Transformation(transform.Scale, transform.Orientation, translation, world);
|
||||
}
|
||||
|
||||
TaaJitterRemoveContext::TaaJitterRemoveContext(const RenderView& view)
|
||||
{
|
||||
if (view.IsTaaResolved)
|
||||
{
|
||||
// Cancel-out sub-pixel jitter when drawing geometry after TAA has been resolved
|
||||
_view = (RenderView*)&view;
|
||||
_prevProjection = view.Projection;
|
||||
_prevNonJitteredProjection = view.NonJitteredProjection;
|
||||
_view->Projection = _prevNonJitteredProjection;
|
||||
_view->UpdateCachedData();
|
||||
}
|
||||
}
|
||||
|
||||
TaaJitterRemoveContext::~TaaJitterRemoveContext()
|
||||
{
|
||||
if (_view)
|
||||
{
|
||||
// Restore projection
|
||||
_view->Projection = _prevProjection;
|
||||
_view->UpdateCachedData();
|
||||
_view->NonJitteredProjection = _prevNonJitteredProjection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ public:
|
||||
/// </summary>
|
||||
API_FIELD() bool IsCullingDisabled = false;
|
||||
|
||||
/// <summary>
|
||||
/// True if TAA has been resolved when rendering view and frame doesn't contain jitter anymore. Rendering geometry after this point should not use jitter anymore (eg. editor gizmos or custom geometry as overlay).
|
||||
/// </summary>
|
||||
API_FIELD() bool IsTaaResolved = false;
|
||||
|
||||
/// <summary>
|
||||
/// The static flags mask used to hide objects that don't have a given static flags. Eg. use StaticFlags::Lightmap to render only objects that can use lightmap.
|
||||
/// </summary>
|
||||
@@ -160,7 +165,7 @@ public:
|
||||
API_FIELD() DEPRECATED float ShadowModelLODDistanceFactor = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The Temporal Anti-Aliasing jitter frame index.
|
||||
/// Temporal Anti-Aliasing jitter frame index.
|
||||
/// </summary>
|
||||
API_FIELD() int32 TaaFrameIndex = 0;
|
||||
|
||||
@@ -261,6 +266,11 @@ public:
|
||||
RenderView& operator=(const RenderView& other) = default;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
|
||||
/// <summary>
|
||||
/// Updates the cached data for the view (inverse matrices, etc.).
|
||||
/// </summary>
|
||||
void UpdateCachedData();
|
||||
|
||||
// Set up view with custom params
|
||||
// @param viewProjection View * Projection matrix
|
||||
void SetUp(const Matrix& viewProjection);
|
||||
@@ -344,3 +354,15 @@ public:
|
||||
world.M43 -= Origin.Z;
|
||||
}
|
||||
};
|
||||
|
||||
// Removes TAA jitter from the RenderView when drawing geometry after TAA has been resolved to prevent unwanted jittering.
|
||||
struct TaaJitterRemoveContext
|
||||
{
|
||||
private:
|
||||
RenderView* _view = nullptr;
|
||||
Matrix _prevProjection, _prevNonJitteredProjection;
|
||||
|
||||
public:
|
||||
TaaJitterRemoveContext(const RenderView& view);
|
||||
~TaaJitterRemoveContext();
|
||||
};
|
||||
|
||||
@@ -146,4 +146,7 @@ void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextu
|
||||
context->Draw(output);
|
||||
renderContext.Buffers->TemporalAA = outputHistory;
|
||||
}
|
||||
|
||||
// Mark TAA jitter as resolved for future drawing
|
||||
(bool&)renderContext.View.IsTaaResolved = true;
|
||||
}
|
||||
|
||||
@@ -652,6 +652,7 @@ void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsL
|
||||
const auto* batchesData = list.Batches.Get();
|
||||
const auto context = GPUDevice::Instance->GetMainContext();
|
||||
bool useInstancing = list.CanUseInstancing && CanUseInstancing(renderContext.View.Pass) && GPUDevice::Instance->Limits.HasInstancing;
|
||||
TaaJitterRemoveContext taaJitterRemove(renderContext.View);
|
||||
|
||||
// Clear SR slots to prevent any resources binding issues (leftovers from the previous passes)
|
||||
context->ResetSR();
|
||||
|
||||
@@ -612,7 +612,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
// Color Grading LUT generation
|
||||
auto colorGradingLUT = ColorGradingPass::Instance()->RenderLUT(renderContext);
|
||||
|
||||
// Post processing
|
||||
// Post-processing
|
||||
EyeAdaptationPass::Instance()->Render(renderContext, frameBuffer);
|
||||
PostProcessingPass::Instance()->Render(renderContext, frameBuffer, tempBuffer, colorGradingLUT);
|
||||
RenderTargetPool::Release(colorGradingLUT);
|
||||
|
||||
Reference in New Issue
Block a user