Skip to content

Commit 3858645

Browse files
Hydrogent: improved handling of OIT blend render targets
1 parent 6ff99f8 commit 3858645

File tree

4 files changed

+77
-33
lines changed

4 files changed

+77
-33
lines changed

Hydrogent/interface/HnFrameRenderTargets.hpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include <array>
3030

3131
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/TextureView.h"
32-
#include "../../../DiligentFX/PBR/interface/PBR_Renderer.hpp"
32+
#include "../../../DiligentFX/PBR/interface/USD_Renderer.hpp"
3333

3434
namespace Diligent
3535
{
@@ -67,6 +67,26 @@ struct HnFrameRenderTargets
6767
ITextureView* JitteredFinalColorRTV = nullptr;
6868

6969
static const char* GetGBufferTargetName(GBUFFER_TARGET Id);
70+
71+
static constexpr GBUFFER_TARGET GetGBufferTargetFromRendererOutputFlag(USD_Renderer::USD_PSO_FLAGS OutputFlag)
72+
{
73+
static_assert(GBUFFER_TARGET_COUNT == 7, "Did you add a new GBuffer target? Please handle it here.");
74+
switch (OutputFlag)
75+
{
76+
// clang-format off
77+
case USD_Renderer::USD_PSO_FLAG_ENABLE_COLOR_OUTPUT: return GBUFFER_TARGET_SCENE_COLOR;
78+
case USD_Renderer::USD_PSO_FLAG_ENABLE_MESH_ID_OUTPUT: return GBUFFER_TARGET_MESH_ID;
79+
case USD_Renderer::USD_PSO_FLAG_ENABLE_MOTION_VECTORS_OUTPUT: return GBUFFER_TARGET_MOTION_VECTOR;
80+
case USD_Renderer::USD_PSO_FLAG_ENABLE_NORMAL_OUTPUT: return GBUFFER_TARGET_NORMAL;
81+
case USD_Renderer::USD_PSO_FLAG_ENABLE_BASE_COLOR_OUTPUT: return GBUFFER_TARGET_BASE_COLOR;
82+
case USD_Renderer::USD_PSO_FLAG_ENABLE_MATERIAL_DATA_OUTPUT: return GBUFFER_TARGET_MATERIAL;
83+
case USD_Renderer::USD_PSO_FLAG_ENABLE_IBL_OUTPUT: return GBUFFER_TARGET_IBL;
84+
// clang-format on
85+
86+
default:
87+
return GBUFFER_TARGET_COUNT;
88+
}
89+
}
7090
};
7191

7292
} // namespace USD

Hydrogent/src/Tasks/HnEndOITPassTask.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ bool HnEndOITPassTask::IsActive(pxr::HdRenderIndex& RenderIndex) const
6262
return RenderMode == HN_RENDER_MODE_SOLID;
6363
}
6464

