Add option to always render Global SDF
This commit is contained in:
@@ -62,11 +62,17 @@ public:
|
||||
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
|
||||
bool AllowCSMBlending = false;
|
||||
|
||||
/// <summary>
|
||||
/// If checked, enables Global SDF rendering. This can be used in materials, shaders, and particles.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), EditorDisplay(\"Global SDF\")")
|
||||
bool EnableGlobalSDF = false;
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// If checked, the 'Generate SDF' option will be checked on model import options by default. Use it if your project uses Global SDF (eg. for Global Illumination or particles).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), EditorDisplay(\"Global SDF\")")
|
||||
API_FIELD(Attributes="EditorOrder(2010), EditorDisplay(\"Global SDF\")")
|
||||
bool GenerateSDFOnModelImport = false;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -150,6 +150,17 @@ public:
|
||||
return _viewport;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T* FindCustomBuffer(const StringView& name) const
|
||||
{
|
||||
for (CustomBuffer* e : CustomBuffers)
|
||||
{
|
||||
if (e->Name == name)
|
||||
return (const T*)e;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* GetCustomBuffer(const StringView& name)
|
||||
{
|
||||
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
GPUTexture* CascadeMips[4] = {};
|
||||
Vector3 Positions[4];
|
||||
HashSet<RasterizeChunkKey> NonEmptyChunks[4];
|
||||
GlobalSignDistanceFieldPass::BindingData Result;
|
||||
|
||||
~GlobalSignDistanceFieldCustomBuffer()
|
||||
{
|
||||
@@ -212,6 +213,17 @@ void GlobalSignDistanceFieldPass::Dispose()
|
||||
ChunksCache.SetCapacity(0);
|
||||
}
|
||||
|
||||
bool GlobalSignDistanceFieldPass::Get(const RenderBuffers* buffers, BindingData& result)
|
||||
{
|
||||
auto* sdfData = buffers->FindCustomBuffer<GlobalSignDistanceFieldCustomBuffer>(TEXT("GlobalSignDistanceField"));
|
||||
if (sdfData && sdfData->LastFrameUsed == Engine::FrameCount)
|
||||
{
|
||||
result = sdfData->Result;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContext* context, BindingData& result)
|
||||
{
|
||||
// Skip if not supported
|
||||
@@ -221,6 +233,16 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
return true;
|
||||
auto& sdfData = *renderContext.Buffers->GetCustomBuffer<GlobalSignDistanceFieldCustomBuffer>(TEXT("GlobalSignDistanceField"));
|
||||
|
||||
// Skip if already done in the current frame
|
||||
const auto currentFrame = Engine::FrameCount;
|
||||
if (sdfData.LastFrameUsed == currentFrame)
|
||||
{
|
||||
result = sdfData.Result;
|
||||
return false;
|
||||
}
|
||||
|
||||
PROFILE_GPU_CPU("Global SDF");
|
||||
|
||||
// TODO: configurable via graphics settings
|
||||
const int32 resolution = 256;
|
||||
const int32 mipFactor = 4;
|
||||
@@ -229,12 +251,6 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
const float distanceExtent = 2500.0f;
|
||||
const float cascadesDistances[] = { distanceExtent, distanceExtent * 2.0f, distanceExtent * 4.0f, distanceExtent * 8.0f };
|
||||
|
||||
// Skip if already done in the current frame
|
||||
const auto currentFrame = Engine::FrameCount;
|
||||
if (sdfData.LastFrameUsed != currentFrame)
|
||||
{
|
||||
PROFILE_GPU_CPU("Global SDF");
|
||||
|
||||
// Initialize buffers
|
||||
sdfData.LastFrameUsed = currentFrame;
|
||||
auto desc = GPUTextureDescription::New3D(resolution, resolution, resolution, GLOBAL_SDF_FORMAT, GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess, 1);
|
||||
@@ -459,7 +475,6 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
context->ResetSR();
|
||||
context->FlushState();
|
||||
}
|
||||
}
|
||||
|
||||
// Copy results
|
||||
static_assert(ARRAY_COUNT(result.Cascades) == ARRAY_COUNT(sdfData.Cascades), "Invalid cascades count.");
|
||||
@@ -476,6 +491,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
result.GlobalSDF.CascadeVoxelSize.Raw[cascade] = voxelSize;
|
||||
}
|
||||
result.GlobalSDF.Resolution = (float)resolution;
|
||||
sdfData.Result = result;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,14 @@ private:
|
||||
BoundingBox _cascadeBounds;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the Global SDF (only if enabled in Graphics Settings).
|
||||
/// </summary>
|
||||
/// <param name="buffers">The rendering context buffers.</param>
|
||||
/// <param name="result">The result Global SDF data for binding to the shaders.</param>
|
||||
/// <returns>True if there is no valid Global SDF rendered during this frame, otherwise false.</returns>
|
||||
bool Get(const RenderBuffers* buffers, BindingData& result);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the Global SDF.
|
||||
/// </summary>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "AntiAliasing/SMAA.h"
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Level/Level.h"
|
||||
#include "Engine/Core/Config/GraphicsSettings.h"
|
||||
#if USE_EDITOR
|
||||
#include "Editor/Editor.h"
|
||||
#include "Editor/QuadOverdrawPass.h"
|
||||
@@ -289,6 +290,7 @@ void Renderer::DrawPostFxMaterial(GPUContext* context, const RenderContext& rend
|
||||
void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
|
||||
{
|
||||
auto context = GPUDevice::Instance->GetMainContext();
|
||||
auto* graphicsSettings = GraphicsSettings::Get();
|
||||
auto& view = renderContext.View;
|
||||
ASSERT(renderContext.Buffers && renderContext.Buffers->GetWidth() > 0);
|
||||
|
||||
@@ -338,6 +340,13 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Global SDF rendering (can be used by materials later on)
|
||||
if (graphicsSettings->EnableGlobalSDF)
|
||||
{
|
||||
GlobalSignDistanceFieldPass::BindingData bindingData;
|
||||
GlobalSignDistanceFieldPass::Instance()->Render(renderContext, context, bindingData);
|
||||
}
|
||||
|
||||
// Fill GBuffer
|
||||
GBufferPass::Instance()->Fill(renderContext, lightBuffer->View());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user