UE|后处理材质的应用


前言

通过后处理材质来制作描边、风格化渲染的效果。


一、基础知识

Custom Depth

UE的渲染缓存如下图所示,其中的Scene Depth表示场景中的点到摄像机的距离,距离越远,数值越大,反应在深度图上就越白;距离越近,数值越小,深度图上就越黑。
在这里插入图片描述
在UE中还有另外一个渲染通道叫做Custom Depth,其特点是:选择参与该通道渲染的物体才会被渲染;渲染的深度和Scene Depth没有区别;没有参与渲染的部分都是白色,其数值可以看作无限大(很大的正整数)。
在蓝图中选择网格体,勾选上Render CustomDepth Pass,即可参与自定义深度渲染。
在这里插入图片描述

后处理材质

后处理材质在最后进行渲染。
要想使用后处理材质,需要为场景中添加后处理体积:
在这里插入图片描述
类似于KillZVolume,这个体积所包裹的范围就能够渲染后处理材质,我们可以通过缩放调整大小,也可以直接勾选如下选项设置为无限大范围:
在这里插入图片描述
在后处理体积的细节面板中添加后处理材质,被添加进该数组的后处理材质才能被渲染:
在这里插入图片描述

二、描边效果

后处理材质的使用

在content目录下创建材质,双击材质进入材质界面,在左下侧设置材质域为Post Process:
在这里插入图片描述
此时材质的输出节点将只能连接Emissive Color。我们可以尝试增加一个常量,分别设置值为0和1直接连接Emissive Color,可以看到分别显示为黑色和白色:
在这里插入图片描述
在这里插入图片描述

再多测试几个值可以发现,从0~1颜色从黑色像白色逐渐过渡,例如0.5就是灰色,超过1就是纯白色。

如果我们想要通过后处理材质渲染画面的原始颜色,可以使用SceneTexture节点:
在这里插入图片描述
但注意,如果直接连接输出节点会报错,需要先选择SceneTexture节点,在左下侧设置Scene Texture Id为PostProcessInput0,此时再连接Emissive Color,画面将为原始颜色。
在这里插入图片描述

SceneTexture节点可以看作是一个循环,它将遍历屏幕的所有像素点,对每个像素点都执行计算。例如我们选择SceneTexture的Scene Texture Id为BaseColor,那么它将会计算每一个屏幕像素点的BaseColor。

自定义深度

SceneTexture节点还可以选择Scene Texture Id为CustomDepth。首先我们按照第一节的方法将第三人称模板的角色的网格体添加进入自定义深度渲染,此时对于屏幕的CustomDepth,除第三人称角色外的屏幕CustomDepth值都视为无限大,第三人称角色对应在屏幕上的CustomDepth是一个正数。
我们可以通过除以一个很大的数让CustomDepth限制在0~1之间,如下图所示:
在这里插入图片描述
直接连接到Emissive Color后显示如下:
在这里插入图片描述

描边效果

1.思路
实现描边的思路是,通过一定的边缘检测算法找到角色渲染到屏幕上的边界像素点,然后将这些像素设置为想要的描边颜色,其他部分都设置为原始颜色。
提供一种简单的边缘检测算法:
参与自定义深度的物体内和边界上的像素点:CustomDepth值为一个正数;物体外的像素点,CustomDepth值为很大的正数(视为无限大)。
对于屏幕上的任意一个像素点,如果它位于物体内部,那么其上下左右四个像素都在物体上(内部或者边界),四个像素的CustomDepth值之和为一个较大的正数;如果位于物体边界,那么上下左右一定存在CustomDepth值为无限大的像素点,四个像素的CustomDepth值之和为无限大;对于物体外的像素,上下左右的邻居像素的CustomDepth值之和也为无限大。
通过这种方式,我们就将内部像素与边界像素区分开来了,那么只需要再区分物体上的像素和物体外的像素,就可以通过逻辑与运算找出边界像素。而通过每个像素点自身CustomDepth的值很容易就能区分出物体外像素和物体内像素。


2.区分内部像素和边界像素
获取到每个像素点的上下左右相邻像素点的自定义深度值之和
SceneTexture节点,返回的是屏幕中每一个像素点对应的值,我们也可以指定屏幕UV返回对应的值。
在这里插入图片描述
屏幕UV坐标如下图所示,坐标原点在左上方,横轴为U,纵轴为V,U、V的范围都是[0, 1]。
在这里插入图片描述
SceneTexelSize可以理解为屏幕上的像素大小,通过ComponentMask节点的R和G通道可以拿到屏幕像素的宽和高,如下图表示屏幕像素的宽:
在这里插入图片描述
ScreenPosition输出当前被渲染到屏幕空间的像素的坐标,有两个输出节点,ViewportUV返回的是屏幕空间正在渲染的像素点对应的UV坐标,范围为[0, 1];PixelPosition输出的则是像素在屏幕上的坐标,其值为ViewportUV*ViewSize,范围为[0, ViewSize]。
在这里插入图片描述
通过如下方式可以获得UV坐标下的四个单位向量:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上方的邻居像素为例,直接将ViewportUV与(U, 0)向量相加,即是每一个像素的上方邻居像素:
在这里插入图片描述
计算邻居像素自定义深度和如下:
在这里插入图片描述

