Add RenderSetup and allow customizing it by gameplay and postfx
This commit is contained in:
@@ -44,6 +44,13 @@ public:
|
||||
return GetEnabled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pre-rendering event called before scene rendering begin. Can be used to perform custom rendering or customize render view/setup.
|
||||
/// </summary>
|
||||
virtual void PreRender(GPUContext* context, RenderContext& renderContext)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs custom postFx rendering.
|
||||
/// </summary>
|
||||
|
||||
@@ -371,6 +371,11 @@ public:
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
virtual void OnPostRender(GPUContext* context, RenderContext& renderContext);
|
||||
|
||||
/// <summary>
|
||||
/// The action called before any rendering to override/customize setup RenderSetup inside RenderList. Can be used to enable eg. Motion Vectors rendering.
|
||||
/// </summary>
|
||||
Delegate<RenderContext&> SetupRender;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the rendering render task viewport (before upsampling).
|
||||
|
||||
@@ -18,7 +18,7 @@ void RenderView::Prepare(RenderContext& renderContext)
|
||||
// Check if use TAA (need to modify the projection matrix)
|
||||
Float2 taaJitter;
|
||||
NonJitteredProjection = Projection;
|
||||
if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
|
||||
if (renderContext.List->Setup.UseTemporalAAJitter)
|
||||
{
|
||||
// Move to the next frame
|
||||
const int MaxSampleCount = 8;
|
||||
|
||||
@@ -63,11 +63,6 @@ void TAA::Dispose()
|
||||
_shader = nullptr;
|
||||
}
|
||||
|
||||
bool TAA::NeedMotionVectors(const RenderContext& renderContext)
|
||||
{
|
||||
return renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing;
|
||||
}
|
||||
|
||||
void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextureView* output)
|
||||
{
|
||||
auto context = GPUDevice::Instance->GetMainContext();
|
||||
|
||||
@@ -16,14 +16,6 @@ private:
|
||||
GPUPipelineState* _psTAA;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Determinates whenever this pass requires motion vectors rendering.
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <returns>True if need to render motion vectors, otherwise false.</returns>
|
||||
static bool NeedMotionVectors(const RenderContext& renderContext);
|
||||
|
||||
/// <summary>
|
||||
/// Performs AA pass rendering for the input task.
|
||||
/// </summary>
|
||||
|
||||
@@ -480,7 +480,7 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
||||
auto& cascade = ddgiData.Cascades[cascadeIndex];
|
||||
data.ProbeScrollClears[cascadeIndex] = Int4(cascade.ProbeScrollClears, 0);
|
||||
}
|
||||
if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
|
||||
if (renderContext.List->Setup.UseTemporalAAJitter)
|
||||
{
|
||||
// Use temporal offset in the dithering factor (gets cleaned out by TAA)
|
||||
const float time = Time::Draw.UnscaledTime.GetTotalSeconds();
|
||||
|
||||
@@ -162,7 +162,7 @@ void MotionBlurPass::RenderMotionVectors(RenderContext& renderContext)
|
||||
const int32 motionVectorsHeight = screenHeight / static_cast<int32>(settings.MotionVectorsResolution);
|
||||
|
||||
// Ensure to have valid data
|
||||
if (!Renderer::NeedMotionVectors(renderContext) || checkIfSkipPass())
|
||||
if (!renderContext.List->Setup.UseMotionVectors || checkIfSkipPass())
|
||||
{
|
||||
// Skip pass (just clear motion vectors if texture is allocated)
|
||||
if (motionVectors->IsAllocated())
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "DrawCall.h"
|
||||
#include "RenderListBuffer.h"
|
||||
#include "RendererAllocation.h"
|
||||
#include "RenderSetup.h"
|
||||
|
||||
enum class StaticFlags;
|
||||
class RenderBuffers;
|
||||
@@ -363,6 +364,11 @@ public:
|
||||
/// </summary>
|
||||
Array<PostProcessEffect*> PostFx;
|
||||
|
||||
/// <summary>
|
||||
/// The renderer setup for the frame drawing.
|
||||
/// </summary>
|
||||
RenderSetup Setup;
|
||||
|
||||
/// <summary>
|
||||
/// The post process settings.
|
||||
/// </summary>
|
||||
|
||||
15
Source/Engine/Renderer/RenderSetup.h
Normal file
15
Source/Engine/Renderer/RenderSetup.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
|
||||
/// <summary>
|
||||
/// The utility container for rendering setup configuration. Allows to properly decide about using certain render features (eg. motion vectors, TAA jitter) before rendering happens.
|
||||
/// </summary>
|
||||
struct FLAXENGINE_API RenderSetup
|
||||
{
|
||||
RenderingUpscaleLocation UpscaleLocation = RenderingUpscaleLocation::AfterAntiAliasingPass;
|
||||
bool UseMotionVectors = false;
|
||||
bool UseTemporalAAJitter = false;
|
||||
};
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/PostProcessEffect.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "GBufferPass.h"
|
||||
#include "ForwardPass.h"
|
||||
@@ -224,19 +225,6 @@ void Renderer::Render(SceneRenderTask* task)
|
||||
RenderList::ReturnToPool(e.List);
|
||||
}
|
||||
|
||||
bool Renderer::NeedMotionVectors(const RenderContext& renderContext)
|
||||
{
|
||||
const int32 screenWidth = renderContext.Buffers->GetWidth();
|
||||
const int32 screenHeight = renderContext.Buffers->GetHeight();
|
||||
if (screenWidth < 16 || screenHeight < 16 || renderContext.Task->IsCameraCut)
|
||||
return false;
|
||||
MotionBlurSettings& motionBlurSettings = renderContext.List->Settings.MotionBlur;
|
||||
return ((renderContext.View.Flags & ViewFlags::MotionBlur) != 0 && motionBlurSettings.Enabled && motionBlurSettings.Scale > ZeroTolerance) ||
|
||||
renderContext.View.Mode == ViewMode::MotionVectors ||
|
||||
ScreenSpaceReflectionsPass::NeedMotionVectors(renderContext) ||
|
||||
TAA::NeedMotionVectors(renderContext);
|
||||
}
|
||||
|
||||
void Renderer::DrawSceneDepth(GPUContext* context, SceneRenderTask* task, GPUTexture* output, const Array<Actor*>& customActors)
|
||||
{
|
||||
CHECK(context && task && output && output->IsDepthStencil());
|
||||
@@ -314,20 +302,45 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
aaMode = AntialiasingMode::None; // TODO: support TAA in ortho projection (see RenderView::Prepare to jitter projection matrix better)
|
||||
renderContext.List->Settings.AntiAliasing.Mode = aaMode;
|
||||
|
||||
// Initialize setup
|
||||
RenderSetup& setup = renderContext.List->Setup;
|
||||
{
|
||||
PROFILE_CPU_NAMED("Setup");
|
||||
if (renderContext.View.Origin != renderContext.View.PrevOrigin)
|
||||
renderContext.Task->CameraCut(); // Cut any temporal effects on rendering origin change
|
||||
const int32 screenWidth = renderContext.Buffers->GetWidth();
|
||||
const int32 screenHeight = renderContext.Buffers->GetHeight();
|
||||
setup.UpscaleLocation = renderContext.Task->UpscaleLocation;
|
||||
if (screenWidth < 16 || screenHeight < 16 || renderContext.Task->IsCameraCut)
|
||||
setup.UseMotionVectors = false;
|
||||
else
|
||||
{
|
||||
const MotionBlurSettings& motionBlurSettings = renderContext.List->Settings.MotionBlur;
|
||||
const ScreenSpaceReflectionsSettings ssrSettings = renderContext.List->Settings.ScreenSpaceReflections;
|
||||
setup.UseMotionVectors = ((renderContext.View.Flags & ViewFlags::MotionBlur) != 0 && motionBlurSettings.Enabled && motionBlurSettings.Scale > ZeroTolerance) ||
|
||||
renderContext.View.Mode == ViewMode::MotionVectors ||
|
||||
(ssrSettings.TemporalEffect && renderContext.View.Flags & ViewFlags::SSR) ||
|
||||
renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing;
|
||||
}
|
||||
setup.UseTemporalAAJitter = aaMode == AntialiasingMode::TemporalAntialiasing;
|
||||
|
||||
// Customize setup (by postfx or custom gameplay effects)
|
||||
renderContext.Task->SetupRender(renderContext);
|
||||
for (PostProcessEffect* e : renderContext.List->PostFx)
|
||||
e->PreRender(context, renderContext);
|
||||
}
|
||||
|
||||
// Prepare
|
||||
renderContext.View.Prepare(renderContext);
|
||||
if (renderContext.View.Origin != renderContext.View.PrevOrigin)
|
||||
renderContext.Task->CameraCut(); // Cut any temporal effects on rendering origin change
|
||||
renderContext.Buffers->Prepare();
|
||||
|
||||
// Build batch of render contexts (main view and shadow projections)
|
||||
const bool isGBufferDebug = GBufferPass::IsDebugView(renderContext.View.Mode);
|
||||
const bool needMotionVectors = Renderer::NeedMotionVectors(renderContext);
|
||||
{
|
||||
PROFILE_CPU_NAMED("Collect Draw Calls");
|
||||
|
||||
view.Pass = DrawPass::GBuffer | DrawPass::Forward | DrawPass::Distortion;
|
||||
if (needMotionVectors)
|
||||
if (setup.UseMotionVectors)
|
||||
view.Pass |= DrawPass::MotionVectors;
|
||||
renderContextBatch.GetMainContext() = renderContext; // Sync render context in batch with the current value
|
||||
|
||||
@@ -372,7 +385,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
renderContext.List->SortDrawCalls(renderContext, false, DrawCallsListType::GBufferNoDecals);
|
||||
renderContext.List->SortDrawCalls(renderContext, true, DrawCallsListType::Forward);
|
||||
renderContext.List->SortDrawCalls(renderContext, false, DrawCallsListType::Distortion);
|
||||
if (needMotionVectors)
|
||||
if (setup.UseMotionVectors)
|
||||
renderContext.List->SortDrawCalls(renderContext, false, DrawCallsListType::MotionVectors);
|
||||
for (int32 i = 1; i < renderContextBatch.Contexts.Count(); i++)
|
||||
{
|
||||
@@ -555,7 +568,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
|
||||
// Upscaling after scene rendering but before post processing
|
||||
bool useUpscaling = task->RenderingPercentage < 1.0f;
|
||||
const Viewport outputViewport = task->GetOutputViewport();
|
||||
if (useUpscaling && task->UpscaleLocation == RenderingUpscaleLocation::BeforePostProcessingPass)
|
||||
if (useUpscaling && setup.UpscaleLocation == RenderingUpscaleLocation::BeforePostProcessingPass)
|
||||
{
|
||||
useUpscaling = false;
|
||||
RenderTargetPool::Release(tempBuffer);
|
||||
|
||||
@@ -33,13 +33,6 @@ public:
|
||||
/// <param name="task">The scene rendering task.</param>
|
||||
static void Render(SceneRenderTask* task);
|
||||
|
||||
/// <summary>
|
||||
/// Determinates whenever any pass requires motion vectors rendering.
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <returns>True if need to render motion vectors, otherwise false.</returns>
|
||||
static bool NeedMotionVectors(const RenderContext& renderContext);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -55,12 +55,6 @@ PACK_STRUCT(struct Data
|
||||
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
|
||||
});
|
||||
|
||||
bool ScreenSpaceReflectionsPass::NeedMotionVectors(const RenderContext& renderContext)
|
||||
{
|
||||
auto& settings = renderContext.List->Settings.ScreenSpaceReflections;
|
||||
return settings.TemporalEffect && renderContext.View.Flags & ViewFlags::SSR;
|
||||
}
|
||||
|
||||
String ScreenSpaceReflectionsPass::ToString() const
|
||||
{
|
||||
return TEXT("ScreenSpaceReflectionsPass");
|
||||
|
||||
@@ -36,13 +36,6 @@ private:
|
||||
AssetReference<Texture> _preIntegratedGF;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Determinates whenever this pass requires motion vectors rendering.
|
||||
/// </summary>
|
||||
/// <param name="renderContext">The rendering context.</param>
|
||||
/// <returns>True if need to render motion vectors, otherwise false.</returns>
|
||||
static bool NeedMotionVectors(const RenderContext& renderContext);
|
||||
|
||||
/// <summary>
|
||||
/// Perform SSR rendering for the input task (blends reflections to given texture using alpha blending).
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user