Skip to content

Commit

Permalink
Hydrogent: use reverse depth buffer (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Jan 10, 2025
1 parent 7adae45 commit 90f7174
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 70 deletions.
3 changes: 2 additions & 1 deletion Hydrogent/include/HnRenderParam.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 Diligent Graphics LLC
* Copyright 2023-2025 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -52,6 +52,7 @@ class HnRenderParam final : public pxr::HdRenderParam
bool UseIndexPool = false;
bool AsyncShaderCompilation = false;
bool UseNativeStartVertex = false;
bool UseReverseDepth = false;
HN_MATERIAL_TEXTURES_BINDING_MODE TextureBindingMode = {};
float MetersPerUnit = 1.0f;
Uint64 GeometryLoadBudget = 0;
Expand Down
60 changes: 7 additions & 53 deletions Hydrogent/interface/Tasks/HnBeginFrameTask.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 Diligent Graphics LLC
* Copyright 2023-2025 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -73,52 +73,7 @@ struct HnBeginFrameTaskParams
};
RenderTargetFormats Formats;

struct RenderState
{
bool FrontFaceCCW = false;

float DepthBias = 0;
float SlopeScaledDepthBias = 0;
pxr::HdCompareFunction DepthFunc = pxr::HdCmpFuncLess;
bool DepthBiasEnabled = false;
bool DepthTestEnabled = true;
bool DepthClampEnabled = false;

pxr::HdCullStyle CullStyle = pxr::HdCullStyleBack;

pxr::HdCompareFunction StencilFunc = pxr::HdCmpFuncAlways;
int StencilRef = 0;
int StencilMask = 0xFF;
pxr::HdStencilOp StencilFailOp = pxr::HdStencilOpKeep;
pxr::HdStencilOp StencilZFailOp = pxr::HdStencilOpKeep;
pxr::HdStencilOp StencilZPassOp = pxr::HdStencilOpKeep;
bool StencilEnabled = false;

constexpr bool operator==(const RenderState& rhs) const
{
// clang-format off
return FrontFaceCCW == rhs.FrontFaceCCW &&
DepthBias == rhs.DepthBias &&
SlopeScaledDepthBias == rhs.SlopeScaledDepthBias &&
DepthFunc == rhs.DepthFunc &&
DepthBiasEnabled == rhs.DepthBiasEnabled &&
DepthTestEnabled == rhs.DepthTestEnabled &&
DepthClampEnabled == rhs.DepthClampEnabled &&
CullStyle == rhs.CullStyle &&
StencilFunc == rhs.StencilFunc &&
StencilRef == rhs.StencilRef &&
StencilMask == rhs.StencilMask &&
StencilFailOp == rhs.StencilFailOp &&
StencilZFailOp == rhs.StencilZFailOp &&
StencilZPassOp == rhs.StencilZPassOp &&
StencilEnabled == rhs.StencilEnabled;
// clang-format on
}
};
RenderState State;

float4 ClearColor = {0, 0, 0, 0};
float ClearDepth = 1.f;

pxr::SdfPath FinalColorTargetId;
pxr::SdfPath CameraId;
Expand Down Expand Up @@ -157,13 +112,11 @@ struct HnBeginFrameTaskParams
bool operator==(const HnBeginFrameTaskParams& rhs) const
{
// clang-format off
return Formats == rhs.Formats &&
ClearColor == rhs.ClearColor &&
ClearDepth == rhs.ClearDepth &&
State == rhs.State &&
FinalColorTargetId == rhs.FinalColorTargetId &&
CameraId == rhs.CameraId &&
Renderer == rhs.Renderer;
return Formats == rhs.Formats &&
ClearColor == rhs.ClearColor &&
FinalColorTargetId == rhs.FinalColorTargetId &&
CameraId == rhs.CameraId &&
Renderer == rhs.Renderer;
// clang-format on
}
bool operator!=(const HnBeginFrameTaskParams& rhs) const
Expand Down Expand Up @@ -231,6 +184,7 @@ class HnBeginFrameTask final : public HnTask

Uint32 m_FrameBufferWidth = 0;
Uint32 m_FrameBufferHeight = 0;
float m_DepthClearValue = 1.f;

Timer m_FrameTimer;