计算邻居像素也可以使用BlurSampleOffsets节点实现

将这个和减去一个很大的数(这里是1e+8),然后夹值到0~1在四舍五入,这样物体边界和外部像素点的值为1,物体内部像素值为0:
在这里插入图片描述


3.区分物体上像素和物体外像素
在这里插入图片描述
让上面两个结果相乘,则1表示边界像素,0表示内部或者外部像素,因此我们达到了找边界的目的。


4.描边
使用Lerp节点,将根据Alpha的值混合A和B输出,如果Alpha=0,则输出A,如果Alpha=1,则输出B。
在这里插入图片描述
描边效果如下:
在这里插入图片描述
可以发现描边有锯齿和抖动,可以在后处理材质的左下侧面板中设置Blendable Location为Before Translucency,应用后可以发现描边变得稳定平滑了。
在这里插入图片描述
在这里插入图片描述

遮挡描边

为了实现物体被遮挡时描边,可以同时使用Scene Depth和Custom Depth。
如下图所示,当物体被遮挡物遮挡时,其CustomDepth一定大于其SceneDepth,而当遮挡物不存在时,二者的值相同。因此可以直接使用CustomDepth - SceneDepth,对于物体外的像素点,其值始终大于0;对于物体上(内部和边界)的像素点,没有遮挡物时,其值为0,存在遮挡物时,其值大于0。
在这里插入图片描述
具体可以相减后先夹值到[0, 1]再四舍五入,此时外部像素和被遮挡的物体上像素值为1,未遮挡的物体像素值为0。将这个结果与上一部分我们确定的边界相乘,则1表示被遮挡时的边界。
在这里插入图片描述
最终遮挡描边效果如下:
在这里插入图片描述

三、风格化渲染

这里记录卡通风格的渲染。
注意一般如果游戏要使用卡通风格化渲染,美术一开始就需要这样设计,如果使用写实风格的资源去进行卡通风格化渲染,可能会看起来怪怪的。此处使用第三人称模板中的角色,使用如下材质:
在这里插入图片描述
在这里插入图片描述
卡通风格的特点:颜色色阶简单,以大色块为主;风格化阴影,即阴影部分与非阴影部分变化直接而明显,阴影部分整体颜色变化单调一致;物体上在有起伏的位置有很明显的描边,如下图(无主之地)。
在这里插入图片描述

1.颜色、阴影处理

首先是颜色色阶,我们在后处理材质中连接上SceneTexture: BaseColor,只包含基础颜色的画面色阶简单。
在这里插入图片描述
对于阴影,我们先使用Desaturation节点将原画面转换为灰度图:
在这里插入图片描述
在这里插入图片描述
再将BaseColor转化为灰度图:
在这里插入图片描述
使用原画面灰度图直接除以BaseColor灰度图,就可以找到阴影。可以这样理解:对于非阴影位置,我们可以近似理解原画面灰度图和BaseColor灰度图基本一致,二者相除的值接近于1;对于阴影位置,原始画面灰度图的值一定小于BaseColor灰度图(更暗,灰度图的值就更小),二者相处的值小于1。因此我们就能够区分出阴影。

之所以要灰度化,就是为了减小除颜色外其他属性对我们找阴影边界的影响

在这里插入图片描述
Saturate节点用于夹值到[0, 1],效果如下:
在这里插入图片描述
接下来只需要将等于1的部分设置为BaseColor,等于0的部分设置为阴影即可:
在这里插入图片描述
降低色阶以及风格化阴影的效果如下:
在这里插入图片描述

2.描边

这里的描边思路和上一节的遮挡描边类似,通过邻居像素来确定描边位置。具体做法分两步。
首先是利用场景深度找深度变化剧烈的位置。即通过当前像素与的上下左右邻居像素的场景深度之差来判断深度突变的位置。
以纵向深度为例,第一列表示纵向深度,第二列表示减去下方邻居深度的值,第三列表示减去上方邻居深度的值,可以发现深度突变处的值很大,而非突变处则较小,因此通过这种方式可以找到深度突变的位置。
300 -10 xxx xxx
310 -10 10 0
320 -10 10 0
330 -470 10 -460
800 -10 470 460
810 -10 10 0
820 xxx 10 xxx
下面的蓝图以计算当前深度和下方邻居深度为例,还需要计算上、左、右,然后相加
在这里插入图片描述
直接连接后处理材质的Emissive Color效果如下:
在这里插入图片描述
为了增加描边细节,还可以再按上述方式处理一边法线,即将SceneTexture: SceneDepth修改为SceneTexture: WorldNormal,然后再取Max,效果如下:
在这里插入图片描述
最后使用Lerp节点连接上描边颜色和降低色阶、风格化阴影后的颜色即可:
在这里插入图片描述
注意之前使用BaseColor,天空部分都是一片黑色,我们需要在最后添加一层天空遮罩的逻辑:
在这里插入图片描述
最终效果如下:
在这里插入图片描述

  • 41
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值