UE4后期处理材质的一些应用(下) 您所在的位置:网站首页 ue4后期合成 UE4后期处理材质的一些应用(下)

UE4后期处理材质的一些应用(下)

2023-08-15 09:30| 来源: 网络整理| 查看: 265

       我们接着上部的内容继续讲解,如果没看过上部的朋友,建议先观看上部的教程,不然会有很多看不懂的地方

(由于图片上传的原因,评论有人反应清晰度不行,这里贴一个网盘链接,里面是所有用到的图片,有需要自取)

链接:https://pan.baidu.com/s/10pyB7gZQx-l_S4eSAEcBxw 提取码:1234

4、卡通渲染

       卡通渲染与正常渲染在画面上的主要区别有三点,一是卡通渲染的阴影没有柔和的过渡而是风格化强烈的,二是画面的色彩从多色阶降到低色阶,减少色阶的丰富程度,三是场景的描边勾线

       经过上面的学习,我们应该开始理解了后期处理材质的本质,就是通过不同的遮罩给画面添加不同的效果,而卡通渲染后期处理材质的本质就是找到阴影的遮罩,给这个遮罩内的部分添加一个比较深的颜色与原本的场景颜色叠加,然后给整体的色彩降低色阶的丰富程度,最后再给场景添加描边勾线

       我们一步一步来,首先想方法找到阴影的遮罩,阴影产生在原本场景中的背光面,使背光面的颜色变暗,但是场景中往往颜色比较杂,阴影的颜色也会比较杂,不利于观察分离出阴影的遮罩,所以我们先要去掉场景的饱和度

       这里使用Desaturation节点,这个节点的作用是去饱和度,让画面变成黑白灰色

       通过观察我们可以看到,目前的黑白画面中同一色块的区域阴影部分会出现比非阴影部分颜色更暗的情况,但是对比场景中其他色块区域还不能单纯从明暗上区分哪是阴影哪是非阴影

       这里要运用到数学的一个理论来解决,一个数字(非0)除以它本身,得到的答案是1,而黑白画面的每一个像素都可以看成是一个0-1的数字,越接近0越黑,越接近1越白,如果我们可以用这个画面除以一个没有阴影、AO、漫反射等影响的原始黑白画面,是不是就能得到相对比较纯净的阴影遮罩了

       大家一定会好奇,如果是一个非0的数除以0的话,会得到什么结果呢?(好吧,可能就我会这么好奇,所以有了下面的题外知识)

       在我的求真探索后,我得到了这样的一个结论:在UE4中,任意一个非0的数除以0会得到一个计算机无法判断的乱码数,正常情况下这个数得到的颜色和0一样但却是一个无穷大的数,但当这个数通过Clamp、Satruate节点运算后,会因为被排除而变成数字1

       Saturate节点(saturate(x)的作用是如果x取值小于0,则返回值为0;如果x取值大于1,则返回值为1;若x在0到1之间,则直接返回x的值)

       Clamp节点则是把所有的取值等比压缩或拉大到0与1之间

       我们可以用Debug来测试一下结果是不是真的是这样,先用常量1连接Debug,输出的值为1.0000006

       而当我们用常量0连接Debug,输出的值为0000000

       我们用常量1除以常量0,连接Debug后输出的值为llllllll.lllllll,这里我称它为乱码数

       这个乱码数在窗口的显示颜色为黑色,与数值0的显示颜色相同

       当这个乱码数通过Satruate节点限制到0-1后,输出的结果和常量1一样

       当这个乱码数通过Clamp节点限制到0-1后,输出的结果也和常量1一样

       一个显示颜色与0相同的乱码数,在经过限制(0~1之间)后数值却变成了1,不禁让我想看看他与一个接近无限大的数比大小的结果,所以有了下面这张图,我用if节点让乱码数与100亿比大小,如果乱码数比100亿大,那么输出数值5,如果乱码数比100亿小,那么输出数值0,最后我们得到的结果是数值5

       这个Debug测试验证了我上面的结论,至于0除以0的话,得到的乱码数为lllllll,与之前的略微不一样,显示颜色还是黑色,但是经过Clamp、Satruate节点限制后,输出的数值为0,大家有兴趣可以自己试一下

       回到我们的正题,为了我们想要的结果,现在需要找到一个没有阴影、AO、漫反射等影响的原始黑白画面来作为我们的分母

