5.9 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
Untitled 2024-09-25 14:59:32

前言

可以使用DrawDynamicMeshPass()实现在插件中使用MeshDraw绘制Pass。

参考文章:

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()

DepthStencil

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);
	}
}

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);