ue4-shader-自定义模板CustomStencil
Custom Depth Stencil is an extension of Custom Depth. 自定义深度模板 是 自定义深度 的一个扩展.
前篇
- 官方文档: CustomDepth Stencil - https://docs.unrealengine.com/en-US/Engine/Rendering/PostProcessEffects/PostProcessMaterials
- Multi-color Outline Post Process in Unreal Engine 4 - http://www.tomlooman.com/multi-color-outline-post-process-in-unreal-engine-4/
使用流程
项目开启模板测试, 默认是关闭的. project settings -> engine -> rendering -> postprocessing -> custom depth-stencil pass, 选取 enabled with stencil
给物体指定 模板值. 在 mesh 组件下搜索 render,
勾选 render customDepth pass, 给 customDepth stencil value 指定模板值 180 (自定义)
如果使用c++, 相关代码
1
2GetMesh()->SetRenderCustomDepth(true);
GetMesh()->SetCustomDepthStencilValue(255); // assign an int32 within 1-255 range.可以查看一下. lit -> buffer visualization -> custom stencil
测试-outline
参考: Outline effect (Part 1) - https://www.parallelcube.com/2017/12/05/outline-effect-part-1/
效果图
这是一个 post process 材质, 搭配 post process volume 使用
custom 节点代码. 作用是偏移屏幕像素对应的缓冲, 然后再冲 GBuffer 中获取模板值.
GetScreenSpaceData 函数可以从 GBuffer 中获取到数据, 这是 延迟管线 的函数. 参考: Base Pass Pixel Shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
return 0;
float offset_h = SceneTexelSize.r * Thickness;
float offset_v = SceneTexelSize.g * Thickness;
float TL = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(-offset_h, -offset_v)), false).GBuffer.CustomStencil.r;
float TM = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(0, -offset_v)), false).GBuffer.CustomStencil.r;
float TR = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(offset_h, -offset_v)), false).GBuffer.CustomStencil.r;
float ML = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(-offset_h, 0)), false).GBuffer.CustomStencil.r;
float MR = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(offset_h, 0)), false).GBuffer.CustomStencil.r;
float BL = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(-offset_h, offset_v)), false).GBuffer.CustomStencil.r;
float BM = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(0, offset_v)), false).GBuffer.CustomStencil.r;
float BR = GetScreenSpaceData(ViewportUVToBufferUV(ScreenPosition + float2(offset_h, offset_v)), false).GBuffer.CustomStencil.r;
return max(TL, max(TM, max(TR, max(ML, max(MR, max(BL, max(BM, BR ) ) ) ) ) ) );
辅助理解图示意图
最后只有交集的地方才是值才是1, 也就是描边的区域. lerp 函数 0 的地方就是 原颜色, 1 的地方就是 描边颜色