SceneTextureBaseColor(底色)定义的是材质的整体颜色,它接收 Vector3 (RGB) 值,并且每个通道都自动限制在 0 与 1 之间,是一个没有阴影、AO、漫反射等影响的色阶丰富度低的画面

       这个节点输出的结果就是我们想要的,同样的我们给SceneTexture底色节点一个Desaturation节点来去色,让画面变成黑白

       现在分子和分母都做好了,按照猜想,我们把他们相除就能得到相对比较纯净的阴影遮罩了,我们来试一下

       其中关于天空部分相除后的结果,这里添加了一个Saturate来使数据更精确(这里的天空因为是非0数除以0,应该是乱码数显示黑色,但由于添加了Saturate,天空的乱码数被排除后强制变成了1,所以显示为白色)

       这里额外提一下,由于部分材质球中加入了Metailc金属性、高光度等,当带这些材质的物体放在一个场景中时,相互会有一定的影响,所以会让结果有一定的出入

材质球连接着金属性、高光度、粗糙度车辆没有产生阴影的地方显示的颜色也为深色当我们把这几个属性去掉后车辆的颜色就跟周围环境一样得到了正确的白色

       现在的阴影部分还是会有一定的明暗深浅,我们用一个if节点来进一步降低色阶的丰富程度(两极分化),用Mask取黑白画面的一维数字与参数(Shadow Cutoff)对比,从而达到阴影分界值的作用,当黑白画面的亮度大于Shadow Cutoff时,我们输出1,当黑白画面的亮度小于Shadow Cutoff时,我们输出0

       这样就能得到一张纯黑白画面的阴影遮罩蒙版了(只有0和1,相当于两极分化去掉中间的过渡值),同时我们也可以通过控制参数Shadow Cutoff来改变阴影的分界位置

       得到了阴影遮罩,我们就可以用Lerp节点给黑白两部分分别上色,白色部分可以用色阶丰富程度低的SceneTextureBaseColor(底色),黑色部分可以用一个3维数组参数(Shadow Color)控制,由于SceneTextureBaseColor(底色)是一个4维数组,所以这里要添加一个Mask取RGB值

       不能说效果有错,只是现在的阴影是一个纯色,并不是很好看,我们希望的阴影是能透出一点原本的颜色的

       所以这边可以用Shadow Color参数与SceneTextureBaseColor(底色)相乘混合后再给阴影遮罩部分,这样阴影遮罩部分就是变暗过后的底色

       现在场景中的颜色就是我们想要的结果了,但是由于SceneTextureBaseColor(底色)得到的画面天空部分是黑色,我们要想办法得到天空的遮罩,然后用场景原本的颜色去填充,从而把天空还原出来

       在上部的《遮挡物体描边显示》中,我们利用了SceneTextureCustomDepth(自定义深度)除以一个很大的数来还原出开启自定义深度通道物体的黑白遮罩蒙版,这边天空没办法开启自定义深度通道,所以我们要用SceneTextureSceneDepth(场景深度)求出整个场景的景深图,因为天空离摄像机最远,所以在与某个比较大的数(比天空离摄像机的距离略小)进行对比的时候,只有天空的部分会比这个数大,我们就能得到天空的黑白遮罩蒙版了

       接下来就只需要用Lerp节点,通过天空遮罩蒙版作为Alpha,把之前的结果和场景原本的颜色进行混合,就可以把天空还原出来了

       现在已经完成了风格化阴影和降低色阶丰富度,还差一个场景的描边勾线

       在上部的《遮挡物体描边显示》学习中,我们通过用SceneTextureCustomDepth(自定义深度)计算开启自定义深度通道物体的所有像素点上下左右4个像素深度之和来判断是否为边界,这边我们可以用类似的方法来勾出场景的描边

       我们用SceneTextureSceneDepth(场景深度),场景深度图代表的意思是物体离摄像机越远数字就越大越接近白色,离摄像机越近数字就越小越接近黑色

       为了方便理解,我这边把场景深度图导入AE中进行讲解,这边我们假设右上角的自定义深度值是0.11、0.12、0.13、0.14、0.15、0.41、0.42,在0.15与0.42之间就是场景深度断层的地方

       当2个相同的数字相减他们的差为0,证明他们在场景中的深度相同,这边我复制一层位置不变,用A层减去B层画面全部变为黑色

       但是如果我们把一张场景深度图偏一点移像素后再相减,那么在场景深度有断层的附近将会有数值相对较大的差值出现,我们就可以用这种方法得到场景的描边勾线

      运用之前偏移像素点的方法,以SceneTexelSize作为偏移单位,接着与保存UV各个像素点坐标的 ScreenPosition进行相加,然后输出给SceneTextureSceneDepth的UV来完成场景深度的偏移,最后用原本的场景深度去与偏移后的结果相减

       但是这边AE中减去的图层向左偏移了,右侧为正数亮面,而UE4中是(-1,0)也向左偏移了,但是右侧为负数暗面,两个结果是相反的,因为UE4中是UV往左偏移的话相当于最终显示的图像是往右移动了,这个可以通过简单的测试验证

       这里我做了一张简易的贴图,方便测试观察

       把贴图连接到UE4的材质中,并用前面的方法将贴图的UV向左进行偏移,得到的画面却是向右偏移的

       同样的方法,我们向右偏移,得到了下面这张图

       当我们把向左偏移和向右偏移的差值结果相加后,就能得到黑白的描边蒙版了(这里AE里的颜色值只有0-1之间,而UE4中支持小于0或大于1的值,所以AE中的结果可能不够精确)

       下面这张是完整的左右偏移后相加的节点连接图,可以看到,连接在一起后,左右两边的描边清晰可见,而上下的描边却没有

        这是视窗中的画面,基本把场景的描边勾勒出来了

       现在的描边只有左右两边,上下是缺失的,我们用同样的方法补齐上下的描边,这样就把场景的描边勾线制作出来了

       但是这个描边勾线还不是最精确的,因为当在同一平面的场景深度时,线框就没了

       为了得到更精确的描边勾线,我们可以用SceneTextureSceneNormal(场景法线),可以让细小的凹槽部分(面的朝向不同)也能有颜色上的差异,而颜色的差异也就是数值上的差异

       可以看到大楼的窗户边缘浮现出了不同的颜色线条,与之前一整面都是黑色的结果不同

       同样用上面的方法再制作一遍(这边直接复制修改SceneTexture的ID就好了),然后会得到一个法线版本的描边勾线

       现在画面中增加了不少细节的线条

       完成之后我们用两者(场景深度与场景法线的结果)相比较取更大的一个值输出(有描边勾线的地方值为1,黑色部分为0,为了保留更多的描边勾线所以是取更大的值),就能得到我们想要的结果了,最后添加Saturate节点让过亮的部分限制为1,还可以在限制亮度之前用Multiply(乘以)一个参数(Outline Cutoff)或者Power(乘方)一个参数(Pow)来控制线框的密度(作用都是两极分化,可以消除细暗的描边勾线,也可以是提亮加粗细暗的描边勾线)

       有了描边勾线的黑白图之后,还是老方法用Lerp节点与之前完成的部分相连接,这里可以给白色部分输入一个3维参数(Outline Color)来控制描边的颜色,黑色部分输入之前完成的部分(这里最好放在制作天空蒙版还原天空颜色之前,因为现在的描边勾线蒙版天空部分也是有线框的,不然需要重新再还原一次天空)

       如果放在天空还原之后,天空这边会多出我们不需要的描边勾线

       最后我们再把结果连接上我们还原天空颜色的部分就大功告成了,下面是完整的节点和效果

       通过创建材质实例,我们可以编辑我们的参数来调整最终的效果

