Init
This commit is contained in:
123
03-UnrealEngine/卡通渲染相关资料/渲染功能/其他渲染功能/Toon眉毛渲染.md
Normal file
123
03-UnrealEngine/卡通渲染相关资料/渲染功能/其他渲染功能/Toon眉毛渲染.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: Toon眉毛渲染
|
||||
date: 2023-12-08 17:48:07
|
||||
excerpt:
|
||||
tags:
|
||||
rating: ⭐
|
||||
---
|
||||
## 有关眉毛、表情需要使用 模板功能
|
||||
UTS使用模板
|
||||
![[08-Assets/Images/ImageBag/UrealEngineNPR/UTS表情.png]]
|
||||
![[08-Assets/Images/ImageBag/UrealEngineNPR/UTS表情_StencilOut.png]]
|
||||
![[08-Assets/Images/ImageBag/UrealEngineNPR/UTS表情_StencilMask.png]]
|
||||
|
||||
```
|
||||
Stencil
|
||||
{
|
||||
Ref[_StencilNo] //设置渲染的模板缓存值,0~255
|
||||
Comp[_StencilComp] //模板测试的通过条件,有除了equal,还有Greater、Less、Always、Never等,类似ZTest。
|
||||
Pass[_StencilOpPass] //表示通过模板测试和Z测试(注意是都通过)的像素,怎么处置它的模板值。
|
||||
Fail[_StencilOpFail] //表示通过了模板测试但没通过Z测试的像素,怎么处置它的模板值。
|
||||
}
|
||||
|
||||
_UTS_StencilMode mode = (_UTS_StencilMode)(material.GetInt(ShaderPropStencilMode));
|
||||
switch (mode)
|
||||
{
|
||||
case _UTS_StencilMode.Off:
|
||||
// material.SetInt(ShaderPropStencilNo,0);
|
||||
material.SetInt(ShaderPropStencilComp, (int)_StencilCompFunction.Disabled);
|
||||
material.SetInt(ShaderPropStencilOpPass, (int)_StencilOperation.Keep);
|
||||
material.SetInt(ShaderPropStencilOpFail, (int)_StencilOperation.Keep);
|
||||
break;
|
||||
case _UTS_StencilMode.StencilMask:
|
||||
// material.SetInt(ShaderPropStencilNo,0);
|
||||
material.SetInt(ShaderPropStencilComp, (int)_StencilCompFunction.Always);
|
||||
material.SetInt(ShaderPropStencilOpPass, (int)_StencilOperation.Replace);
|
||||
material.SetInt(ShaderPropStencilOpFail, (int)_StencilOperation.Replace);
|
||||
break;
|
||||
case _UTS_StencilMode.StencilOut:
|
||||
// material.SetInt(ShaderPropStencilNo,0);
|
||||
material.SetInt(ShaderPropStencilComp, (int)_StencilCompFunction.NotEqual);
|
||||
material.SetInt(ShaderPropStencilOpPass, (int)_StencilOperation.Keep);
|
||||
material.SetInt(ShaderPropStencilOpFail, (int)_StencilOperation.Keep);
|
||||
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
七大罪中使用使用了深度测试 Greater Equal.(默认是 less Equal)。但这个方式可能在UE4里不太行,因为UE4的深度测试是全局的?
|
||||
|
||||
这个应该需要创建一个MeshProcessor来实现:
|
||||
```c#
|
||||
FSingleLayerWaterPassMeshProcessor::FSingleLayerWaterPassMeshProcessor(const FScene* Scene, const FSceneView* InViewIfDynamicMeshCommand, const FMeshPassProcessorRenderState& InPassDrawRenderState, FMeshPassDrawListContext* InDrawListContext)
|
||||
: FMeshPassProcessor(Scene, Scene->GetFeatureLevel(), InViewIfDynamicMeshCommand, InDrawListContext)
|
||||
, PassDrawRenderState(InPassDrawRenderState)
|
||||
{
|
||||
if (SingleLayerWaterUsesSimpleShading(Scene->GetShaderPlatform()))
|
||||
{
|
||||
// Force non opaque, pre multiplied alpha, transparent blend mode because water is going to be blended against scene color (no distortion from texture scene color).
|
||||
FRHIBlendState* ForwardSimpleWaterBlendState = TStaticBlendState<CW_RGBA, BO_Add, BF_One, BF_InverseSourceAlpha>::GetRHI();
|
||||
PassDrawRenderState.SetBlendState(ForwardSimpleWaterBlendState);
|
||||
}
|
||||
}
|
||||
|
||||
//默认是CF_DepthNearOrEqual,做这个效果可能就要使用CF_DepthFartherOrEqual
|
||||
void SetupBasePassState(FExclusiveDepthStencil::Type BasePassDepthStencilAccess, const bool bShaderComplexity, FMeshPassProcessorRenderState& DrawRenderState)
|
||||
{
|
||||
DrawRenderState.SetDepthStencilAccess(BasePassDepthStencilAccess);
|
||||
if (bShaderComplexity)
|
||||
{
|
||||
// Additive blending when shader complexity viewmode is enabled.
|
||||
DrawRenderState.SetBlendState(TStaticBlendState<CW_RGBA, BO_Add, BF_One, BF_One, BO_Add, BF_Zero, BF_One>::GetRHI());
|
||||
// Disable depth writes as we have a full depth prepass.
|
||||
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_DepthNearOrEqual>::GetRHI());
|
||||
}
|
||||
}
|
||||
```
|
||||
设置位置在于FXXXPassMeshProcessor::Process()中的SetDepthStencilStateForBasePass()中。需要bMaskedInEarlyPass为false,GetDepthStencilAccess为DepthRead。
|
||||
```c#
|
||||
const bool bMaskedInEarlyPass = (MaterialResource.IsMasked() || Mesh.bDitheredLODTransition) && MaskedInEarlyPass(GShaderPlatformForFeatureLevel[FeatureLevel]);
|
||||
|
||||
if (bEnableReceiveDecalOutput)
|
||||
{
|
||||
// Set stencil value for this draw call
|
||||
// This is effectively extending the GBuffer using the stencil bits
|
||||
const uint8 StencilValue = GET_STENCIL_BIT_MASK(RECEIVE_DECAL, PrimitiveSceneProxy ? !!PrimitiveSceneProxy->ReceivesDecals() : 0x00)
|
||||
| STENCIL_LIGHTING_CHANNELS_MASK(PrimitiveSceneProxy ? PrimitiveSceneProxy->GetLightingChannelStencilValue() : 0x00);
|
||||
|
||||
if (bMaskedInEarlyPass)
|
||||
{
|
||||
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<
|
||||
false, CF_Equal,
|
||||
true, CF_Always, SO_Keep, SO_Keep, SO_Replace,
|
||||
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
||||
0xFF, GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)
|
||||
>::GetRHI());
|
||||
DrawRenderState.SetStencilRef(StencilValue);
|
||||
}
|
||||
else if (DrawRenderState.GetDepthStencilAccess() & FExclusiveDepthStencil::DepthWrite)
|
||||
{
|
||||
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<
|
||||
true, CF_GreaterEqual,
|
||||
true, CF_Always, SO_Keep, SO_Keep, SO_Replace,
|
||||
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
||||
0xFF, GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)
|
||||
>::GetRHI());
|
||||
DrawRenderState.SetStencilRef(StencilValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<
|
||||
false, CF_GreaterEqual,
|
||||
true, CF_Always, SO_Keep, SO_Keep, SO_Replace,
|
||||
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
||||
0xFF, GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)
|
||||
>::GetRHI());
|
||||
DrawRenderState.SetStencilRef(StencilValue);
|
||||
}
|
||||
}
|
||||
else if (bMaskedInEarlyPass)
|
||||
{
|
||||
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<false, CF_Equal>::GetRHI());
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user