Add Graphics.GI.GetConvergence to use GI bounce progress for game loading screens/fades
This commit is contained in:
@@ -128,6 +128,16 @@ public:
|
||||
API_FIELD() static bool ColorGradingVolumeLUT;
|
||||
};
|
||||
|
||||
// Global Illumination rendering configuration and API.
|
||||
API_CLASS(Static, Attributes="DebugCommand") class FLAXENGINE_API GI
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(GI);
|
||||
|
||||
// Gets the normalized 0-1 progress of the Global Illumination lighting bounces convergence (0 = no GI, 1 = full GI convergence). Can be used to continue displaying loading screen after scene load to ensure indirect lighting has been evaluated. Non-zero value means GI has started to be calculated.
|
||||
API_FUNCTION(Attributes="DebugCommand(Hide=true)")
|
||||
static float GetConvergence(const RenderBuffers* buffers);
|
||||
};
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Disposes the device.
|
||||
|
||||
@@ -105,6 +105,7 @@ public:
|
||||
int32 CascadesCount = 0;
|
||||
int32 ProbeRaysCount = 0;
|
||||
int32 ProbesCountTotal = 0;
|
||||
int32 FramesSinceClear = 0;
|
||||
Int3 ProbeCounts = Int3::Zero;
|
||||
GPUTexture* ProbesTrace = nullptr; // Probes ray tracing: (RGB: hit radiance, A: hit distance)
|
||||
GPUTexture* ProbesData = nullptr; // Probes data: (RGB: probe-space offset, A: state/data)
|
||||
@@ -148,6 +149,12 @@ public:
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
bool IsFresh() const
|
||||
{
|
||||
// Allow to use data from the previous frame (eg. particles in Editor using the Editor viewport in Game viewport - Game render task runs first)
|
||||
return LastFrameUsed + 1 >= Engine::FrameCount;
|
||||
}
|
||||
};
|
||||
|
||||
void CalculateVolumeRandomRotation(Matrix3x3& matrix)
|
||||
@@ -182,6 +189,20 @@ void CalculateVolumeRandomRotation(Matrix3x3& matrix)
|
||||
matrix.M33 = 1.0f - 2.0f * u3;
|
||||
}
|
||||
|
||||
float Graphics::GI::GetConvergence(const RenderBuffers* buffers)
|
||||
{
|
||||
float result = 0;
|
||||
auto* ddgiData = buffers ? buffers->FindCustomBuffer<DDGICustomBuffer>(TEXT("DDGI")) : nullptr;
|
||||
if (ddgiData && ddgiData->IsFresh())
|
||||
{
|
||||
// This depends on scene complexity and lighting conditions so fake it
|
||||
// Potentially could use probes variance readback to estimate it but that's probably too much trouble
|
||||
constexpr int32 framesToCoverage = 30;
|
||||
result = Math::Saturate((float)ddgiData->FramesSinceClear / framesToCoverage + 0.01f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String DynamicDiffuseGlobalIlluminationPass::ToString() const
|
||||
{
|
||||
return TEXT("DynamicDiffuseGlobalIlluminationPass");
|
||||
@@ -286,7 +307,7 @@ void DynamicDiffuseGlobalIlluminationPass::Dispose()
|
||||
bool DynamicDiffuseGlobalIlluminationPass::Get(const RenderBuffers* buffers, BindingData& result)
|
||||
{
|
||||
auto* ddgiData = buffers ? buffers->FindCustomBuffer<DDGICustomBuffer>(TEXT("DDGI")) : nullptr;
|
||||
if (ddgiData && ddgiData->LastFrameUsed + 1 >= Engine::FrameCount) // Allow to use data from the previous frame (eg. particles in Editor using the Editor viewport in Game viewport - Game render task runs first)
|
||||
if (ddgiData && ddgiData->IsFresh())
|
||||
{
|
||||
result = ddgiData->Result;
|
||||
return false;
|
||||
@@ -450,8 +471,10 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont
|
||||
#if DDGI_DEBUG_INSTABILITY
|
||||
context->ClearUA(ddgiData.ProbesInstability, Float4::Zero);
|
||||
#endif
|
||||
ddgiData.FramesSinceClear = 0;
|
||||
}
|
||||
ddgiData.LastFrameUsed = Engine::FrameCount;
|
||||
ddgiData.FramesSinceClear++;
|
||||
|
||||
// Calculate which cascades should be updated this frame
|
||||
const uint64 cascadeFrequencies[] = { 2, 3, 5, 7 };
|
||||
@@ -725,7 +748,7 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
||||
if (auto* sceneTask = ScriptingObject::Cast<SceneRenderTask>(task))
|
||||
{
|
||||
auto* sceneTaskDDGI = sceneTask->Buffers ? sceneTask->Buffers->FindCustomBuffer<DDGICustomBuffer>(TEXT("DDGI")) : nullptr;
|
||||
if (sceneTaskDDGI && sceneTaskDDGI->LastFrameUsed + 1 >= Engine::FrameCount)
|
||||
if (sceneTaskDDGI && sceneTaskDDGI->IsFresh())
|
||||
{
|
||||
// Reuse DDGI from this task
|
||||
renderBuffers = sceneTask->Buffers;
|
||||
|
||||
Reference in New Issue
Block a user