5、场景扫描探测

       这个扫描探测效果很多游戏和动漫中会用到,有了前面的学习基础,制作起来也不难,流程大概是先运用《卡通渲染》中的方法制作场景的描边勾线蒙版,然后给他赋予勾线颜色和辉光,再给场景中添加一个遮罩,遮罩内的显示为描边勾线,遮罩外的显示为场景原本的颜色,最后再排除掉人物本身或者其他需要排除的物体就可以了

       我们先从卡通渲染的材质中复制一下描边勾线的节点过来(可以把场景深度和场景法线都复制过来,这边我只复制了场景深度的描边勾线)

       这样我们就得到了场景的线框图

       接着给描边勾线添加颜色和辉光,我们用Multiply相乘,给结果分别乘上Outline Glow和Outline Color参数,这边辉光默认1,给了一个绿色的Color做对比

       然后我们就需要给场景一个遮罩,用来当做Lerp节点的Alpha通道,遮罩内显示描边勾线,遮罩外显示场景原本的颜色,这里我们用一个SphereMask球形遮罩节点在场景中添加一个球形遮罩来制作这个效果

SphereMask有四个输入参数

A:待检查的位置

B:圆心的位置

Radius:半径

Hardness:硬度,0是完整过渡,100是没有过渡(硬度是一个100的固定值,我们这边控制的是硬度的百分比,也就是0-1)

