234 lines
10 KiB
Markdown
234 lines
10 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
|
||
|
||
# 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
|
||
它定义了8个渲染对象,一般我们只用第一组,它的七个参数分别是:
|
||
- 颜色写入蒙版
|
||
- 颜色混合运算
|
||
- 颜色源混合因子
|
||
- 颜色目标混合因子
|
||
- Alpha混合运算
|
||
- Alpha源混合因子
|
||
- Alpha目标混合因子
|
||
|
||
颜色写入蒙版:
|
||
|
||
```text
|
||
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,
|
||
};
|
||
```
|
||
|
||
要继续讲解其他参数,需要先列出DirectX的[混合方程](https://zhida.zhihu.com/search?content_id=217472065&content_type=Article&match_order=1&q=%E6%B7%B7%E5%90%88%E6%96%B9%E7%A8%8B&zhida_source=entity)作为参照:
|
||
C = C_{src} \otimes F_{src} \oplus C_{dst} \otimes F_{dst}_C_=_Csrc_⊗_Fsrc_⊕_Cdst_⊗_Fdst_A = A_{src} \otimes F_{src} \oplus A_{dst} \otimes F_{dst}_A_=_Asrc_⊗_Fsrc_⊕_Adst_⊗_Fdst_
|
||
|
||
第一个是颜色的混合方程,第二个是Alpha的混合方程。
|
||
|
||
### 混合运算
|
||
|
||
混合运算符对于颜色混合方程和Alpha混合方程效果是一样的,这里就只用颜色混合方程来做讲解。
|
||
|
||
|BlendOperation|颜色混合方程|
|
||
|---|---|
|
||
|BO_Add|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
|
||
>
|
||
```
|
||
|
||
#### 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),
|
||
};
|
||
```
|
||
|
||
### 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); |