Skip to content

Commit 3225fda

Browse files
PBR Renderer: implemented clearing OIT layers
1 parent f61a2ad commit 3225fda

File tree

6 files changed

+161
-9
lines changed

6 files changed

+161
-9
lines changed

Hydrogent/interface/Tasks/HnBeginOITPassTask.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include "HnTask.hpp"
3030
#include "../interface/HnRenderPassState.hpp"
3131

32+
#include "../../../../DiligentCore/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h"
33+
#include "../../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
34+
3235
namespace Diligent
3336
{
3437

@@ -76,6 +79,8 @@ class HnBeginOITPassTask final : public HnTask
7679

7780
HnRenderPassState m_RenderPassState;
7881

82+
RefCntAutoPtr<IShaderResourceBinding> m_ClearLayersSRB;
83+
7984
Uint32 m_BoundOITResourcesVersion = ~0u;
8085
};
8186

Hydrogent/src/Tasks/HnBeginOITPassTask.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ void HnBeginOITPassTask::Prepare(pxr::HdTaskContext* TaskCtx,
8282
if (OITDesc.Width != ColorTargetDesc.Width || OITDesc.Height != ColorTargetDesc.Height)
8383
{
8484
FrameTargets->OIT = {};
85+
m_ClearLayersSRB.Release();
8586
}
8687
}
8788

@@ -134,19 +135,14 @@ void HnBeginOITPassTask::Prepare(pxr::HdTaskContext* TaskCtx,
134135

135136
void HnBeginOITPassTask::BindOITResources(HnRenderDelegate* RenderDelegate)
136137
{
137-
if (m_FrameTargets == nullptr)
138-
{
139-
UNEXPECTED("Frame targets are null. This likely indicates that Prepare() has not been called.");
140-
return;
141-
}
142-
138+
VERIFY_EXPR(m_FrameTargets != nullptr);
143139
if (!m_FrameTargets->OIT)
144140
{
145141
UNEXPECTED("OIT resources are not initialized. This likely indicates that Prepare() has not been called.");
146142
return;
147143
}
148144

149-
USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
145+
const USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
150146
if (IShaderResourceBinding* pFrameAttribsSRB = RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::Transparent))
151147
{
152148
Renderer.SetOITResources(pFrameAttribsSRB, m_FrameTargets->OIT);
@@ -173,6 +169,11 @@ void HnBeginOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
173169
UNEXPECTED("Render index is null. This likely indicates that Prepare() has not been called.");
174170
return;
175171
}
172+
if (m_FrameTargets == nullptr)
173+
{
174+
UNEXPECTED("Frame targets are null. This likely indicates that Prepare() has not been called.");
175+
return;
176+
}
176177

177178
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(m_RenderIndex->GetRenderDelegate());
178179
IDeviceContext* pCtx = RenderDelegate->GetDeviceContext();
@@ -186,7 +187,16 @@ void HnBeginOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
186187

187188
ScopedDebugGroup DebugGroup{pCtx, "Begin OIT pass"};
188189

189-
m_RenderPassState.SetFrameAttribsSRB(RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::OITLayers));
190+
const USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
191+
if (!m_ClearLayersSRB)
192+
{
193+
Renderer.CreateClearOITLayersSRB(RenderDelegate->GetFrameAttribsCB(), m_FrameTargets->OIT.Layers, &m_ClearLayersSRB);
194+
}
195+
const TextureDesc& OITTailDesc = m_FrameTargets->OIT.Tail->GetDesc();
196+
Renderer.ClearOITLayers(pCtx, m_ClearLayersSRB, OITTailDesc.Width, OITTailDesc.Height);
197+
198+
IShaderResourceBinding* pFrameAttribsSRB = RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::OITLayers);
199+
m_RenderPassState.SetFrameAttribsSRB(pFrameAttribsSRB);
190200
m_RenderPassState.Commit(pCtx);
191201
}
192202

PBR/interface/PBR_Renderer.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,8 @@ class PBR_Renderer
795795

796796
static OITResources CreateOITResources(IRenderDevice* pDevice, Uint32 Width, Uint32 Height, Uint32 LayerCount);
797797
OITResources CreateOITResources(Uint32 Width, Uint32 Height) const;
798+
void CreateClearOITLayersSRB(IBuffer* pFrameAttribs, IBuffer* OITLayers, IShaderResourceBinding** ppSRB) const;
799+
void ClearOITLayers(IDeviceContext* pCtx, IShaderResourceBinding* pSRB, Uint32 Width, Uint32 Height) const;
798800

799801
protected:
800802
ShaderMacroHelper DefineMacros(const PSOKey& Key) const;
@@ -821,6 +823,8 @@ class PBR_Renderer
821823
const PSOKey& Key,
822824
bool AsyncCompile);
823825

