413 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			413 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								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
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 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
							 | 
						|||
| 
								 | 
							
								使用***FBlendStateInitializerRHI()*** 进行初始化。
							 | 
						|||
| 
								 | 
							
								它定义了8个渲染对象,一般我们只用第一组,它的七个参数分别是:
							 | 
						|||
| 
								 | 
							
								- Color
							 | 
						|||
| 
								 | 
							
									- Color Write Mask
							 | 
						|||
| 
								 | 
							
									- Color Blend 混合类型
							 | 
						|||
| 
								 | 
							
									- Color Src 混合因子
							 | 
						|||
| 
								 | 
							
									- Color Dest 混合因子
							 | 
						|||
| 
								 | 
							
								- Alpha
							 | 
						|||
| 
								 | 
							
									- Alpha Blend 混合类型
							 | 
						|||
| 
								 | 
							
									- Alpha Src 混合因子
							 | 
						|||
| 
								 | 
							
									- Alpha Dest 混合因子
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								FRHIBlendState* CopyBlendState = TStaticBlendState<CW_RGB, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha, BO_Add, BF_Zero, BF_One>::GetRHI();
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								颜色写入蒙版:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								enum EColorWriteMask
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									CW_RED   = 0x01,
							 | 
						|||
| 
								 | 
							
									CW_GREEN = 0x02,
							 | 
						|||
| 
								 | 
							
									CW_BLUE  = 0x04,
							 | 
						|||
| 
								 | 
							
									CW_ALPHA = 0x08,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									CW_NONE  = 0,
							 | 
						|||
| 
								 | 
							
									CW_RGB   = CW_RED | CW_GREEN | CW_BLUE,
							 | 
						|||
| 
								 | 
							
									CW_RGBA  = CW_RED | CW_GREEN | CW_BLUE | CW_ALPHA,
							 | 
						|||
| 
								 | 
							
									CW_RG    = CW_RED | CW_GREEN,
							 | 
						|||
| 
								 | 
							
									CW_BA    = CW_BLUE | CW_ALPHA,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									EColorWriteMask_NumBits = 4,
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### 混合运算
							 | 
						|||
| 
								 | 
							
								混合运算符对于颜色混合方程和Alpha混合方程效果是一样的,这里就只用颜色混合方程来做讲解。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								| BlendOperation       | 颜色混合方程                                                                             |
							 | 
						|||
| 
								 | 
							
								| -------------------- | ---------------------------------------------------------------------------------- |
							 | 
						|||
| 
								 | 
							
								| BO_Add               | $$C=C_{src} \otimes F_{src} + C_{dst} \otimes F_{dst}Csrc⊗Fsrc+Cdst⊗Fdst$$     |
							 | 
						|||
| 
								 | 
							
								| BO_Subtract          | $$C = C_{src} \otimes F_{src} - C_{dst} \otimes F_{dst}C=Csrc⊗Fsrc−Cdst⊗Fdst$$ |
							 | 
						|||
| 
								 | 
							
								| BO_ReverseSubtract   | $$C = C_{dst} \otimes F_{dst} - C_{src} \otimes F_{src}C=Cdst⊗Fdst−Csrc⊗Fsrc$$ |
							 | 
						|||
| 
								 | 
							
								| BO_Min               | $$C = Min(C_{src} , C_{dst} )C=Min(Csrc,Cdst)$$                                  |
							 | 
						|||
| 
								 | 
							
								| BO_Max               | $$C = Max(C_{src} , C_{dst} )C=Max(Csrc,Cdst)$$                                  |
							 | 
						|||
| 
								 | 
							
								| BO_Min和BO_Max忽略了混合因子 |                                                                                    |
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### 混合因子
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								| BlendFactor                   | 颜色混合因子                                                           | Alpha混合因子                |
							 | 
						|||
| 
								 | 
							
								| ----------------------------- | ---------------------------------------------------------------- | ------------------------ |
							 | 
						|||
| 
								 | 
							
								| BF_Zero                       | $$F = (0,0,0)F=(0,0,0)$$                                         | $$F=0F=0$$               |
							 | 
						|||
| 
								 | 
							
								| BF_One                        | $$F=(1,1,1)F=(1,1,1)$$                                           | $$F=1F=1$$               |
							 | 
						|||
| 
								 | 
							
								| BF_SourceColor                | $$F=(r_{src},g_{src},b_{src})F=(rsrc,gsrc,bsrc)$$             | –                        |
							 | 
						|||
| 
								 | 
							
								| BF_InverseSourceColor         | $$F=(1-r_{src},1-g_{src},1-b_{src})F=(1−rsrc,1−gsrc,1−bsrc)$$ | –                        |
							 | 
						|||
