欢迎光临散文网 会员登陆 & 注册

【UE4后处理材质】《看门狗2》主角马赛克效果模板

2021-07-11 13:47 作者:吃黑蒜的喵酱  | 我要投稿

一、前言:

    前两年玩过一段时间《看门狗2》,虽然个人觉得游戏内容非常重复、剧情拖沓,只玩了一半就躺在硬盘里吃灰,但里面的很多美术效果和创意都非常值得学习和参考。比如在主角出现在自己远程操控的摄像头画面中时,主角的身体会被蒙上一层马赛克。这篇文章就分享一下我对于这个效果的制作思路和实现方法,文章的结尾会实现一个基于Custom Stencil的目标物马赛克效果的基本模板,在此模板的基础上进行自定义修改,即可实现你想要的任意扩展效果

二、效果分析

    首先,我们可以很容易的分析出这个画面主要是由原始画面(当然游戏画面中还有许多其他后处理效果,这篇文章中不会讨论)与覆盖在角色身上的马赛克两个主要部分组成。

    我们可以将这个效果理解为:利用角色模型轮廓处理生成一个马赛克遮罩,并在遮罩内对画面进行马赛克化处理,遮罩外输出原始画面

    为了实现这个效果,我们需要了解两种关键后处理效果的实现方法:

    1.画面的马赛克化后处理

    2.覆盖角色的马赛克遮罩

三、效果实现

1.马赛克效果实现步骤

    为了实现马赛克后处理效果,我们首先需要了解屏幕空间的坐标,将ScreenPosition中的Viewport UV通过后处理材质直接输出,你会看到如下画面:

    可以看到屏幕空间的UVW坐标类似模型纹理的的Tex Coord(这里把Tex Coord输出会的得到相同的结果),可以理解为窗口即是一张1X1的UVW map,横轴与纵轴的长宽比等于窗口尺寸的长宽比,知道了这个结果,我们就可以使用与纹理马赛克化相同的方式对画面进行马赛克化操作

    通过以下逻辑,对UV做阶段化处理,即可初步实现马赛克画面:

    但此时得到的并非我们想要的正方形马赛克效果,因为窗口UV长宽比受窗口长宽比影响,所以输出的马赛克块的长宽比与窗口长宽比相同,为了在任何窗口比例下得到正方形马赛克块,我们需要利用窗口尺寸对窗口UV做非等比缩放处理:

    把刚刚得到的阶段化的窗口UV连接到Scene Texture并输出,可以得到正方形马赛克块处理后的画面:

马赛克化画面

    把得到的窗口UV处理逻辑保存成材质函数,便于在后续制作中做扩展处理:

2.角色区域遮罩实现步骤

    为了实现角色遮罩的效果,我们首先需要了解引擎中的Custom Stencil后处理功能,这个功能允许我们为开启了Custom Depth的物体设置单独的Stencil Value,并通过Scene Texture在后处理材质或半透明材质中得到对应的遮罩(这里需要注意的是,设置了Stencil Value的半透明材质无法在后处理中通过Scene Texture获取到其对应遮罩)

    接下来的几步可以帮助你理解和使用

    首先,为了使用此功能,我们需要在项目设置中开启Custom Stencil:

    然后,在角色模型的细节面板中勾选Custom Depth,并为Stencil Value设置任意大于0的整数(默认区间0~255):

    接着,在后处理材质中通过如下逻辑获取对应的角色遮罩,这个逻辑可以让你根据输入的Stencil Value得到一个非0即1的遮罩(对应Stencil Value的模型区域为1,其余区域为0)

    把得到的遮罩输出到窗口中,即可得到遮罩的画面:

    把刚刚得到的遮罩保存成材质函数,便于后续使用和扩展:

    现在,我们已经得到了角色模型的遮罩,但只是原始模型轮廓遮罩,并不适配马赛克块

    所以,我们需要对角色遮罩做相同的马赛克处理:

    把马赛克处理后的角色遮罩输出,可以得到如下画面:

3.马赛克与原始画面混合

    现在,我们得到了马赛克化后的画面,并得到了马赛克化的角色遮罩,可以先通过线性插值将马赛克与原始画面进行混合:

    把插值结果输出,可以得到如下画面:

    可以看到马赛克覆盖到了角色身上,但相对于角色,马赛克的位置整体偏向右下,使角色的左上半边暴露在马赛克外

    这是因为我们使用的UV阶段化逻辑中,每一阶UV块的坐标值取自于当前块左上角点对应的坐标值,所以每一个马赛克块的颜色填充取自当前块左上角点对应的原始画面颜色

    因此,当色块的左上角点刚好处于角色原始遮罩左边时,即使色块覆盖到了角色遮罩区域,依然会被填充为取自色块左上角点的黑色,导致角色左上半边没有马赛克遮盖

    为了矫正马赛克的覆盖区域,我们需要修改UV阶段化逻辑,让马赛克向左上方移动半个色块的距离,使色块的填充色取自色块中心点对应的原始画面颜色:

    把修改后的结果输出到窗口,可以得到如下画面:

    可以看到马赛克位置已经与角色完全重合,但在四周依然角色原始画面暴露在马赛克之外。把马赛克区域输出改成黑色,可以方便的观察到角色原始画面暴露的部分:

    接下来,为了扩大马赛克遮罩使剩余的角色画面被马赛克覆盖,我们把马赛克遮罩向 (1,0),(-1,0),(0,1),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1) 共8个方向分别偏移,并将得到的结果与原始马赛克遮罩对比取最大值。为此我们需要在UV阶段化逻辑中加入UV偏移输入:

    把修改后的材质函数按照上述逻辑连接,可以得到如下材质逻辑图:

    把得到的插值结果输出,可以得到如下画面:

    现在,我们已经得到了一个完全覆盖角色的马赛克效果,如果你想要在一个目标与摄像机距离相对固定的视角下使用此效果,目前已经实现了可以满足你需求的目标物马赛克效果模板。接下来是我对一些非固定视角下的修改和应用

四、扩展应用

    在大范围运动视角下,由于马赛克的尺寸相对于窗口尺寸保持不变,当我们把视角拉远时,或由于马赛克相对于角色过大无法分辨角色轮廓,或由于马赛克遮罩精度降低而出现未完全覆盖角色的情况,当我们把视角拉近时,会由于马赛克相对于角色过小,几乎还原画面细节,失去了马赛克的原有作用。为了解决这个问题,使马赛克尺寸相对于角色保持不变,我希望利用角色坐标与摄像机坐标动态计算马赛克尺寸

    为了方便预览和使用,我把材质混合模式从后处理改成半透明,在角色身上附加一个顶点法线方向向内的球体模型,并把材质引用设置为我们的半透明材质,接下来,在材质逻辑中把原来的马赛克数量变量,改为利用球体与摄像机距离动态计算的材质逻辑,并禁用材质的深度检测:

球体细节面板

    

    现在,就得到了一个动态计算马赛克尺寸的后处理效果,随着摄像机的拉近拉远,马赛克尺寸相对于角色会保持不变:

最终结果
球体尺寸

    感谢你看到这里,如果你对这个效果有其他的想法或实现方法,请在评论区里和我分享讨论吧!

【UE4后处理材质】《看门狗2》主角马赛克效果模板的评论 (共 条)

分享到微博请遵守国家法律