826+
void CreateClearOITLayersPSO();
827+
824828
protected:
825829
enum IBL_FEATURE_FLAGS : Uint32
826830
{
@@ -928,6 +932,9 @@ class PBR_Renderer
928932

929933
std::unordered_map<GraphicsPipelineDesc, PsoHashMapType> m_PSOs;
930934

935+
static constexpr Uint32 ClearOITLayersThreadGroupSize = 16;
936+
RefCntAutoPtr<IPipelineState> m_ClearOITLayersPSO;
937+
931938
std::unique_ptr<StaticShaderTextureIdsArrayType> m_StaticShaderTextureIds;
932939
};
933940

PBR/src/PBR_Renderer.cpp

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,11 @@ PBR_Renderer::PBR_Renderer(IRenderDevice* pDevice,
539539
LOG_WARNING_MESSAGE("OIT is disabled because the device does not support compute shaders");
540540
m_Settings.OITLayerCount = 0;
541541
}
542+
543+
if (m_Settings.OITLayerCount > 0)
544+
{
545+
CreateClearOITLayersPSO();
546+
}
542547
}
543548

544549
if (InitSignature)
@@ -1379,7 +1384,7 @@ ShaderMacroHelper PBR_Renderer::DefineMacros(const PSOKey& Key) const
13791384
Macros.Add("DEBUG_VIEW_CLEAR_COAT", static_cast<int>(DebugViewType::ClearCoat));
13801385
Macros.Add("DEBUG_VIEW_CLEAR_COAT_FACTOR", static_cast<int>(DebugViewType::ClearCoatFactor));
13811386
Macros.Add("DEBUG_VIEW_CLEAR_COAT_ROUGHNESS", static_cast<int>(DebugViewType::ClearCoatRoughness));
1382-
Macros.Add("DEBUG_VIEW_CLEAR_COAT_NORMAL", static_cast<int>(DebugViewType::ClearCoatNormal));
1387+
Macros.Add("DEBUG_VIEW_CLEAR_COAT_NORMAL", static_cast<int>(DebugViewType::ClearCoatNormal));
13831388
Macros.Add("DEBUG_VIEW_SHEEN", static_cast<int>(DebugViewType::Sheen));
13841389
Macros.Add("DEBUG_VIEW_SHEEN_COLOR", static_cast<int>(DebugViewType::SheenColor));
13851390
Macros.Add("DEBUG_VIEW_SHEEN_ROUGHNESS", static_cast<int>(DebugViewType::SheenRoughness));
@@ -2142,6 +2147,84 @@ IPipelineState* PBR_Renderer::GetPSO(PsoHashMapType& PsoHashMap,
21422147
return it != PsoHashMap.end() ? it->second.RawPtr() : nullptr;
21432148
}
21442149

