188 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Untitled
date: 2024-09-25 14:59:32
excerpt:
tags:
rating: ⭐
---
# 前言
可以使用DrawDynamicMeshPass()实现在插件中使用MeshDraw绘制Pass。
参考文章:
- ***UE5为HairStrands添加自定义深度与模板***:https://zhuanlan.zhihu.com/p/689578355
# MeshDraw
推荐学习:
- CustomDepth
- RenderBasePassInternal()
- RenderAnisotropyPass()
Shader推荐
- DepthOnlyVertexShader.usf
- DepthOnlyPixelShader.usf
# NaniteMeshDraw
`Engine\Source\Runtime\Renderer\Private\Nanite\`NaniteMaterials.h & NaniteMaterials.cpp
PS.使用的Shader必须是`FNaniteGlobalShader`的子类。
## BasePass
### DrawBasePass()
该函数在FDeferredShadingSceneRenderer::RenderBasePassInternal()中调用。
DrawNaniteMaterialPass() => SubmitNaniteIndirectMaterial()
## PSO
- RDG 04 Graphics Pipeline State Initializer https://zhuanlan.zhihu.com/p/582020846
- FGraphicsPipelineStateInitializer
- FRHIDepthStencilState* DepthStencilState
- FRHIBlendState* BlendState
- FRHIRasterizerState* RasterizerState
- EPrimitiveType PrimitiveType
- FBoundShaderStateInput BoundShaderState.VertexDeclarationRHI
- FBoundShaderStateInput BoundShaderState.VertexShaderRHI
- FBoundShaderStateInput BoundShaderState.PixelShaderRHI
- ……
// 应用
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit,0);
## FMeshPassProcessorRenderState
- FMeshPassProcessorRenderState
- FRHIBlendState* BlendState
- FRHIDepthStencilState* DepthStencilState
- FExclusiveDepthStencil::Type DepthStencilAccess
- FRHIUniformBuffer* ViewUniformBuffer
- FRHIUniformBuffer* InstancedViewUniformBuffer
- FRHIUniformBuffer* PassUniformBuffer
- FRHIUniformBuffer* NaniteUniformBuffer
- uint32 StencilRef = 0;
### FRHIBlendState
### FRHIDepthStencilState
***TStaticDepthStencilState***
```c++
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Equal>::GetRHI());
template<bool bDepthTest, ECompareFunction CompareFunction, uint32 StencilWriteMask>
void SetDepthStencilStateForBasePass_Internal(FMeshPassProcessorRenderState& InDrawRenderState)
{
InDrawRenderState.SetDepthStencilState(TStaticDepthStencilState<
bDepthTest, CompareFunction,
true, CF_Always, SO_Keep, SO_Keep, SO_Replace,
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
0xFF, StencilWriteMask>::GetRHI());
}
template<bool bDepthTest, ECompareFunction CompareFunction>
void SetDepthStencilStateForBasePass_Internal(FMeshPassProcessorRenderState& InDrawRenderState, ERHIFeatureLevel::Type FeatureLevel)
{
const static bool bStrataDufferPassEnabled = Strata::IsStrataEnabled() && Strata::IsDBufferPassEnabled(GShaderPlatformForFeatureLevel[FeatureLevel]);
if (bStrataDufferPassEnabled)
{
SetDepthStencilStateForBasePass_Internal<bDepthTest, CompareFunction, GET_STENCIL_BIT_MASK(STRATA_RECEIVE_DBUFFER_NORMAL, 1) | GET_STENCIL_BIT_MASK(STRATA_RECEIVE_DBUFFER_DIFFUSE, 1) | GET_STENCIL_BIT_MASK(STRATA_RECEIVE_DBUFFER_ROUGHNESS, 1) | GET_STENCIL_BIT_MASK(DISTANCE_FIELD_REPRESENTATION, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)>(InDrawRenderState);
}
else
{
SetDepthStencilStateForBasePass_Internal<bDepthTest, CompareFunction, GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1) | GET_STENCIL_BIT_MASK(DISTANCE_FIELD_REPRESENTATION, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)>(InDrawRenderState);
}
}
void SetDepthStencilStateForBasePass(
FMeshPassProcessorRenderState& DrawRenderState,
ERHIFeatureLevel::Type FeatureLevel,
bool bDitheredLODTransition,
const FMaterial& MaterialResource,
bool bEnableReceiveDecalOutput,
bool bForceEnableStencilDitherState)
{
const bool bMaskedInEarlyPass = (MaterialResource.IsMasked() || bDitheredLODTransition) && MaskedInEarlyPass(GShaderPlatformForFeatureLevel[FeatureLevel]);
if (bEnableReceiveDecalOutput)
{
if (bMaskedInEarlyPass)
{
SetDepthStencilStateForBasePass_Internal<false, CF_Equal>(DrawRenderState, FeatureLevel);
}
else if (DrawRenderState.GetDepthStencilAccess() & FExclusiveDepthStencil::DepthWrite)
{
SetDepthStencilStateForBasePass_Internal<true, CF_GreaterEqual>(DrawRenderState, FeatureLevel);
}
else
{
SetDepthStencilStateForBasePass_Internal<false, CF_GreaterEqual>(DrawRenderState, FeatureLevel);
}
}
else if (bMaskedInEarlyPass)
{
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Equal>::GetRHI());
}
if (bForceEnableStencilDitherState)
{
SetDepthStencilStateForBasePass_Internal<false, CF_Equal>(DrawRenderState, FeatureLevel);
}
}
```
### CustomStencil
#### InitCustomDepthStencilContext()
根据当前平台是否支持使用ComputeShader直接输出结果bComputeExport、以及是否写入Stencil缓存以此来创建不同的资源。最终输出FCustomDepthContext。
```c++
struct FCustomDepthContext
{
FRDGTextureRef InputDepth = nullptr;
FRDGTextureSRVRef InputStencilSRV = nullptr;
FRDGTextureRef DepthTarget = nullptr;
FRDGTextureRef StencilTarget = nullptr;
bool bComputeExport = true;
};
```
#### EmitCustomDepthStencilTargets()
根据bComputeExport分别使用RDG的ComputeShader与PixelShader输出DepthStencil。
- CS使用FComputeShaderUtils::AddPass()
- PS使用NaniteExportGBuffer.usf的**EmitCustomDepthStencilPS()**FPixelShaderUtils::AddFullscreenPass()
以**FEmitCustomDepthStencilPS**(NaniteExportGBuffer.usf)为例额外输入的Nanite相关变量
- FSceneUniformParameters Scene
- StructuredBuffer`<`FPackedView`>` InViews
- ByteAddressBuffer VisibleClustersSWHW
- FIntVector4, PageConstants
- Texture2D`<`UlongType`>`, VisBuffer64
- ByteAddressBuffer MaterialSlotTable
#### FinalizeCustomDepthStencil()
替换输出的Depth&Stencil。
# FViewInfo
FViewInfo& ViewInfo
- WriteView.bSceneHasSkyMaterial |= bSceneHasSkyMaterial;
- WriteView.bHasSingleLayerWaterMaterial |= bHasSingleLayerWaterMaterial;
- WriteView.bHasCustomDepthPrimitives |= bHasCustomDepthPrimitives;
- WriteView.bHasDistortionPrimitives |= bHasDistortionPrimitives;
- WriteView.bUsesCustomDepth |= bUsesCustomDepth;
- WriteView.bUsesCustomStencil |= bUsesCustomStencil;
- FRelevancePacket::Finalize()
相关性:
- 相关性定义
- FStaticMeshBatchRelevance
- FMaterialRelevance
- View相关计算
- FViewInfo::Init()
- FRelevancePacket
- FRelevancePacket::Finalize()
# 相关宏定义
- SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime);
- DECLARE_CYCLE_STAT_EXTERN(TEXT("Base pass drawing"),STAT_BasePassDrawTime,STATGROUP_SceneRendering, RENDERCORE_API);
- DEFINE_STAT(STAT_BasePassDrawTime);
- DEFINE_GPU_STAT(NaniteBasePass);
- DECLARE_GPU_STAT_NAMED_EXTERN(NaniteBasePass, TEXT("Nanite BasePass"));
- GET_STATID(STAT_CLP_BasePass)
- FRDGParallelCommandListSet ParallelCommandListSet(InPass, RHICmdList, GET_STATID(STAT_CLP_BasePass), View, FParallelCommandListBindings(PassParameters));
- DECLARE_CYCLE_STAT(TEXT("BasePass"), STAT_CLP_BasePass, STATGROUP_ParallelCommandListMarkers);