7.0 KiB
title, date, excerpt, tags, rating
title | date | excerpt | tags | rating |
---|---|---|---|---|
Untitled | 2024-09-25 14:59:32 | ⭐ |
前言
可以使用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
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。
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);