| 
								 | 
							
								| BF_SourceAlpha                | $$F=(a_{src},a_{src},a_{src})F=(asrc,asrc,asrc)$$             | $$F=a_{src}F=asrc$$     |
							 | 
						|||
| 
								 | 
							
								| BF_InverseSourceAlpha         | $$F=(1-a_{src},1-a_{src},1-a_{src})F=(1−asrc,1−asrc,1−asrc)$$ | $$F=1-a_{src}F=1−asrc$$ |
							 | 
						|||
| 
								 | 
							
								| BF_DestAlpha                  | $$F=(a_{dst},a_{dst},a_{dst})F=(adst,adst,adst)$$             | $$F=a_{dst}F=adst$$     |
							 | 
						|||
| 
								 | 
							
								| BF_InverseDestAlpha           | $$F=(1-a_{dst},1-a_{dst},1-a_{dst})F=(1−adst,1−adst,1−adst)$$ | $$F=1-a_{dst}F=1−adst$$ |
							 | 
						|||
| 
								 | 
							
								| BF_DestColor                  | $$F=(r_{dst},g_{dst},b_{dst})F=(rdst,gdst,bdst)$$             | –                        |
							 | 
						|||
| 
								 | 
							
								| BF_InverseDestColor           | $$F=(1-r_{dst},1-g_{dst},1-b_{dst})F=(1−rdst,1−gdst,1−bdst)$$ | –                        |
							 | 
						|||
| 
								 | 
							
								| BF_ConstantBlendFactor        | F=(r,g,b)F=(r,g,b)                                               | F=aF=a                   |
							 | 
						|||
| 
								 | 
							
								| BF_InverseConstantBlendFactor | F=(1-r,1-g,1-b)F=(1−r,1−g,1−b)                                   | F=1-aF=1−a               |
							 | 
						|||
| 
								 | 
							
								| BF_Source1Color               | 未知                                                               | 未知                       |
							 | 
						|||
| 
								 | 
							
								| BF_InverseSource1Color        | 未知                                                               | 未知                       |
							 | 
						|||
| 
								 | 
							
								| BF_Source1Alpha               | 未知                                                               | 未知                       |
							 | 
						|||
| 
								 | 
							
								| BF_InverseSource1Alpha        | 未知                                                               | 未知                       |
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								最后四个选项没有在DirectX中找到对应的选项,没有继续探究,前面的应该足够一般使用了。
							 | 
						|||
| 
								 | 
							
								### FRHIDepthStencilState
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								TStaticDepthStencilState<
							 | 
						|||
| 
								 | 
							
										bEnableDepthWrite,          // 是否启用深度写入
							 | 
						|||
| 
								 | 
							
										DepthTest,                  // 深度测试比较函数
							 | 
						|||
| 
								 | 
							
										bEnableFrontFaceStencil,    // (正面)启用模板
							 | 
						|||
| 
								 | 
							
										FrontFaceStencilTest,       // (正面)模板测试操作
							 | 
						|||
| 
								 | 
							
										FrontFaceStencilFailStencilOp, //(正面)模板测试失败时如何更新模板缓冲区
							 | 
						|||
| 
								 | 
							
										FrontFaceDepthFailStencilOp,  //(正面)深度测试失败时如何更新模板缓冲区
							 | 
						|||
| 
								 | 
							
										FrontFacePassStencilOp,     //(正面)通过模板测试时如何更新模板缓冲区
							 | 
						|||
| 
								 | 
							
										bEnableBackFaceStencil,     // (背面)启用模板
							 | 
						|||
| 
								 | 
							
										BackFaceStencilTest,        // (背面)模板失败操作
							 | 
						|||
| 
								 | 
							
										BackFaceStencilFailStencilOp, //(背面)模板测试失败时如何更新模板缓冲区
							 | 
						|||
| 
								 | 
							
										BackFaceDepthFailStencilOp, //(背面)深度测试失败时如何更新模板缓冲区
							 | 
						|||
| 
								 | 
							
										BackFacePassStencilOp,      //(背面)通过模板测试时如何更新模板红冲去
							 | 
						|||
| 
								 | 
							
										StencilReadMask,            // 模板读取Mask
							 | 
						|||
| 
								 | 
							
										StencilWriteMask            // 模板写入Mask
							 | 
						|||
| 
								 | 
							
										>
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								//一般使用这个
							 | 
						|||
| 
								 | 
							
								TStaticDepthStencilState<true, CF_DepthNearOrEqual>::GetRHI();
							 | 
						|||