65+
static_assert(USD_Renderer::USD_PSO_FLAG_OIT_BLEND_OUTPUTS ==
66+
(USD_Renderer::USD_PSO_FLAG_ENABLE_COLOR_OUTPUT |
67+
USD_Renderer::USD_PSO_FLAG_ENABLE_BASE_COLOR_OUTPUT |
68+
USD_Renderer::USD_PSO_FLAG_ENABLE_MATERIAL_DATA_OUTPUT |
69+
USD_Renderer::USD_PSO_FLAG_ENABLE_IBL_OUTPUT),
70+
"Did you change OIT blend output targets? You may need to update this code.");
71+
static constexpr std::array<HnFrameRenderTargets::GBUFFER_TARGET, 4> OITBlendTargetIds{
72+
HnFrameRenderTargets::GetGBufferTargetFromRendererOutputFlag(USD_Renderer::USD_PSO_FLAG_ENABLE_COLOR_OUTPUT),
73+
HnFrameRenderTargets::GetGBufferTargetFromRendererOutputFlag(USD_Renderer::USD_PSO_FLAG_ENABLE_BASE_COLOR_OUTPUT),
74+
HnFrameRenderTargets::GetGBufferTargetFromRendererOutputFlag(USD_Renderer::USD_PSO_FLAG_ENABLE_MATERIAL_DATA_OUTPUT),
75+
HnFrameRenderTargets::GetGBufferTargetFromRendererOutputFlag(USD_Renderer::USD_PSO_FLAG_ENABLE_IBL_OUTPUT),
76+
};
77+
6578
void HnEndOITPassTask::Prepare(pxr::HdTaskContext* TaskCtx,
6679
pxr::HdRenderIndex* RenderIndex)
6780
{
@@ -79,21 +92,18 @@ void HnEndOITPassTask::Prepare(pxr::HdTaskContext* TaskCtx,
7992

8093
if (!m_ApplyOITAttenuationPSO)
8194
{
82-
ITextureView* pColorRTV = FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_SCENE_COLOR];
83-
ITextureView* pBaseColorRTV = FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_BASE_COLOR];
84-
ITextureView* pIblRTV = FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_IBL];
85-
if (pColorRTV == nullptr || pBaseColorRTV == nullptr || pIblRTV == nullptr)
95+
std::array<TEXTURE_FORMAT, OITBlendTargetIds.size()> RTVFormats;
96+
for (size_t i = 0; i < RTVFormats.size(); ++i)
8697
{
87-
UNEXPECTED("Scene color, base color or IBL target is null");
88-
return;
98+
ITextureView* pRTV = FrameTargets->GBufferRTVs[OITBlendTargetIds[i]];
99+
if (pRTV == nullptr)
100+
{
101+
UNEXPECTED("Frame render target ", HnFrameRenderTargets::GetGBufferTargetName(OITBlendTargetIds[i]), " is null");
102+
return;
103+
}
104+
RTVFormats[i] = pRTV->GetDesc().Format;
89105
}
90-
91-
const TextureViewDesc& ColorDesc = pColorRTV->GetDesc();
92-
const TextureViewDesc& BaseColorDesc = pBaseColorRTV->GetDesc();
93-
const TextureViewDesc& IblDesc = pIblRTV->GetDesc();
94-
const TEXTURE_FORMAT RTVFormats[] = {ColorDesc.Format, BaseColorDesc.Format, IblDesc.Format};
95-
96-
Renderer.CreateApplyOITAttenuationPSO(RTVFormats, _countof(RTVFormats), ~0u, TEX_FORMAT_UNKNOWN, &m_ApplyOITAttenuationPSO);
106+
Renderer.CreateApplyOITAttenuationPSO(RTVFormats.data(), static_cast<Uint32>(RTVFormats.size()), ~0u, TEX_FORMAT_UNKNOWN, &m_ApplyOITAttenuationPSO);
97107
VERIFY_EXPR(m_ApplyOITAttenuationPSO);
98108
}
99109

@@ -116,6 +126,12 @@ void HnEndOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
116126
return;
117127
}
118128

129+
if (!m_ApplyOITAttenuationPSO)
130+
{
131+
UNEXPECTED("Apply OIT attenuation PSO is null.");
132+
return;
133+
}
134+
119135
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(m_RenderIndex->GetRenderDelegate());
120136
const USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
121137
IDeviceContext* pCtx = RenderDelegate->GetDeviceContext();
@@ -129,18 +145,17 @@ void HnEndOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
129145
return;
130146
}
131147