2150+
2151+
void PBR_Renderer::CreateClearOITLayersPSO()
2152+
{
2153+
ComputePipelineStateCreateInfoX PsoCI{"Clear OIT Layers"};
2154+
2155+
ShaderMacroHelper Macros;
2156+
Macros.Add("THREAD_GROUP_SIZE", static_cast<int>(ClearOITLayersThreadGroupSize));
2157+
Macros.Add("NUM_OIT_LAYERS", static_cast<int>(m_Settings.OITLayerCount));
2158+
2159+
ShaderCreateInfo ShaderCI{
2160+
"ClearOITLayers.csh",
2161+
&DiligentFXShaderSourceStreamFactory::GetInstance(),
2162+
"main",
2163+
Macros,
2164+
SHADER_SOURCE_LANGUAGE_HLSL,
2165+
{"PBR VS", SHADER_TYPE_COMPUTE, true},
2166+
};
2167+
ShaderCI.CompileFlags = m_Settings.PackMatrixRowMajor ? SHADER_COMPILE_FLAG_PACK_MATRIX_ROW_MAJOR : SHADER_COMPILE_FLAG_NONE;
2168+
2169+
RefCntAutoPtr<IShader> pCS = m_Device.CreateShader(ShaderCI);
2170+
if (!pCS)
2171+
{
2172+
LOG_ERROR_MESSAGE("Failed to create clear OIT layers compute shader");
2173+
return;
2174+
}
2175+
2176+
PsoCI.AddShader(pCS);
2177+
PsoCI.PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE;
2178+
2179+
m_ClearOITLayersPSO = m_Device.CreateComputePipelineState(PsoCI);
2180+
if (!m_ClearOITLayersPSO)
2181+
{
2182+
LOG_ERROR_MESSAGE("Failed to create clear OIT layers PSO");
2183+
}
2184+
}
2185+
2186+
void PBR_Renderer::CreateClearOITLayersSRB(IBuffer* pFrameAttribs, IBuffer* OITLayers, IShaderResourceBinding** ppSRB) const
2187+
{
2188+
if (!m_ClearOITLayersPSO)
2189+
{
2190+
LOG_ERROR_MESSAGE("Clear OIT layers PSO is not initialized");
2191+
return;
2192+
}
2193+
2194+
m_ClearOITLayersPSO->CreateShaderResourceBinding(ppSRB, true);
2195+
VERIFY_EXPR(*ppSRB);
2196+
(*ppSRB)->GetVariableByName(SHADER_TYPE_COMPUTE, "cbFrameAttribs")->Set(pFrameAttribs);
2197+
(*ppSRB)->GetVariableByName(SHADER_TYPE_COMPUTE, "g_rwOITLayers")->Set(OITLayers->GetDefaultView(BUFFER_VIEW_UNORDERED_ACCESS));
2198+
}
2199+
2200+
void PBR_Renderer::ClearOITLayers(IDeviceContext* pCtx, IShaderResourceBinding* pSRB, Uint32 Width, Uint32 Height) const
2201+
{
2202+
if (!m_ClearOITLayersPSO)
2203+
{
2204+
LOG_ERROR_MESSAGE("Clear OIT layers PSO is not initialized");
2205+
return;
2206+
}
2207+
if (pCtx == nullptr)
2208+
{
2209+
DEV_ERROR("pCtx must not be null");
2210+
return;
2211+
}
2212+
if (pSRB == nullptr)
2213+
{
2214+
DEV_ERROR("pSRB must not be null");
2215+
return;
2216+
}
2217+
2218+
pCtx->SetPipelineState(m_ClearOITLayersPSO);
2219+
pCtx->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
2220+
DispatchComputeAttribs DispatchAttrs{
2221+
(Width + ClearOITLayersThreadGroupSize - 1) / ClearOITLayersThreadGroupSize,
2222+
(Height + ClearOITLayersThreadGroupSize - 1) / ClearOITLayersThreadGroupSize,
2223+
1,
2224+
};
2225+
pCtx->DispatchCompute(DispatchAttrs);
2226+
}
2227+
21452228
void PBR_Renderer::SetInternalShaderParameters(HLSL::PBRRendererShaderParameters& Renderer)
21462229
{
21472230
Renderer.PrefilteredCubeLastMip = m_Settings.EnableIBL ? static_cast<float>(m_pPrefilteredEnvMapSRV->GetTexture()->GetDesc().MipLevels - 1) : 0.f;

Shaders/Common/public/OIT.fxh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
uint PackOITLayer(float Depth, float Transmittance)
2+
{
3+
// Pack depth into the high 24 bits so that packed values
4+
// can be sorted by depth.
5+
uint D = uint(clamp(Depth, 0.0, 1.0) * 16777215.0);
6+
uint T = uint(clamp(Transmittance, 0.0, 1.0) * 255.0);
7+
return (D << 8u) | T;
8+
}
9+
10+
uint GetOITLayerDepth(uint Layer)
11+
{
12+
return Layer >> 8u;
13+
}
14+
15+
float GetOITLayerTransmittance(uint Layer)
16+
{
17+
return float(Layer & 0xFFu) / 255.0;
18+
}
19+
20+
uint GetOITLayerDataOffset(uint2 PixelCoord, uint2 ScreenSize, uint NumLayers)
21+
{
22+
return (PixelCoord.y * ScreenSize.x + PixelCoord.x) * NumLayers;
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "OIT.fxh"
2+
#include "BasicStructures.fxh"
3+
4+
cbuffer cbFrameAttribs
5+
{
6+
CameraAttribs g_Camera;
7+
}
8+
9+
RWStructuredBuffer<uint> g_rwOITLayers;
10+
11+
[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)]
12+
void main(uint3 ThreadID : SV_DispatchThreadID)
13+
{
14+
uint2 ScreenSize = uint2(g_Camera.f4ViewportSize.x, g_Camera.f4ViewportSize.y);
15+
if (ThreadID.x >= ScreenSize.x ||
16+
ThreadID.y >= ScreenSize.y)
17+
return;
18+
19+
uint Offset = GetOITLayerDataOffset(ThreadID.xy, ScreenSize, uint(NUM_OIT_LAYERS));
20+
for (uint layer = 0; layer < uint(NUM_OIT_LAYERS); ++layer)
21+
{
22+
g_rwOITLayers[Offset + layer] = 0xFFFFFFFFu;
23+
}
24+
}

0 commit comments

Comments
 (0)