Fix env probes far from origin
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user