Fix half res depth buffer regression from 192d3d1a8e

This commit is contained in:
Wojtek Figat
2026-01-20 12:01:03 +01:00
parent 192d3d1a8e
commit c7c1bbe35f
9 changed files with 303 additions and 339 deletions

View File

@@ -1802,7 +1802,7 @@ API_STRUCT() struct FLAXENGINE_API ScreenSpaceReflectionsSettings : ISerializabl
/// The raycast resolution. Full gives better quality, but half improves performance.
/// </summary>
API_FIELD(Attributes="EditorOrder(25), PostProcessSetting((int)ScreenSpaceReflectionsSettingsOverride.ResolvePassResolution)")
ResolutionMode ResolvePassResolution = ResolutionMode::Full;
ResolutionMode ResolvePassResolution = ResolutionMode::Half;
/// <summary>
/// The number of rays used to resolve the reflection color. Higher values provide better quality but reduce effect performance. Use value of 1 for the best performance at cost of quality.

View File

@@ -2,6 +2,7 @@
#include "RenderBuffers.h"
#include "Engine/Core/Config/GraphicsSettings.h"
#include "RenderTools.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPULimits.h"
#include "Engine/Graphics/RenderTargetPool.h"
@@ -83,8 +84,8 @@ GPUTexture* RenderBuffers::RequestHalfResDepth(GPUContext* context)
if (LastFrameHalfResDepth == currentFrame)
return HalfResDepth;
const int32 halfDepthWidth = (_width + 1) / 2;
const int32 halfDepthHeight = (_height + 1) / 2;
const int32 halfDepthWidth = RenderTools::GetResolution(_width, ResolutionMode::Half);
const int32 halfDepthHeight = RenderTools::GetResolution(_height, ResolutionMode::Half);
const PixelFormat halfDepthFormat = GPU_DEPTH_BUFFER_PIXEL_FORMAT;
auto tempDesc = GPUTextureDescription::New2D(halfDepthWidth, halfDepthHeight, halfDepthFormat);
if (EnumHasAnyFlags(DepthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView))

View File

@@ -695,12 +695,12 @@ Float2 RenderTools::GetDepthBounds(const RenderView& view, const OrientedBoundin
return GetDepthBounds(view, Span<Float3>(corners, 8));
}
float RenderTools::GetDepthBounds(const RenderView& view, const Float3& point)
float RenderTools::GetDepthBounds(const RenderView& view, const Float3& point, bool near)
{
const Float4 pointClip = Matrix::TransformPosition(view.ViewProjection(), Float4(point, 1.0));
float depth = pointClip.Z / pointClip.W;
if (depth >= 1.0f)
depth = 0.0f; // Point is behind the view
depth = near ? 0.0f : 1.0f; // Point is behind the view
return Math::Clamp(depth, 0.0f, 1.0f);
}

View File

@@ -34,6 +34,12 @@ public:
return Math::FloatSelect(worldMatrix.RotDeterminant(), 1, -1);
}
template<typename ResolutionMode>
FORCE_INLINE static int32 GetResolution(int32 base, ResolutionMode mode)
{
return Math::DivideAndRoundUp(base, (int32)mode);
}
/// <summary>
/// Computes the feature level for the given shader profile.
/// </summary>
@@ -148,7 +154,7 @@ public:
static Float2 GetDepthBounds(const RenderView& view, const Span<Float3>& points);
static Float2 GetDepthBounds(const RenderView& view, const BoundingBox& bounds);
static Float2 GetDepthBounds(const RenderView& view, const OrientedBoundingBox& bounds);
static float GetDepthBounds(const RenderView& view, const Float3& point);
static float GetDepthBounds(const RenderView& view, const Float3& point, bool near);
static constexpr float DepthBoundMaxBackground = 1.0f - 0.0000001f; // Skip background/sky pixels from shading
// Calculates error for a given render target format to reduce floating-point precision artifacts via QuantizeColor (from Noise.hlsl).