Enable depth-only shadow pass execution

This commit is contained in:
2026-04-04 20:35:47 +08:00
parent a548e0d0a9
commit 353d129613
8 changed files with 494 additions and 59 deletions

View File

@@ -45,19 +45,47 @@ bool IsSupportedPerObjectOnlyBindingPlan(const BuiltinPassResourceBindingPlan& b
!bindingPlan.usesSamplers;
}
uint32_t ResolveSurfaceColorAttachmentCount(const RenderSurface& surface) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
return (!colorAttachments.empty() && colorAttachments[0] != nullptr) ? 1u : 0u;
}
RHI::Format ResolveSurfaceColorFormat(const RenderSurface& surface) {
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface.GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr) {
return RHI::Format::Unknown;
}
return colorAttachments[0]->GetFormat();
}
RHI::Format ResolveSurfaceDepthFormat(const RenderSurface& surface) {
if (RHI::RHIResourceView* depthAttachment = surface.GetDepthAttachment();
depthAttachment != nullptr) {
return depthAttachment->GetFormat();
}
return RHI::Format::Unknown;
}
RHI::GraphicsPipelineDesc CreatePipelineDesc(
RHI::RHIType backendType,
RHI::RHIPipelineLayout* pipelineLayout,
const Resources::Shader& shader,
const Containers::String& passName,
const Resources::Material* material,
const RenderSurface& surface,
const RHI::InputLayoutDesc& inputLayout) {
RHI::GraphicsPipelineDesc pipelineDesc = {};
pipelineDesc.pipelineLayout = pipelineLayout;
pipelineDesc.topologyType = static_cast<uint32_t>(RHI::PrimitiveTopologyType::Triangle);
pipelineDesc.renderTargetCount = 1;
pipelineDesc.renderTargetFormats[0] = static_cast<uint32_t>(RHI::Format::R8G8B8A8_UNorm);
pipelineDesc.depthStencilFormat = static_cast<uint32_t>(RHI::Format::D24_UNorm_S8_UInt);
pipelineDesc.renderTargetCount = ResolveSurfaceColorAttachmentCount(surface);
if (pipelineDesc.renderTargetCount > 0) {
pipelineDesc.renderTargetFormats[0] =
static_cast<uint32_t>(ResolveSurfaceColorFormat(surface));
}
pipelineDesc.depthStencilFormat =
static_cast<uint32_t>(ResolveSurfaceDepthFormat(surface));
pipelineDesc.sampleCount = 1;
pipelineDesc.inputLayout = inputLayout;
ApplyMaterialRenderState(material, pipelineDesc);
@@ -138,9 +166,10 @@ bool BuiltinDepthStylePassBase::Execute(const RenderPassContext& context) {
}
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (colorAttachments.empty() ||
colorAttachments[0] == nullptr ||
context.surface.GetDepthAttachment() == nullptr) {
RHI::RHIResourceView* depthAttachment = context.surface.GetDepthAttachment();
RHI::RHIResourceView* renderTarget =
(!colorAttachments.empty() ? colorAttachments[0] : nullptr);
if (depthAttachment == nullptr) {
return false;
}
@@ -154,16 +183,20 @@ bool BuiltinDepthStylePassBase::Execute(const RenderPassContext& context) {
}
RHI::RHICommandList* commandList = context.renderContext.commandList;
RHI::RHIResourceView* renderTarget = colorAttachments[0];
if (context.surface.IsAutoTransitionEnabled()) {
if (context.surface.IsAutoTransitionEnabled() && renderTarget != nullptr) {
commandList->TransitionBarrier(
renderTarget,
context.surface.GetColorStateBefore(),
RHI::ResourceStates::RenderTarget);
}
commandList->SetRenderTargets(1, &renderTarget, context.surface.GetDepthAttachment());
RHI::RHIResourceView* renderTargets[] = { renderTarget };
const uint32_t renderTargetCount = renderTarget != nullptr ? 1u : 0u;
commandList->SetRenderTargets(
renderTargetCount,
renderTargetCount > 0 ? renderTargets : nullptr,
depthAttachment);
const RHI::Viewport viewport = {
static_cast<float>(renderArea.x),
@@ -185,11 +218,12 @@ bool BuiltinDepthStylePassBase::Execute(const RenderPassContext& context) {
const Math::Color clearColor = context.sceneData.cameraData.clearColor;
const float clearValues[4] = { clearColor.r, clearColor.g, clearColor.b, clearColor.a };
if (HasRenderClearFlag(context.sceneData.cameraData.clearFlags, RenderClearFlags::Color)) {
if (renderTarget != nullptr &&
HasRenderClearFlag(context.sceneData.cameraData.clearFlags, RenderClearFlags::Color)) {
commandList->ClearRenderTarget(renderTarget, clearValues, 1, clearRects);
}
if (HasRenderClearFlag(context.sceneData.cameraData.clearFlags, RenderClearFlags::Depth)) {
commandList->ClearDepthStencil(context.surface.GetDepthAttachment(), 1.0f, 0, 1, clearRects);
commandList->ClearDepthStencil(depthAttachment, 1.0f, 0, 1, clearRects);
}
commandList->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList);
@@ -199,12 +233,12 @@ bool BuiltinDepthStylePassBase::Execute(const RenderPassContext& context) {
continue;
}
DrawVisibleItem(context.renderContext, context.sceneData, visibleItem);
DrawVisibleItem(context.renderContext, context.surface, context.sceneData, visibleItem);
}
commandList->EndRenderPass();
if (context.surface.IsAutoTransitionEnabled()) {
if (context.surface.IsAutoTransitionEnabled() && renderTarget != nullptr) {
commandList->TransitionBarrier(
renderTarget,
RHI::ResourceStates::RenderTarget,
@@ -433,6 +467,7 @@ BuiltinDepthStylePassBase::PassResourceLayout* BuiltinDepthStylePassBase::GetOrC
RHI::RHIPipelineState* BuiltinDepthStylePassBase::GetOrCreatePipelineState(
const RenderContext& context,
const RenderSurface& surface,
const Resources::Material* material) {
const ResolvedShaderPass resolvedShaderPass = ResolveSurfaceShaderPass(material);
if (resolvedShaderPass.shader == nullptr || resolvedShaderPass.pass == nullptr) {
@@ -449,6 +484,9 @@ RHI::RHIPipelineState* BuiltinDepthStylePassBase::GetOrCreatePipelineState(
material != nullptr ? material->GetRenderState() : Resources::MaterialRenderState();
pipelineKey.shader = resolvedShaderPass.shader;
pipelineKey.passName = resolvedShaderPass.passName;
pipelineKey.renderTargetCount = ResolveSurfaceColorAttachmentCount(surface);
pipelineKey.renderTargetFormat = static_cast<uint32_t>(ResolveSurfaceColorFormat(surface));
pipelineKey.depthStencilFormat = static_cast<uint32_t>(ResolveSurfaceDepthFormat(surface));
const auto existing = m_pipelineStates.find(pipelineKey);
if (existing != m_pipelineStates.end()) {
@@ -461,6 +499,7 @@ RHI::RHIPipelineState* BuiltinDepthStylePassBase::GetOrCreatePipelineState(
*resolvedShaderPass.shader,
resolvedShaderPass.passName,
material,
surface,
BuildCommonInputLayout());
RHI::RHIPipelineState* pipelineState = context.device->CreatePipelineState(pipelineDesc);
if (pipelineState == nullptr || !pipelineState->IsValid()) {
@@ -552,6 +591,7 @@ void BuiltinDepthStylePassBase::DestroyPassResourceLayout(PassResourceLayout& pa
bool BuiltinDepthStylePassBase::DrawVisibleItem(
const RenderContext& context,
const RenderSurface& surface,
const RenderSceneData& sceneData,
const VisibleRenderItem& visibleItem) {
if (visibleItem.mesh == nullptr || visibleItem.gameObject == nullptr) {
@@ -579,7 +619,7 @@ bool BuiltinDepthStylePassBase::DrawVisibleItem(
return false;
}
RHI::RHIPipelineState* pipelineState = GetOrCreatePipelineState(context, material);
RHI::RHIPipelineState* pipelineState = GetOrCreatePipelineState(context, surface, material);
if (pipelineState == nullptr) {
return false;
}