--- 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::GetRHI()); template 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 void SetDepthStencilStateForBasePass_Internal(FMeshPassProcessorRenderState& InDrawRenderState, ERHIFeatureLevel::Type FeatureLevel) { const static bool bStrataDufferPassEnabled = Strata::IsStrataEnabled() && Strata::IsDBufferPassEnabled(GShaderPlatformForFeatureLevel[FeatureLevel]); if (bStrataDufferPassEnabled) { SetDepthStencilStateForBasePass_Internal(InDrawRenderState); } else { SetDepthStencilStateForBasePass_Internal(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(DrawRenderState, FeatureLevel); } else if (DrawRenderState.GetDepthStencilAccess() & FExclusiveDepthStencil::DepthWrite) { SetDepthStencilStateForBasePass_Internal(DrawRenderState, FeatureLevel); } else { SetDepthStencilStateForBasePass_Internal(DrawRenderState, FeatureLevel); } } else if (bMaskedInEarlyPass) { DrawRenderState.SetDepthStencilState(TStaticDepthStencilState::GetRHI()); } if (bForceEnableStencilDitherState) { SetDepthStencilStateForBasePass_Internal(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);