vault backup: 2024-10-01 23:11:43

This commit is contained in:
BlueRose 2024-10-01 23:11:43 +08:00
parent 0ff0fdfbce
commit b834f90bf8

View File

@ -59,72 +59,118 @@ SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit,0);
- uint32 StencilRef = 0; - uint32 StencilRef = 0;
### FRHIBlendState ### 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⊗FsrcCdst⊗Fdst|
|BO_ReverseSubtract|C = C_{dst} \otimes F_{dst} - C_{src} \otimes F_{src}C=Cdst⊗FdstCsrc⊗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=(1rsrc,1gsrc,1bsrc) | |
| 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=(1asrc,1asrc,1asrc) | F=1-a_{src}F=1asrc |
| 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=(1adst,1adst,1adst) | F=1-a_{dst}F=1adst |
| 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=(1rdst,1gdst,1bdst) | |
| BF_ConstantBlendFactor | F=(r,g,b)F=(r,g,b) | F=aF=a |
| BF_InverseConstantBlendFactor | F=(1-r,1-g,1-b)F=(1r,1g,1b) | F=1-aF=1a |
| BF_Source1Color | 未知 | 未知 |
| BF_InverseSource1Color | 未知 | 未知 |
| BF_Source1Alpha | 未知 | 未知 |
| BF_InverseSource1Alpha | 未知 | 未知 |
最后四个选项没有在DirectX中找到对应的选项没有继续探究前面的应该足够一般使用了。
### FRHIDepthStencilState ### FRHIDepthStencilState
***TStaticDepthStencilState***
```c++ ```c++
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Equal>::GetRHI()); TStaticDepthStencilState<
bEnableDepthWrite, // 是否启用深度写入
DepthTest, // 深度测试比较函数
bEnableFrontFaceStencil, // (正面)启用模板
FrontFaceStencilTest, // (正面)模板失败操作
FrontFaceStencilFailStencilOp, //(正面)模板测试失败时如何更新模板缓冲区
FrontFaceDepthFailStencilOp, //(正面)深度测试失败时如何更新模板缓冲区
FrontFacePassStencilOp, //(正面)通过模板测试时如何更新模板红冲去
bEnableBackFaceStencil, // (背面)启用模板
BackFaceStencilTest, // (背面)模板失败操作
BackFaceStencilFailStencilOp, //(背面)模板测试失败时如何更新模板缓冲区
BackFaceDepthFailStencilOp, //(背面)深度测试失败时如何更新模板缓冲区
BackFacePassStencilOp, //(背面)通过模板测试时如何更新模板红冲去
StencilReadMask, // 模板读取Mask
StencilWriteMask // 模板写入Mask
>
```
template<bool bDepthTest, ECompareFunction CompareFunction, uint32 StencilWriteMask> #### DepthTest
void SetDepthStencilStateForBasePass_Internal(FMeshPassProcessorRenderState& InDrawRenderState) 深度测试比较函数。
```c++
enum ECompareFunction
{ {
InDrawRenderState.SetDepthStencilState(TStaticDepthStencilState< CF_Less,
bDepthTest, CompareFunction, CF_LessEqual,
true, CF_Always, SO_Keep, SO_Keep, SO_Replace, CF_Greater,
false, CF_Always, SO_Keep, SO_Keep, SO_Keep, CF_GreaterEqual,
0xFF, StencilWriteMask>::GetRHI()); CF_Equal,
} CF_NotEqual,
CF_Never, // 总是返回false
CF_Always, // 总是返回true
template<bool bDepthTest, ECompareFunction CompareFunction> ECompareFunction_Num,
void SetDepthStencilStateForBasePass_Internal(FMeshPassProcessorRenderState& InDrawRenderState, ERHIFeatureLevel::Type FeatureLevel) ECompareFunction_NumBits = 3,
{
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( // Utility enumerations
FMeshPassProcessorRenderState& DrawRenderState, CF_DepthNearOrEqual = (((int32)ERHIZBuffer::IsInverted != 0) ? CF_GreaterEqual : CF_LessEqual),
ERHIFeatureLevel::Type FeatureLevel, CF_DepthNear = (((int32)ERHIZBuffer::IsInverted != 0) ? CF_Greater : CF_Less),
bool bDitheredLODTransition, CF_DepthFartherOrEqual = (((int32)ERHIZBuffer::IsInverted != 0) ? CF_LessEqual : CF_GreaterEqual),
const FMaterial& MaterialResource, CF_DepthFarther = (((int32)ERHIZBuffer::IsInverted != 0) ? CF_Less : CF_Greater),
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);
}
}
``` ```
### CustomStencil ### CustomStencil