| 
								 | 
							
								//CustomStencil中使用的
							 | 
						|||
| 
								 | 
							
								TStaticDepthStencilState<true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, 255, 255>::GetRHI()
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#### DepthTest
							 | 
						|||
| 
								 | 
							
								深度测试比较函数。
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								enum ECompareFunction
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									CF_Less,
							 | 
						|||
| 
								 | 
							
									CF_LessEqual,
							 | 
						|||
| 
								 | 
							
									CF_Greater,
							 | 
						|||
| 
								 | 
							
									CF_GreaterEqual,
							 | 
						|||
| 
								 | 
							
									CF_Equal,
							 | 
						|||
| 
								 | 
							
									CF_NotEqual,
							 | 
						|||
| 
								 | 
							
									CF_Never, // 总是返回false
							 | 
						|||
| 
								 | 
							
									CF_Always, // 总是返回true
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									ECompareFunction_Num,
							 | 
						|||
| 
								 | 
							
									ECompareFunction_NumBits = 3,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// Utility enumerations
							 | 
						|||
| 
								 | 
							
									CF_DepthNearOrEqual		= (((int32)ERHIZBuffer::IsInverted != 0) ? CF_GreaterEqual : CF_LessEqual),
							 | 
						|||
| 
								 | 
							
									CF_DepthNear			= (((int32)ERHIZBuffer::IsInverted != 0) ? CF_Greater : CF_Less),
							 | 
						|||
| 
								 | 
							
									CF_DepthFartherOrEqual	= (((int32)ERHIZBuffer::IsInverted != 0) ? CF_LessEqual : CF_GreaterEqual),
							 | 
						|||
| 
								 | 
							
									CF_DepthFarther			= (((int32)ERHIZBuffer::IsInverted != 0) ? CF_Less : CF_Greater),
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								enum EStencilOp  
							 | 
						|||
| 
								 | 
							
								{  
							 | 
						|||
| 
								 | 
							
								    SO_Keep,  
							 | 
						|||
| 
								 | 
							
								    SO_Zero,  
							 | 
						|||
| 
								 | 
							
								    SO_Replace,  
							 | 
						|||
| 
								 | 
							
								    SO_SaturatedIncrement,  
							 | 
						|||
| 
								 | 
							
								    SO_SaturatedDecrement,  
							 | 
						|||
| 
								 | 
							
								    SO_Invert,  
							 | 
						|||
| 
								 | 
							
								    SO_Increment,  
							 | 
						|||
| 
								 | 
							
								    SO_Decrement,  
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								    EStencilOp_Num,  
							 | 
						|||
| 
								 | 
							
								    EStencilOp_NumBits = 3,  
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 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);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# NaniteMeshDraw
							 | 
						|||