输出的结果:是一个0~1之间的数(A和B可以1~4维的vector),当A在B之外时,输出0;当A在B的位置时,输出1;A在圆内时,输出0~1,具体取决于是否有硬度以及位置

       简单的说就是检查A的所有位置,与以B为圆心且Radius为半径的圆做交集,A与B的交集部分输出0~1(当Hardness为1时,Mask边缘输出1,当Hardness为0时Mask边缘输出0-1的过渡,当Hradness为0-1时控制的是边缘的过渡区域大小),而B以外且A以内的部分输出0(黑色)

       这里的A实际上就是整个场景的坐标位置,B就是你想生成球形遮罩的圆心,我们用一个简单的测试来帮助理解,我们给A一个WorldPosition绝对世界坐标,然后把角色在场景中位置的三维数值给B,随便给一个半径的数值300,然后控制Hardness数值观察结果(数值分别为0、1、0.8)

       当Hardness数值取0时

       球形遮罩颜色偏灰,边缘羽化明显

       当Hardness数值取1时

       球形遮罩颜色纯白,边缘无羽化,为硬边缘

       当Hardness数值取0.8时

       球形遮罩中间为纯白色,边缘略带羽化

       可以看到以角色中心位置生成了一个半径300的球形(3D立体),根据Hardness的不同数值,球形边缘的羽化程度不同

       理解了之后我们把它作为Lerp的Alpha,而在《卡通渲染》中用到过SceneTexture后期处理输入0来代表场景原本的颜色,所以蒙版黑色的部分(即Lerp的A)用SceneTexture后期处理输入0接入,蒙版白色的部分(即Lerp的B)用前面的描边勾线接入,这里添加了2个参数节点用来替换Radius与Hardness的常数节点,通过材质实例,可以方便控制与观察效果

       可以看到已经有了效果的基本雏形了,但是边缘的过渡看着不是很合适,没有边界的感觉,我们可以给球形遮罩边缘也添加一圈描边

       我们知道边界是羽化的部分,羽化的地方是一个0-1的值,越接近蒙版边界,这个值越接近0,所以这边可以用if节点,让这个值和0.9以及0比较,小于等于0的值输出0黑色,大于0小于0.9的值输出1白色,大于0.9的值输出0黑色,这样就能把边缘的描边提取出来了(0-0.9的部分)

       但是这样需要用2个if节点,然而我们把这个步骤移到Lerp节点之前的话,Lerp节点会帮我们把“判断是否小于0的”这部分还原成场景原本的颜色(小于等于0的部分就是球形遮罩的外面),所以这里只需要1个if节点判断与0.9的大小关系就好了,然后把得到的边界描边蒙版与最初的整个场景的描边勾线蒙版融合成一个蒙版,这边可以用Max节点,即两个蒙版的白色数值1的部分全部保留,其他为黑色0

       边界就制作好了,可以通过调整参数Hardness或者if节点的B值来控制边界的宽度

       现在我们的角色会受到扫描效果的影响,我们可以用前面学过的知识来把角色或者其他物体排除掉,还原成场景中原本的颜色

       这里我们用Lerp节点,把角色的带遮挡的遮罩作为蒙版,遮罩白色部分为原有结果,黑色部分还原成角色原来的颜色

       现在我们的角色就不受这个扫描探测的效果影响了

       效果做好了以后,我们怎么去控制这个动画效果,让他慢慢扩散开呢?后期处理材质中的参数没有办法直接加入定序器中K帧做动画,但是材质参数集可以加入定序器K帧,所以我们可以用材质参数集来替换掉后期处理材质中的参数节点,然后到定序器中K帧来实现动画效果

       首先我们先创建一个材质参数集,然后添加我们需要替换掉的Radius参数名称

       然后把材质参数集拖入制作的后期处理材质中替换掉Radius参数

       接着打开定序器,点开左上角绿色轨道按钮,选择相对应的材质参数集轨道

       这样我们就可以给Radius进行K帧来控制场景扫描探测的动画了

       当然如果角色需要移动的情况,还需要另外把SphereMask的B值(圆心)加入定序器

       而如果是制作游戏的话,这个效果还可以通过给角色蓝图中添加节点绑定按键来驱动,这里我就不讲解了,直接放一个蓝图的节点(Loc为SphereMask的B值即角色坐标,TimeLine需要双击点开K帧数值跟随时间变化幅度),后期处理材质部分也需要在SphereMask的B值与Radius处做修改,Loc材质参数集获取角色位置输入给SphereMask作为蒙版圆心,Radius材质参数集需要乘以一个倍数(TimeLine输出的数值为0-1,所以如果是600的Radius需要乘以600的常数作为倍数)

       在材质参数集中添加一个新的材质参数Loc作为圆心的位置

       在后期处理材质的球形蒙版处替换掉原本的Loc参数,并用Mask节点取RGB值,在Radius处乘以一个常数600(这边的常数为你需要的球形半径值)

打开角色的蓝图在事件图标中添加下面的节点(Timeline需要双击点开进行K帧,即0-N秒内,数值从0-1进行变化)

       注意不要忘了修改Timeline的总长度,否则当你第二次按键想要把扫描探测的动画回收时需要等很久

以上就是全部内容了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有