10 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
使用FBlendStateInitializerRHI() 进行初始化。 它定义了8个渲染对象,一般我们只用第一组,它的七个参数分别是:
- Color
- Color Write Mask
- Color Blend 混合类型
- Color Src 混合因子
- Color Dest 混合因子
- Alpha
- Alpha Blend 混合类型
- Alpha Src 混合因子
- Alpha Dest 混合因子
FRHIBlendState* CopyBlendState = TStaticBlendState<CW_RGB, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha, BO_Add, BF_Zero, BF_One>::GetRHI();
颜色写入蒙版:
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
TStaticDepthStencilState<
bEnableDepthWrite, // 是否启用深度写入
DepthTest, // 深度测试比较函数
bEnableFrontFaceStencil, // (正面)启用模板
FrontFaceStencilTest, // (正面)模板失败操作
FrontFaceStencilFailStencilOp, //(正面)模板测试失败时如何更新模板缓冲区
FrontFaceDepthFailStencilOp, //(正面)深度测试失败时如何更新模板缓冲区
FrontFacePassStencilOp, //(正面)通过模板测试时如何更新模板红冲去
bEnableBackFaceStencil, // (背面)启用模板
BackFaceStencilTest, // (背面)模板失败操作
BackFaceStencilFailStencilOp, //(背面)模板测试失败时如何更新模板缓冲区
BackFaceDepthFailStencilOp, //(背面)深度测试失败时如何更新模板缓冲区
BackFacePassStencilOp, //(背面)通过模板测试时如何更新模板红冲去
StencilReadMask, // 模板读取Mask
StencilWriteMask // 模板写入Mask
>
DepthTest
深度测试比较函数。
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。
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);