URP | 后处理-描边
内容偏多

使用软件 Unity 2021.3.15 后处理实现描边效果
目的
后处理实现描边效果
这样做有什么需要注意的地方
效果

深度描边
Renderer Feature
我们准备一个默认的 Renderer Feature 在只需要把Shader渲染出来就可以
管线准备
URP | 后处理-自定义后处理 - 哔哩哔哩 (bilibili.com)

Shader
上面定好后处理管线了,那我们开始制作Shader, 核心算法是在Shader中。
提供默认Shader模板
为了计算轮廓,计算相邻像素进行采样比较两个像素的值,如果数值不同,就判断是边缘绘制一条线。
使用深度计算我们的边缘,在深度缓存中以X形状进行采样,
定义我们的渲染储存大小 _MainTex_TexelSize,_Scale
我们首先计算两个值,然后.这两个值将随着增加而递增 1。通过以这种方式缩放UV,我们能够一次仅增加一个像素的边缘宽度 - 实现最大可能的粒度 - 同时仍然保持坐标的中心。

扩展_MainTex_TexelSize和_MainTex_ST 的区别?
_MainTex_TexelSize 是贴图 _MainTex 的像素尺寸大小,值: Vector4(1 / width, 1 / height, width, height)
half2 offs = _MainTex_TexelSize.xy * half2(1,0) * _BlurSize;
_MainTex_ST 是贴图_MainTex的tiling和offset的四元数
_MainTex_ST.xy 是tiling的值
_MainTex_ST.zw 是offset的值
// Transforms 2D UV by scale/bias property #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
注意:这里前到 后处理和管线中增加 控制 Scale 属性
后处理

管线中增加控制Shader

这样后续才能显示正确

采样深度
URP | Depth 深度 - 哔哩哔哩 (bilibili.com)
使用我们计算出来的UV对深度进行采样。
增加深度

因为我们是4个方向,所以使用4个方向采样深度。
我们输出一个深度查看一下效果,

效果

使用减法来比较像素之间的不同深度。

由于差值可以是正数或负数,因此我们在返回结果之前取其绝对值。由于附近深度值之间的差异可能非常小(因此很难在屏幕上看到),我们将差异乘以 100 以使其更容易看到。
效果

这个是检测边缘的一半,depthFiniteDifference1 是另一半。
我们现在需要把这俩个合并成一个,
效果

我们看到表面还是有很多灰色区域,我们希望是只有黑和白。

增加一个变量控制,黑白

到后处理中增加控制变量的方法,

并且增加到 Render里

效果

出现大面积的白色区域,这些区域不是我想要的,我们对表面深度进行调整。

效果

使用深度法线
我们要获取深度法线,我们在管线中增加一个SSAO ,SSAO自带深度法线
SSAO

使用深度法线来绘制,不是深度,我们最后把两者结合起来,
Shader中增加法线深度

使用同样的方法调用
我们前输出看一下深度法线是否起作用,

效果

显示这样的效果就是正确的,如果是黑色的还是没有获取到深度法线。
现在输出 edgeNormal 法线计算的边缘

我们可以看到法线产生了一些新的边缘,原来的边缘效果有一些消失了,
我们把这俩种方法结合起来。

效果

我们看到平面有时候一片白色的区域
可以调大 深度处理来处理,但是会出现法线边缘不完整的情况。


为什么出现白色边缘?
白色区域
表面的斜率越大,相邻像素深度之间的差异就越大。沿着这些表面的这种大深度增量导致我们的算法检测它们上的“边缘”
为了实现这一点,我们需要每个表面的法线,以及从相机到表面的视角方向。
我们计算视角方向,
我们使用发法线深度是在屏幕空间中,所以我们摄像机视角方向也需要在屏幕空间才可以计算,
我们需要视角空间转换到屏幕空间,我们需要反向投影矩阵。
后处理脚本中我们计算视角方向

Shader中获取后处理传入的View
我们Shader计算屏幕空间中的视角方向。
片元着色器阶段来处理计算法线和视角关系
我们在合并输出,一个是边缘的颜色,一个原图颜色。
注意:记得在Volume增加颜色控制。
效果


Volume
后处理组件,我们在后处理组件中定义我们刚刚Shader中创建的变量属性,
效果

代码
Shader
Render
Volume
总结
实现后处理描边,比较复杂的地方是在Shader阶段,需要的数据很对,主要是获取深度和深度法线的计算方式,
深度获取记得开始管线

深度法线,我们使用SSAO系统给我们提供好的,

计算视角,需要把视角方向转换到屏幕空间进行计算,那一部分比较复杂,主要是 一个是处理UV,一个是处理使用顶点转换到屏幕空间。
资料
卡通渲染之描边技术的实现(URP) - 知乎 (zhihu.com)
URP/LWRP Shader实现描边效果_danad的博客-CSDN博客_urp 描边
Unity Outline Shader Tutorial - Roystan