ue4-shader-自定义模板CustomStencil

Custom Depth Stencil is an extension of Custom Depth. 自定义深度模板 是 自定义深度 的一个扩展.


前篇


使用流程

  1. 项目开启模板测试, 默认是关闭的. project settings -> engine -> rendering -> postprocessing -> custom depth-stencil pass, 选取 enabled with stencil

  2. 给物体指定 模板值. 在 mesh 组件下搜索 render,

    勾选 render customDepth pass, 给 customDepth stencil value 指定模板值 180 (自定义)

    • 如果使用c++, 相关代码

      1
      2
      GetMesh()->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
      #if SCENE_TEXTURES_DISABLED
      return 0;
      #endif
      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 的地方就是 描边颜色