Add real-time environment probes support
This commit is contained in:
@@ -157,7 +157,8 @@ void ProbesRenderer::Bake(EnvironmentProbe* probe, float timeout)
|
||||
_probesToBake.Add(e);
|
||||
|
||||
// Fire event
|
||||
OnRegisterBake(e);
|
||||
if (e.UseTextureData())
|
||||
OnRegisterBake(e);
|
||||
}
|
||||
|
||||
void ProbesRenderer::Bake(SkyLight* probe, float timeout)
|
||||
@@ -183,7 +184,21 @@ void ProbesRenderer::Bake(SkyLight* probe, float timeout)
|
||||
_probesToBake.Add(e);
|
||||
|
||||
// Fire event
|
||||
OnRegisterBake(e);
|
||||
if (e.UseTextureData())
|
||||
OnRegisterBake(e);
|
||||
}
|
||||
|
||||
bool ProbesRenderer::Entry::UseTextureData() const
|
||||
{
|
||||
if (Type == EntryType::EnvProbe && Actor)
|
||||
{
|
||||
switch (Actor.As<EnvironmentProbe>()->UpdateMode)
|
||||
{
|
||||
case EnvironmentProbe::ProbeUpdateMode::Realtime:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 ProbesRenderer::Entry::GetResolution() const
|
||||
@@ -358,7 +373,7 @@ void ProbesRendererService::Update()
|
||||
texture = _probe;
|
||||
break;
|
||||
}
|
||||
ASSERT(texture);
|
||||
ASSERT(texture && _current.UseTextureData());
|
||||
auto taskB = New<DownloadProbeTask>(texture, _current);
|
||||
auto taskA = texture->DownloadDataAsync(taskB->GetData());
|
||||
if (taskA == nullptr)
|
||||
@@ -462,7 +477,6 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
if (_current.Type == EntryType::EnvProbe)
|
||||
{
|
||||
auto envProbe = (EnvironmentProbe*)_current.Actor.Get();
|
||||
LOG(Info, "Updating Env probe '{0}' (resolution: {1})...", envProbe->ToString(), probeResolution);
|
||||
Vector3 position = envProbe->GetPosition();
|
||||
float radius = envProbe->GetScaledRadius();
|
||||
float nearPlane = Math::Max(0.1f, envProbe->CaptureNearPlane);
|
||||
@@ -479,7 +493,6 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
else if (_current.Type == EntryType::SkyLight)
|
||||
{
|
||||
auto skyLight = (SkyLight*)_current.Actor.Get();
|
||||
LOG(Info, "Updating sky light '{0}' (resolution: {1})...", skyLight->ToString(), probeResolution);
|
||||
Vector3 position = skyLight->GetPosition();
|
||||
float nearPlane = 10.0f;
|
||||
float farPlane = Math::Max(nearPlane + 1000.0f, skyLight->SkyDistanceThreshold * 2.0f);
|
||||
@@ -575,6 +588,19 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
|
||||
// Mark as rendered
|
||||
_updateFrameNumber = Engine::FrameCount;
|
||||
_task->Enabled = false;
|
||||
|
||||
// Real-time probes don't use TextureData (for streaming) but copy generated probe directly to GPU memory
|
||||
if (!_current.UseTextureData())
|
||||
{
|
||||
if (_current.Type == EntryType::EnvProbe && _current.Actor)
|
||||
{
|
||||
_current.Actor.As<EnvironmentProbe>()->SetProbeData(context, _probe);
|
||||
}
|
||||
|
||||
// Clear flag
|
||||
_updateFrameNumber = 0;
|
||||
_current.Type = EntryType::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
Timeout = other.Timeout;
|
||||
}
|
||||
|
||||
bool UseTextureData() const;
|
||||
int32 GetResolution() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -412,8 +412,6 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
||||
{
|
||||
// Cache data
|
||||
auto probe = renderContext.List->EnvironmentProbes[probeIndex];
|
||||
if (!probe->HasProbeLoaded())
|
||||
continue;
|
||||
float probeRadius = probe->GetScaledRadius();
|
||||
Float3 probePosition = probe->GetPosition() - renderContext.View.Origin;
|
||||
|
||||
@@ -436,7 +434,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
||||
// Render reflections
|
||||
context->UpdateCB(cb, &data);
|
||||
context->BindCB(0, cb);
|
||||
context->BindSR(4, probe->GetProbe()->GetTexture());
|
||||
context->BindSR(4, probe->GetProbe());
|
||||
|
||||
context->SetState(isViewInside ? _psProbeInverted : _psProbeNormal);
|
||||
_sphereModel->Render(context);
|
||||
|
||||
Reference in New Issue
Block a user