Expand Down
15 changes: 11 additions & 4 deletions Hydrogent/src/HnCamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ void HnCamera::Sync(pxr::HdSceneDelegate* SceneDelegate,
pxr::HdDirtyBits OrigDirtyBits = *DirtyBits;
pxr::HdCamera::Sync(SceneDelegate, RenderParam, DirtyBits);

const float MetersPerUnit = RenderParam ? static_cast<const HnRenderParam*>(RenderParam)->GetConfig().MetersPerUnit : 0.01f;
const float UnitsPerMeter = 1.f / MetersPerUnit;
const HnRenderParam::Configuration& RenderConfig = static_cast<const HnRenderParam*>(RenderParam)->GetConfig();
const float MetersPerUnit = RenderConfig.MetersPerUnit;
const float UnitsPerMeter = 1.f / MetersPerUnit;
if (OrigDirtyBits & pxr::HdCamera::DirtyTransform)
{
// USD camera transform is defined in scene units, with camera looking along -Z axis.
Expand Down Expand Up @@ -97,19 +98,25 @@ void HnCamera::Sync(pxr::HdSceneDelegate* SceneDelegate,
const RenderDeviceInfo& DeviceInfo = pDevice->GetDeviceInfo();
const bool NegativeOneToOneNDCZ = DeviceInfo.GetNDCAttribs().MinZ == -1;

float NearPlane = ClippingRangeMeters.GetMin();
float FarPlane = ClippingRangeMeters.GetMax();
if (RenderConfig.UseReverseDepth)
{
std::swap(NearPlane, FarPlane);
}
if (GetProjection() == pxr::HdCamera::Projection::Perspective)
{
m_ProjectionMatrix = {};

m_ProjectionMatrix._11 = FocalLengthUnits / (0.5f * HorzApertureUnits);
m_ProjectionMatrix._22 = FocalLengthUnits / (0.5f * VertApertureUnits);

m_ProjectionMatrix.SetNearFarClipPlanes(ClippingRangeMeters.GetMin(), ClippingRangeMeters.GetMax(), NegativeOneToOneNDCZ);
m_ProjectionMatrix.SetNearFarClipPlanes(NearPlane, FarPlane, NegativeOneToOneNDCZ);
}
else if (GetProjection() == pxr::HdCamera::Projection::Orthographic)
{

m_ProjectionMatrix = float4x4::Ortho(HorzApertureMeters, VertApertureMeters, ClippingRangeMeters.GetMin(), ClippingRangeMeters.GetMax(), NegativeOneToOneNDCZ);
m_ProjectionMatrix = float4x4::Ortho(HorzApertureMeters, VertApertureMeters, NearPlane, FarPlane, NegativeOneToOneNDCZ);
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion Hydrogent/src/HnRenderDelegate.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 Diligent Graphics LLC
* Copyright 2023-2025 Diligent Graphics LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -467,6 +467,7 @@ HnRenderDelegate::HnRenderDelegate(const CreateInfo& CI) :
CI.UseIndexPool,
CI.AsyncShaderCompilation,
!CI.pDevice->GetDeviceInfo().IsGLDevice(), // UseNativeStartVertex
CI.pDevice->GetDeviceInfo().NDC.MinZ == 0, // UseReverseDepth
CI.TextureBindingMode,
CI.MetersPerUnit,
CI.GeometryLoadBudget,
Expand Down
52 changes: 41 additions & 11 deletions Hydrogent/src/Tasks/HnBeginFrameTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,25 +114,46 @@ static void UpdateRenderPassState(const HnBeginFrameTaskParams& Params,
const TEXTURE_FORMAT* RTVFormats,
Uint32 NumRTVs,
TEXTURE_FORMAT DSVFormat,
const HnRenderParam* RenderParam,
HnRenderPassState& RPState)
{
RPState.SetNumRenderTargets(NumRTVs);
for (Uint32 i = 0; i < NumRTVs; ++i)
RPState.SetRenderTargetFormat(i, RTVFormats[i]);

RPState.SetDepthStencilFormat(DSVFormat);

RPState.SetDepthBias(Params.State.DepthBias, Params.State.SlopeScaledDepthBias);
RPState.SetDepthFunc(Params.State.DepthFunc);
RPState.SetDepthBiasEnabled(Params.State.DepthBiasEnabled);
RPState.SetEnableDepthTest(Params.State.DepthTestEnabled);
RPState.SetEnableDepthClamp(Params.State.DepthClampEnabled);
bool FrontFaceCCW = true;

float DepthBias = 0;
float SlopeScaledDepthBias = 0;
pxr::HdCompareFunction DepthFunc = RenderParam->GetConfig().UseReverseDepth ? pxr::HdCmpFuncGreater : pxr::HdCmpFuncLess;
bool DepthBiasEnabled = false;
bool DepthTestEnabled = true;
bool DepthClampEnabled = false;

pxr::HdCullStyle CullStyle = pxr::HdCullStyleBack;

pxr::HdCompareFunction StencilFunc = pxr::HdCmpFuncAlways;
int StencilRef = 0;
int StencilMask = 0xFF;
pxr::HdStencilOp StencilFailOp = pxr::HdStencilOpKeep;
pxr::HdStencilOp StencilZFailOp = pxr::HdStencilOpKeep;
pxr::HdStencilOp StencilZPassOp = pxr::HdStencilOpKeep;
bool StencilEnabled = false;

RPState.SetCullStyle(Params.State.CullStyle);
RPState.SetDepthFunc(DepthFunc);
RPState.SetDepthBias(DepthBias, SlopeScaledDepthBias);
RPState.SetDepthBiasEnabled(DepthBiasEnabled);
RPState.SetEnableDepthTest(DepthTestEnabled);
RPState.SetEnableDepthClamp(DepthClampEnabled);

RPState.SetStencil(Params.State.StencilFunc, Params.State.StencilRef, Params.State.StencilMask,
Params.State.StencilFailOp, Params.State.StencilZFailOp, Params.State.StencilZPassOp);
RPState.SetCullStyle(CullStyle);

RPState.SetFrontFaceCCW(Params.State.FrontFaceCCW);
RPState.SetStencilEnabled(StencilEnabled);
RPState.SetStencil(StencilFunc, StencilRef, StencilMask, StencilFailOp, StencilZFailOp, StencilZPassOp);

RPState.SetFrontFaceCCW(FrontFaceCCW);
}

static TEXTURE_FORMAT GetFallbackTextureFormat(TEXTURE_FORMAT Format)
Expand All @@ -154,25 +175,35 @@ void HnBeginFrameTask::Sync(pxr::HdSceneDelegate* Delegate,
{
if (GetTaskParams(Delegate, m_Params))
{
pxr::HdRenderIndex& RenderIndex = Delegate->GetRenderIndex();
const HnRenderDelegate* RenderDelegate = static_cast<const HnRenderDelegate*>(RenderIndex.GetRenderDelegate());
const HnRenderParam* RenderParam = static_cast<const HnRenderParam*>(RenderDelegate->GetRenderParam());

UpdateRenderPassState(m_Params,
m_Params.Formats.GBuffer.data(),
m_Params.Formats.GBuffer.size(),
m_Params.Formats.Depth,
RenderParam,
m_RenderPassStates[HnRenderResourceTokens->renderPass_OpaqueSelected]);

UpdateRenderPassState(m_Params,
m_Params.Formats.GBuffer.data(),
m_Params.Formats.GBuffer.size(),
m_Params.Formats.Depth,
RenderParam,
m_RenderPassStates[HnRenderResourceTokens->renderPass_OpaqueUnselected_TransparentAll]);

UpdateRenderPassState(m_Params,
nullptr,
0,
m_Params.Formats.Depth,
RenderParam,
m_RenderPassStates[HnRenderResourceTokens->renderPass_TransparentSelected]);

m_DepthClearValue = RenderParam->GetConfig().UseReverseDepth ? 0.f : 1.f;

(*TaskCtx)[HnRenderResourceTokens->suspendSuperSampling] = pxr::VtValue{true};
(*TaskCtx)[HnRenderResourceTokens->backgroundDepth] = pxr::VtValue{m_DepthClearValue};
}
}

Expand Down Expand Up @@ -289,7 +320,7 @@ void HnBeginFrameTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex,

// We first render selected objects using the selection depth buffer.
// Selection depth buffer is copied to the main depth buffer by the HnCopySelectionDepthTask.
RP_OpaqueSelected.Begin(HnFrameRenderTargets::GBUFFER_TARGET_COUNT, m_FrameRenderTargets.GBufferRTVs.data(), m_FrameRenderTargets.SelectionDepthDSV, ClearValues.data(), m_Params.ClearDepth, ~0u);
RP_OpaqueSelected.Begin(HnFrameRenderTargets::GBUFFER_TARGET_COUNT, m_FrameRenderTargets.GBufferRTVs.data(), m_FrameRenderTargets.SelectionDepthDSV, ClearValues.data(), m_DepthClearValue, ~0u);
RP_OpaqueUnselected_TransparentAll.Begin(HnFrameRenderTargets::GBUFFER_TARGET_COUNT, m_FrameRenderTargets.GBufferRTVs.data(), m_FrameRenderTargets.DepthDSV);
RP_TransparentSelected.Begin(0, nullptr, m_FrameRenderTargets.SelectionDepthDSV);

Expand Down Expand Up @@ -365,7 +396,6 @@ void HnBeginFrameTask::Prepare(pxr::HdTaskContext* TaskCtx,
(*TaskCtx)[HnRenderResourceTokens->closestSelectedLocation0Target] = pxr::VtValue{m_ClosestSelLocnTargetId[0]};
(*TaskCtx)[HnRenderResourceTokens->closestSelectedLocation1Target] = pxr::VtValue{m_ClosestSelLocnTargetId[1]};
(*TaskCtx)[HnRenderResourceTokens->jitteredFinalColorTarget] = pxr::VtValue{m_JitteredFinalColorTargetId};
(*TaskCtx)[HnRenderResourceTokens->backgroundDepth] = pxr::VtValue{m_Params.ClearDepth};

bool ResetTAA = false;
if (!m_Params.CameraId.IsEmpty())
Expand Down

0 comments on commit 90f7174

Please sign in to comment.