Optimize SSAO rendering with depth bounds and half-res depth buffer
This commit is contained in:
@@ -22,6 +22,7 @@ void AmbientOcclusionSettings::BlendWith(AmbientOcclusionSettings& other, float
|
||||
BLEND_FLOAT(Radius);
|
||||
BLEND_FLOAT(FadeOutDistance);
|
||||
BLEND_FLOAT(FadeDistance);
|
||||
BLEND_ENUM(DepthResolution);
|
||||
}
|
||||
|
||||
void GlobalIlluminationSettings::BlendWith(GlobalIlluminationSettings& other, float weight)
|
||||
|
||||
@@ -217,10 +217,15 @@ API_ENUM(Attributes="Flags") enum class AmbientOcclusionSettingsOverride : int32
|
||||
/// </summary>
|
||||
FadeDistance = 1 << 5,
|
||||
|
||||
/// <summary>
|
||||
/// Overrides <see cref="AmbientOcclusionSettings.DepthResolution"/> property.
|
||||
/// </summary>
|
||||
DepthResolution = 1 << 6,
|
||||
|
||||
/// <summary>
|
||||
/// All properties.
|
||||
/// </summary>
|
||||
All = Enabled | Intensity | Power | Radius | FadeOutDistance | FadeDistance,
|
||||
All = Enabled | Intensity | Power | Radius | FadeOutDistance | FadeDistance | DepthResolution,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -274,6 +279,12 @@ API_STRUCT() struct FLAXENGINE_API AmbientOcclusionSettings : ISerializable
|
||||
API_FIELD(Attributes="Limit(0.0f), EditorOrder(5), PostProcessSetting((int)AmbientOcclusionSettingsOverride.FadeDistance)")
|
||||
float FadeDistance = 500.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The depth buffer downscale option to optimize rendering performance. Full gives better quality, but half improves performance.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(6), PostProcessSetting((int)AmbientOcclusionSettingsOverride.DepthResolution)")
|
||||
ResolutionMode DepthResolution = ResolutionMode::Half;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Blends the settings using given weight.
|
||||
|
||||
@@ -83,16 +83,17 @@ GPUTexture* RenderBuffers::RequestHalfResDepth(GPUContext* context)
|
||||
if (LastFrameHalfResDepth == currentFrame)
|
||||
return HalfResDepth;
|
||||
|
||||
const int32 halfDepthWidth = _width / 2;
|
||||
const int32 halfDepthHeight = _height / 2;
|
||||
const int32 halfDepthWidth = (_width + 1) / 2;
|
||||
const int32 halfDepthHeight = (_height + 1) / 2;
|
||||
const PixelFormat halfDepthFormat = GPU_DEPTH_BUFFER_PIXEL_FORMAT;
|
||||
auto tempDesc = GPUTextureDescription::New2D(halfDepthWidth, halfDepthHeight, halfDepthFormat);
|
||||
if (EnumHasAnyFlags(DepthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView))
|
||||
tempDesc.Flags = GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil | GPUTextureFlags::ReadOnlyDepthView;
|
||||
|
||||
LastFrameHalfResDepth = currentFrame;
|
||||
if (HalfResDepth == nullptr)
|
||||
{
|
||||
// Missing buffer
|
||||
auto tempDesc = GPUTextureDescription::New2D(halfDepthWidth, halfDepthHeight, halfDepthFormat);
|
||||
tempDesc.Flags = GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil;
|
||||
HalfResDepth = RenderTargetPool::Get(tempDesc);
|
||||
RENDER_TARGET_POOL_SET_NAME(HalfResDepth, "HalfResDepth");
|
||||
}
|
||||
@@ -100,8 +101,6 @@ GPUTexture* RenderBuffers::RequestHalfResDepth(GPUContext* context)
|
||||
{
|
||||
// Wrong size buffer
|
||||
RenderTargetPool::Release(HalfResDepth);
|
||||
auto tempDesc = GPUTextureDescription::New2D(halfDepthWidth, halfDepthHeight, halfDepthFormat);
|
||||
tempDesc.Flags = GPUTextureFlags::ShaderResource | GPUTextureFlags::DepthStencil;
|
||||
HalfResDepth = RenderTargetPool::Get(tempDesc);
|
||||
RENDER_TARGET_POOL_SET_NAME(HalfResDepth, "HalfResDepth");
|
||||
}
|
||||
|
||||
@@ -695,6 +695,15 @@ Float2 RenderTools::GetDepthBounds(const RenderView& view, const OrientedBoundin
|
||||
return GetDepthBounds(view, Span<Float3>(corners, 8));
|
||||
}
|
||||
|
||||
float RenderTools::GetDepthBounds(const RenderView& view, const Float3& point)
|
||||
{
|
||||
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
|
||||
return Math::Clamp(depth, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Float3 RenderTools::GetColorQuantizationError(PixelFormat format)
|
||||
{
|
||||
Float3 mantissaBits;
|
||||
|
||||
@@ -148,6 +148,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 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).
|
||||
|
||||
Reference in New Issue
Block a user