| 
								 | 
							
								`Engine\Source\Runtime\Renderer\Private\Nanite\`NaniteMaterials.h & NaniteMaterials.cpp
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								PS.使用的Shader必须是`FNaniteGlobalShader`的子类。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								以下是Nanite物体的CustomDepth绘制过程:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								bool FSceneRenderer::RenderCustomDepthPass(
							 | 
						|||
| 
								 | 
							
									FRDGBuilder& GraphBuilder,
							 | 
						|||
| 
								 | 
							
									FCustomDepthTextures& CustomDepthTextures,
							 | 
						|||
| 
								 | 
							
									const FSceneTextureShaderParameters& SceneTextures,
							 | 
						|||
| 
								 | 
							
									TConstArrayView<Nanite::FRasterResults> PrimaryNaniteRasterResults,
							 | 
						|||
| 
								 | 
							
									TConstArrayView<Nanite::FPackedView> PrimaryNaniteViews)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									if (!CustomDepthTextures.IsValid())
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										return false;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// Determine if any of the views have custom depth and if any of them have Nanite that is rendering custom depth
							 | 
						|||
| 
								 | 
							
									// 构建NaniteDrawLists,用于后面的绘制
							 | 
						|||
| 
								 | 
							
									bool bAnyCustomDepth = false;
							 | 
						|||
| 
								 | 
							
									TArray<FNaniteCustomDepthDrawList, SceneRenderingAllocator> NaniteDrawLists;
							 | 
						|||
| 
								 | 
							
									NaniteDrawLists.AddDefaulted(Views.Num());
							 | 
						|||
| 
								 | 
							
									uint32 TotalNaniteInstances = 0;
							 | 
						|||
| 
								 | 
							
									for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										FViewInfo& View = Views[ViewIndex];
							 | 
						|||
| 
								 | 
							
										if (View.ShouldRenderView() && View.bHasCustomDepthPrimitives)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											if (PrimaryNaniteRasterResults.IsValidIndex(ViewIndex))
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												const FNaniteVisibilityResults& VisibilityResults = PrimaryNaniteRasterResults[ViewIndex].VisibilityResults;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												// Get the Nanite instance draw list for this view. (NOTE: Always use view index 0 for now because we're not doing
							 | 
						|||
| 
								 | 
							
												// multi-view yet).
							 | 
						|||
| 
								 | 
							
												NaniteDrawLists[ViewIndex] = BuildNaniteCustomDepthDrawList(View, 0u, VisibilityResults);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
												TotalNaniteInstances += NaniteDrawLists[ViewIndex].Num();
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											bAnyCustomDepth = true;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									SET_DWORD_STAT(STAT_NaniteCustomDepthInstances, TotalNaniteInstances);
							 | 
						|||
| 
								 | 
							
								..
							 | 
						|||
| 
								 | 
							
									if (TotalNaniteInstances > 0)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										RDG_EVENT_SCOPE(GraphBuilder, "Nanite CustomDepth");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										const FIntPoint RasterTextureSize = CustomDepthTextures.Depth->Desc.Extent;
							 | 
						|||
| 
								 | 
							
										FIntRect RasterTextureRect(0, 0, RasterTextureSize.X, RasterTextureSize.Y);
							 | 
						|||
| 
								 | 
							
										if (Views.Num() == 1)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											const FViewInfo& View = Views[0];
							 | 
						|||
| 
								 | 
							
											if (View.ViewRect.Min.X == 0 && View.ViewRect.Min.Y == 0)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												RasterTextureRect = View.ViewRect;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										const bool bWriteCustomStencil = IsCustomDepthPassWritingStencil();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										Nanite::FSharedContext SharedContext{};
							 | 
						|||
| 
								 | 
							
										SharedContext.FeatureLevel = Scene->GetFeatureLevel();
							 | 
						|||
| 
								 | 
							
										SharedContext.ShaderMap = GetGlobalShaderMap(SharedContext.FeatureLevel);
							 | 
						|||
| 
								 | 
							
										SharedContext.Pipeline = Nanite::EPipeline::Primary;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										// TODO: If !bWriteCustomStencil, we could copy off the depth and rasterize depth-only (probable optimization)
							 | 
						|||
| 
								 | 
							
										//初始化Nanite::FRasterContext RasterContext。
							 | 
						|||
| 
								 | 
							
										Nanite::FRasterContext RasterContext = Nanite::InitRasterContext(
							 | 
						|||
| 
								 | 
							
											GraphBuilder,
							 | 
						|||
| 
								 | 
							
											SharedContext,
							 | 
						|||
| 
								 | 
							
											ViewFamily,
							 | 
						|||
| 
								 | 
							
											RasterTextureSize,
							 | 
						|||
| 
								 | 
							
											RasterTextureRect,
							 | 
						|||
| 
								 | 
							
											false, // bVisualize
							 | 
						|||
| 
								 | 
							
											Nanite::EOutputBufferMode::VisBuffer,
							 | 
						|||
| 
								 | 
							
											true, // bClearTarget
							 | 
						|||
| 
								 | 
							
											nullptr, // RectMinMaxBufferSRV
							 | 
						|||
| 
								 | 
							
											0, // NumRects
							 | 
						|||
| 
								 | 
							
											nullptr, // ExternalDepthBuffer
							 | 
						|||
| 
								 | 
							
											true // bCustomPass
							 | 
						|||
| 
								 | 
							
										);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										//用于构建FCustomDepthContext结构体,创建对应的贴图资源。主要包含了InputDepth、InputStencilSRV、DepthTarget、StencilTarget以及bComputeExport(是否使用ComputeShader输出)。
							 | 
						|||
| 
								 | 
							
										Nanite::FCustomDepthContext CustomDepthContext = Nanite::InitCustomDepthStencilContext(
							 | 
						|||
| 
								 | 
							
											GraphBuilder,
							 | 
						|||
| 
								 | 
							
											CustomDepthTextures,
							 | 
						|||
| 
								 | 
							
											bWriteCustomStencil);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										Nanite::FConfiguration CullingConfig = { 0 };//Nanite剔除设置,用的较多的是bUpdateStreaming、bPrimaryContext、bTwoPassOcclusion,设置为true。
							 | 
						|||
| 
								 | 
							
										CullingConfig.bUpdateStreaming = true;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex)
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											RDG_EVENT_SCOPE_CONDITIONAL(GraphBuilder, Views.Num() > 1, "View%d", ViewIndex);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											FViewInfo& View = Views[ViewIndex];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											if (!View.ShouldRenderView() || NaniteDrawLists[ViewIndex].Num() == 0)
							 | 
						|||
| 
								 | 
							
											{
							 | 
						|||
| 
								 | 
							
												continue;
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											//创建Nanite渲染器
							 | 
						|||
| 
								 | 
							
											auto NaniteRenderer = Nanite::IRenderer::Create(
							 | 
						|||
| 
								 | 
							
												GraphBuilder,
							 | 
						|||
| 
								 | 
							
												*Scene,
							 | 
						|||
| 
								 | 
							
												View,
							 | 
						|||
| 
								 | 
							
												GetSceneUniforms(),
							 | 
						|||
| 
								 | 
							
												SharedContext,
							 | 
						|||
| 
								 | 
							
												RasterContext,
							 | 
						|||
| 
								 | 
							
												CullingConfig,
							 | 
						|||
| 
								 | 
							
												View.ViewRect,
							 | 
						|||
| 
								 | 
							
												/* PrevHZB = */ nullptr
							 | 
						|||
| 
								 | 
							
											);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											NaniteRenderer->DrawGeometry(
							 | 
						|||
| 
								 | 
							
												Scene->NaniteRasterPipelines[ENaniteMeshPass::BasePass],
							 | 
						|||
| 
								 | 
							
												PrimaryNaniteRasterResults[ViewIndex].VisibilityResults,
							 | 
						|||
| 
								 | 
							
												*Nanite::FPackedViewArray::Create(GraphBuilder, PrimaryNaniteViews[ViewIndex]),
							 | 
						|||
| 
								 | 
							
												NaniteDrawLists[ViewIndex]
							 | 
						|||
| 
								 | 
							
											);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											Nanite::FRasterResults RasterResults;
							 | 
						|||
| 
								 | 
							
											NaniteRenderer->ExtractResults( RasterResults );
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											// Emit depth
							 | 
						|||
| 
								 | 
							
											Nanite::EmitCustomDepthStencilTargets(
							 | 
						|||
| 
								 | 
							
												GraphBuilder,
							 | 
						|||
| 
								 | 
							
												*Scene,
							 | 
						|||
| 
								 | 
							
												View,
							 | 
						|||
| 
								 | 
							
												RasterResults.PageConstants,
							 | 
						|||
| 
								 | 
							
												RasterResults.VisibleClustersSWHW,
							 | 
						|||
| 
								 | 
							
												RasterResults.ViewsBuffer,
							 | 
						|||
| 
								 | 
							
												RasterContext.VisBuffer64,
							 | 
						|||
| 
								 | 
							
												CustomDepthContext
							 | 
						|||
| 
								 | 
							
											);
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										Nanite::FinalizeCustomDepthStencil(GraphBuilder, CustomDepthContext, CustomDepthTextures);
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								...
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								- Nanite::InitRasterContext():初始化Nanite::FRasterContext RasterContext。
							 | 
						|||
| 
								 | 
							
								- Nanite::InitCustomDepthStencilContext():位于NaniteMaterials.cpp,用于构建FCustomDepthContext结构体,创建对应的贴图资源。主要包含了InputDepth、InputStencilSRV、DepthTarget、StencilTarget以及bComputeExport(是否使用ComputeShader输出)。
							 | 
						|||
| 
								 | 
							
								- auto NaniteRenderer = Nanite::IRenderer::Create():创建Nanite渲染器
							 | 
						|||
| 
								 | 
							
								- NaniteRenderer->DrawGeometry():Nanite物体绘制
							 | 
						|||
| 
								 | 
							
								- NaniteRenderer->ExtractResults( RasterResults ):提取渲染结果。
							 | 
						|||
| 
								 | 
							
								- ***Nanite::EmitCustomDepthStencilTargets()***:使用提取到的Nanite::FRasterResults RasterResults,输出CustomDepth。结果存储在 FCustomDepthContext& CustomDepthContext中。
							 | 
						|||
| 
								 | 
							
									- FDepthExportCS / FEmitCustomDepthStencilPS
							 | 
						|||
| 
								 | 
							
								- Nanite::FinalizeCustomDepthStencil():将CustomDepthContext中的结果输出到CustomDepthTextures上。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## BasePass Nanite
							 | 
						|||
| 
								 | 
							
								1. Render()中向RenderBasePass()传入const TArrayView<Nanite::FRasterResults>& NaniteRasterResults。
							 | 
						|||
| 
								 | 
							
								2. 调用Lambda RenderNaniteBasePass(),本质上是调用Nanite::DrawBasePass()进行渲染。
							 |