Unreal Engine 4 卡通轮廓线(Toon Outlines)教程 之 后期处理法(Post Process Outlines)

文章目录

    • 后期处理法(Post Process Outlines)
      • 理论部分(译者注,头疼可跳到下面的实操部分)
        • 什么是卷积(Convolution)li>
        • 拉普拉斯边缘检测(Laplacian Edge Detection)
      • 实操部分(译者注)
        • 创建边缘检测算子(Laplacian Edge Detector)
        • 创建像素抽样函数(Sample Pixel Function)
          • 小结
        • 卷积
          • 小结
        • 使用阈值
        • 创建粗线
        • 添加到原始图像上

后期处理法(Post Process Outlines)

理论部分(译者注,头疼可跳到下面的实操部分)

使用边缘检测(edge detection)的方法也可以制作轮廓线。这种技术的关键就是检测一幅图像各个区域间的不连续性(discontinuity)。如下图所示不连续性有很多种类型:

译者注:法线的不连续性、深度的不连续性、颜色的不连续性以及亮度的不连续性

对于每一个像素,都用核实体去乘以它的相对应像素。(译者注:这句不好理解,看下面的例子就明白了)以嘴部左上角的像素为例(在这里为了简化运算,我们把图像转成了灰度图)

最后把所有的乘积加在一起,让这个乘积作为中心像素新的值。本例中,新的值就是0.5 + 0.5即1。下图就是每个像素卷积处理完毕以后的结果:

注意:你可能已经发现,在很多图像处理软件中,这些东西被称之为滤镜(Filter)。实际上,图像处理软件就是通过卷积来实现滤镜的。你甚至可以在Photoshop上自定义核来进行卷积运算。

我们一般使用拉普拉斯算子(Laplacian)进行边缘检测,即拉普拉斯边缘检测(Laplacian Edge Detection)。

拉普拉斯边缘检测(Laplacian Edge Detection)

那么,拉普拉斯边缘检测的核是什么样的呢是我们刚刚在上一部分用到的那个!

首先,我们用肉眼找到一个图像的“边缘”像素(下图红色中心那个像素),把这个(一维拉普拉斯算子)核放到上面,然后它的计算卷积。

下面的图表就是用这个图像所有像素进行卷积后结果绘制的,我们可以看到所有的边缘像素的卷积结果都远离零点。

我们使用一个纹理坐标(TextureCoordinate)来获取当前像素的位置。比如,如果当前像素在中间,那么它的返回值就是(0.5,0.5).这个二维向量,我们称之为UV。

然而,这里存在一个问题。因为图像的分辨率可能发生变化,使得像素大小也随之变化。如果把同样的偏移量(0.01,0)用在200×200像素的图像上,它抽样的像素就会是右数第2个。

为了解决这个问题,可以使用节点来返回像素大小。我们如下操作即可:

注意: 材质函数就类似于我们在蓝图和C++中使用的函数

下面的部分,我们将把节点复制到材质函数中,然后创建一个输入引脚来获取偏移量。

创建像素抽样函数(Sample Pixel Function)

首先找到MaterialsPostProcess文件夹。单击Add New然后选择Materials & TexturesMaterial Function来创建材质函数。

首先,我们需要创建一个创建一个节点作为接收偏移量的Input节点。

接下来,我们得用偏移量乘以像素大小。然后通过添加下图中高亮的节点让结果和纹理坐标相加:

小结
  1. 偏移量通过Vector2SceneTexelSize相乘而得来。它是UV空间上偏移量。
  2. 让偏移量和TextureCoordinate相加获得一个相距当前像素距离为(x,y)的像素。
  3. SceneDepth使用所提供的UV来抽样相应像素,然后把它输出。

这就是材质函数的全部了。点击Apply,然后关闭MF_GetPixelDepth

注意: 这时可能会看到一个 错,可以忽略它,因为这个函数将用于后处理材质,没有问题的。

接下来,就要用这个函数来进行深度缓冲上的卷积运算了。

卷积

首先,为每个像素创建偏移量节点。因为核的角上都是0,所以可以不用管它们。这样,我们对左、右、上、下4个像素创建就可以了。

打开PP_Outline材质,按如下所示创建4个节点:

  • (-1, 0)
  • (1, 0)
  • (0, -1)
  • (0, 1)

于是,我们获得了每个像素的深度值。

接下来是乘法阶段。因为周围像素的乘数都是1,你可以不用乘它们;但必须对中心像素乘以-4(对应上图最下面的那个函数)。

目前还有一些问题。首先,有些“边”在只有一点深度差的地方(其实算不上边)。其次,应为背景是球体,所以呈现一圈一圈的。如果你只想对 格模型进行检测,这算不上是问题。但如果你要检测整个场景的边缘,这些环线就不行了。

我们可以通过阈值来修正这些问题。

使用阈值

最终连线如下所示:

注意: 可以创建一个 PP_Outline材质的材质实例来控制阈值和DepthCutoff。

边缘检测运转良好,但是如果想要粗一些的线该怎么办们就需要更大的核。

创建粗线

一般来讲,大的核对性能影响会更大一些。因为我们需要采样更多的像素。有没有方法能够使用大核但是却拥有3×3的核一样的性能呢使用空洞卷积或膨胀卷积(dilated convolution)

在空洞卷积中,我们仅仅是把偏移量放得更远一点。让每个偏移量乘以一个名为膨胀率的标量。膨胀率决定了每个核元素之间的距离。

这样每个周边抽样像素将会远离中心像素3个像素。

接下来如下连接:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年11月20日
下一篇 2020年11月20日

相关推荐