Fix env probes far from origin

This commit is contained in:
Wojtek Figat
2022-07-04 20:22:26 +02:00
parent 3070493729
commit 8da4e546da
5 changed files with 15 additions and 11 deletions

View File

@@ -76,10 +76,11 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set reflection probe data
EnvironmentProbe* probe = nullptr;
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
const Vector3 drawCallOrigin = drawCall.World.GetTranslation() + view.Origin;
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
{
const auto p = cache->EnvironmentProbes[i];
if (p->GetSphere().Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
if (p->GetSphere().Contains(drawCallOrigin) != ContainmentType::Disjoint)
{
probe = p;
break;
@@ -87,7 +88,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
}
if (probe && probe->GetProbe())
{
probe->SetupProbeData(&data.EnvironmentProbe);
probe->SetupProbeData(params.RenderContext, &data.EnvironmentProbe);
const auto texture = probe->GetProbe()->GetTexture();
context->BindSR(envProbeShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
}

View File

@@ -44,10 +44,10 @@ float EnvironmentProbe::GetScaledRadius() const
return _radius * _transform.Scale.MaxValue();
}
void EnvironmentProbe::SetupProbeData(ProbeData* data) const
void EnvironmentProbe::SetupProbeData(const RenderContext& renderContext, ProbeData* data) const
{
const float radius = GetScaledRadius();
data->Data0 = Float4(GetPosition(), 0); // TODO: large-worlds
data->Data0 = Float4(GetPosition() - renderContext.View.Origin, 0);
data->Data1 = Float4(radius, 1.0f / radius, Brightness, 0);
}

View File

@@ -89,8 +89,9 @@ public:
/// <summary>
/// Setup probe data structure
/// </summary>
/// <param name="data">Rendering context</param>
/// <param name="data">Packed probe data to set</param>
void SetupProbeData(struct ProbeData* data) const;
void SetupProbeData(const RenderContext& renderContext, struct ProbeData* data) const;
/// <summary>
/// Gets the custom probe (null if using baked one or none).

View File

@@ -12,6 +12,7 @@
#include "Engine/Level/Actors/EnvironmentProbe.h"
#include "Engine/Level/Actors/SkyLight.h"
#include "Engine/Level/SceneQuery.h"
#include "Engine/Level/LargeWorlds.h"
#include "Engine/ContentExporters/AssetExporters.h"
#include "Engine/Serialization/FileWriteStream.h"
#include "Engine/Engine/Time.h"
@@ -430,12 +431,11 @@ bool fixFarPlaneTreeExecute(Actor* actor, const Vector3& position, float& farPla
if (auto* pointLight = dynamic_cast<PointLight*>(actor))
{
const Real dst = Vector3::Distance(pointLight->GetPosition(), position) + pointLight->GetScaledRadius();
if (dst > farPlane)
if (dst > farPlane && dst * 0.5f < farPlane)
{
farPlane = (float)dst;
}
}
return true;
}
@@ -480,7 +480,8 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
SceneQuery::TreeExecute<const Vector3&, float&>(f, position, farPlane);
// Setup view
_task->View.SetUpCube(nearPlane, farPlane, position);
LargeWorlds::UpdateOrigin(_task->View.Origin, position);
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
}
else if (_current.Type == EntryType::SkyLight)
{
@@ -494,7 +495,8 @@ void ProbesRenderer::onRender(RenderTask* task, GPUContext* context)
// TODO: use setLowerHemisphereToBlack feature for SkyLight?
// Setup view
_task->View.SetUpCube(nearPlane, farPlane, position);
LargeWorlds::UpdateOrigin(_task->View.Origin, position);
_task->View.SetUpCube(nearPlane, farPlane, position - _task->View.Origin);
}
// Disable actor during baking (it cannot influence own results)

View File

@@ -415,7 +415,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
if (!probe->HasProbeLoaded())
continue;
float probeRadius = probe->GetScaledRadius();
Vector3 probePosition = probe->GetPosition(); // TODO: large-worlds
Float3 probePosition = probe->GetPosition() - renderContext.View.Origin;
// Get distance from view center to light center less radius (check if view is inside a sphere)
const float sphereModelScale = 2.0f;
@@ -430,7 +430,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
Matrix::Multiply(world, view.ViewProjection(), wvp);
// Pack probe properties buffer
probe->SetupProbeData(&data.PData);
probe->SetupProbeData(renderContext, &data.PData);
Matrix::Transpose(wvp, data.WVP);
// Render reflections