132-
ITextureView* ppRTVs[] = {
133-
FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_SCENE_COLOR],
134-
FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_BASE_COLOR],
135-
FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_IBL],
136-
};
137-
if (ppRTVs[0] == nullptr || ppRTVs[1] == nullptr || ppRTVs[2] == nullptr)
148+
std::array<ITextureView*, OITBlendTargetIds.size()> ppRTVs;
149+
for (size_t i = 0; i < ppRTVs.size(); ++i)
138150
{
139-
UNEXPECTED("Scene color, base color or IBL target is null");
140-
return;
151+
ppRTVs[i] = FrameTargets->GBufferRTVs[OITBlendTargetIds[i]];
152+
if (ppRTVs[i] == nullptr)
153+
{
154+
UNEXPECTED("Frame render target ", HnFrameRenderTargets::GetGBufferTargetName(OITBlendTargetIds[i]), " is null");
155+
return;
156+
}
141157
}
142-
143-
pCtx->SetRenderTargets(_countof(ppRTVs), ppRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
158+
pCtx->SetRenderTargets(static_cast<Uint32>(ppRTVs.size()), ppRTVs.data(), nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
144159

145160
const StateTransitionDesc Barriers[] =
146161
{

Hydrogent/src/Tasks/HnTaskManager.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,6 @@ HnTaskManager::HnTaskManager(pxr::HdRenderIndex& RenderIndex,
208208
const USD_Renderer& Renderer = *static_cast<const HnRenderDelegate*>(GetRenderIndex().GetRenderDelegate())->GetUSDRenderer();
209209
const bool OITEnabled = Renderer.GetSettings().OITLayerCount > 0;
210210

211-
USD_Renderer::USD_PSO_FLAGS TranslucentPassOutputs = USD_Renderer::USD_PSO_FLAG_ENABLE_ALL_OUTPUTS;
212-
constexpr USD_Renderer::USD_PSO_FLAGS TranslucentMeshIdPassOutputs =
213-
USD_Renderer::USD_PSO_FLAG_ENABLE_MESH_ID_OUTPUT |
214-
USD_Renderer::USD_PSO_FLAG_ENABLE_MOTION_VECTORS_OUTPUT |
215-
USD_Renderer::USD_PSO_FLAG_ENABLE_NORMAL_OUTPUT;
216211
if (OITEnabled)
217212
{
218213
CreateBeginOITPassTask();
@@ -228,8 +223,6 @@ HnTaskManager::HnTaskManager(pxr::HdRenderIndex& RenderIndex,
228223
HnRenderRprimsTaskParams::RENDER_MODE_FLAG_SOLID,
229224
});
230225
CreateEndOITPassTask();
231-
// We will write mesh ID, motion vectors and depth in a separate pass
232-
TranslucentPassOutputs &= ~TranslucentMeshIdPassOutputs;
233226
}
234227

235228
CreateRenderRprimsTask(HnMaterialTagTokens->translucent,
@@ -238,12 +231,20 @@ HnTaskManager::HnTaskManager(pxr::HdRenderIndex& RenderIndex,
238231
HnRenderResourceTokens->renderPass_TransparentAll,
239232
HnRenderPassParams::SelectionType::All,
240233
USD_Renderer::RenderPassType::Main,
241-
TranslucentPassOutputs,
234+
OITEnabled ? USD_Renderer::USD_PSO_FLAG_OIT_BLEND_OUTPUTS : USD_Renderer::USD_PSO_FLAG_ENABLE_ALL_OUTPUTS,
242235
});
243236

244237
if (OITEnabled)
245238
{
246-
// When OIT is enabled, we do not render mesh ID, motion vectors and depth in translucent pass.
239+
// Write outputs not produced by the OIT translucent pass (mesh id, motion vectors, normals)
240+
constexpr USD_Renderer::USD_PSO_FLAGS TranslucentMeshIdPassOutputs =
241+
USD_Renderer::USD_PSO_FLAG_ENABLE_ALL_OUTPUTS &
242+
~USD_Renderer::USD_PSO_FLAG_OIT_BLEND_OUTPUTS;
243+
static_assert(TranslucentMeshIdPassOutputs ==
244+
(USD_Renderer::USD_PSO_FLAG_ENABLE_MOTION_VECTORS_OUTPUT |
245+
USD_Renderer::USD_PSO_FLAG_ENABLE_MESH_ID_OUTPUT |
246+
USD_Renderer::USD_PSO_FLAG_ENABLE_NORMAL_OUTPUT),
247+
"Unexpected translucent mesh id pass outputs - double check this is correct");
247248
CreateRenderRprimsTask(HnMaterialTagTokens->translucent,
248249
TaskUID_RenderRprimsTranslucentMeshId,
249250
{

PBR/interface/USD_Renderer.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ class USD_Renderer final : public PBR_Renderer
7070
USD_PSO_FLAG_ENABLE_NORMAL_OUTPUT |
7171
USD_PSO_FLAG_ENABLE_BASE_COLOR_OUTPUT |
7272
USD_PSO_FLAG_ENABLE_MATERIAL_DATA_OUTPUT |
73+
USD_PSO_FLAG_ENABLE_IBL_OUTPUT,
74+
75+
// Outputs of the OIT blend pass.
76+
// Do not render motion vectors, mesh ids and normals as blending them does not make sense.
77+
USD_PSO_FLAG_OIT_BLEND_OUTPUTS =
78+
USD_PSO_FLAG_ENABLE_COLOR_OUTPUT |
79+
USD_PSO_FLAG_ENABLE_BASE_COLOR_OUTPUT |
80+
USD_PSO_FLAG_ENABLE_MATERIAL_DATA_OUTPUT |
7381
USD_PSO_FLAG_ENABLE_IBL_OUTPUT
7482
};
7583

0 commit comments

Comments
 (0)