编者按:

本文转载于公众号:戴老师的 CG 日常     

作者:戴巍

如需转载请与原公众号或原作者联系。


前言:

这是一份教程。介绍了在 substance designer(以下简称 SD )软件中制作两种 NPR(non physical render)滤镜的方法:

色调分离(posterize)像素化(pixelize)

原图

色调分离

像素化

其实还做了个半色调。但是感觉一套讲完篇幅有点长,先不讲了。大家觉得好玩以后再发吧。

目前来说我还没感觉到这几个滤镜在实际生产中有多么大的作用,或许仅仅只是一种屠龙之技。但其实还是非常棒的学习和研究方向:做的东西没太大用,练习过程中积累的知识和技能却很有用。

做这个教程起因是这样:前一段时间在群里(不加人了,不用留言问群号了)大家讨论这些特殊视觉效果要怎么做的时候,各位大神各显神通,Unity Unreal SD 等各种工具轮番上阵,在不同的软件里实现了这些效果。
看大家发的图片,着实让人头皮发麻,心里痒痒。

这两天有点时间,我也在 SD 里做了一番尝试。一是为了巩固和记录自己的学习成果,二是希望把这种学习和探索的精神继续辐射出去,影响更多人,遂有此篇教程。本文不是基础教程,需要有一定的 SD 使用经验才能读懂。读不懂也没关系,看看我在中间穿插的一些背景介绍什么的,也能学到不少软知识。

之前就有转载老黑在 Unity 中的实现方案。

这次轮到我了。

色调分离(posterize):

历史缘由:

老一点的朋友可能还记得我们小时候在学校电脑机房里学电脑的时候;或者在电脑室玩仙剑 98 柔情版的时候,那个时候可没有现在这么细腻的画面表现。很多时候你看到的画面都是有非常明显的一条条色带的。

这种色带的产生,很多时候都是因为显示位深有限,能够表达的颜色种类较少才导致的。

现在我们用的绝大多数显示器的位深度都是 24bits,也就是 8bit/channel,红绿蓝三通道各能显示 256 个色阶。这时候人看到的画面是顺滑的。

而以前的老显示器,居然用的是 3bit/channel,也就是红绿蓝三通道各能显示 8 个色阶。实在是太凄惨了。

吃惯了山珍海味的我们,总会悼念过往的美好,甚至连曾经8个色阶的画面都令人向往起来。等到我们学有所成,拿起手里的工具,有的时候,我们也会想再去追寻令人感动的源头。

原理:

如上文所言,色调分离目的是模拟每个通道 8 个色阶的效果。

我们可以这样去思考:如果我们创建一条亮度由 0-1 的渐变,默认显示效果是 256 个色阶的,看起来很顺滑。而我们只要把这个色阶均匀分成 8 等分,每一等分里全部填充成统一的亮度,并且这个亮度是这一块区域的平均。那么出来的结果就是 8 色阶的色调分离效果。
那么怎么实现呢。

在SD中实现:

这种要对画面进行逐像素处理的情况,当然要使用 pixel process 节点。

首先是 get float 2 节点获取 $pos(像素的 uv 位置),其实就是一般 CG 里用的 uv 通道,类似于 maya 里的 place2d 这个 uv 节点。

将uv信息输入 sample color 节点。这个sample color节点就类似于 maya 里面的 file 节点,可以从外界拿到图像输入信息。

现在可以正常显示输入进来的节点效果。比如我说如一个线性渐变:

现在我们才开始做具体的色调分离。这里用的计算方法是这样的:

设输入亮度为 x,目标色调分离色阶数为 4(这里就用一个简单的具体例子来说明);那么,先将原来的亮度乘以 4。原来的 0 还是 0,原来的 0.25 变成 1,原来的 0.5 变成 2,原来的 1 变成 4。原来 0 – 1 范围的渐变,会变成 0 – 4 范围的渐变。

核心操作在这里。这个时候我们用一个内置节点叫做 floor,对 4x 进行操作。这个 floor 的效果是对一个小数取整,只取跟这个小数相邻的较小的整数。

比如
floor(3.14) = 3
floor(1.99) = 1
floor(2.08) = 2

通过这样的方式,我们就讲原来顺滑的 0 – 4 渐变,切成了 亮度分别为 0、 1 、 2 、3 四个离散的亮度。这样其实就已经实现了我们想要做4色阶色调分离的目的。

但是还有个问题,在 SD 里不能显示超过 1 的亮度,所以我们要把亮度再压缩回 0 – 1 的区间。于是计算完的效果要再除以 4 。

最终计算公式如下:

result = floor(4x)/4

如果令色带数量为 n,则公式写为:

result = floor(n*x)/n

这张图是节点连接示意,其实就是我上面归纳的公式用节点这种图形化的方式表达出来而已。

你看到有个 X 那个节点,是单独拿出 RGB 三通道的R通道进行操作。这样出来的结果是针对红通道的黑白效果;之后我们可以对三个通道分别计算一次再合并到一起,就是最终的带彩色的效果。

如果我们改变数字 4 的数值,就可以改变具体的色阶数量。

我们可以在 pixel process 节点外面定义一个属性专门控制这里的色阶数量。方便以后使用。
退出 pixel process 节点,在外面的graph中双击地面,打开 graph 的属性设置,在 input parameters 一栏点击加号添加属性。

属性命名 levels(代表色阶数量),数据类型改成 Interger1(代表1位整数),默认值改为 8(默认就是我们的目标8色阶色调分离),最小值改为 1,最大值改成 256,clamp 开启,不让数值越过最小值和最大值。

返回 post process 节点, 创建一个 get integer 节点,这个节点获取刚刚我们自定义的 levels 属性。再创建一个to float 节点,讲整数转换成浮点小数,这样就可以和别的浮点小数一起参与计算了(类型不匹配的属性无法进行数学计算,必须先匹配类型)。这样就可以取代之前的 数值 4 ,在外界进行随意的参数调控了。

最后,将 RGB 三个通道拆分出来(swizzle float 1),分别进行同样的操作,再合并成一个 4 维向量(vector float 2 /vector float 4/ float = 1)输出。因为 SD 里 pixel process 节点只支持 1 个通道的输出,或者 4 个通道的输出。这里要做有颜色的效果,所以需要合成一个 4 维向量做颜色,其实也就是 RGBA。

最终效果预览

像素化(pixelize)历史缘由:

历史缘由:

近些年,8bit 艺术的复兴的架势如火如荼。如果你经常上 steam 关注一些独立游戏的话,你会发现,8bit 游戏简直是独立游戏的主力军一样。

各种各样的 8bit 游戏, 8bit 同人作品层出不穷。而现在的 8bit 虽然形式上和小时候玩的 FC(小霸王游戏机)上的游戏形式上看起来很像,但是制作方法、质量、审美等都不可同日而语。

所以如今的 8bit 艺术,既让你有熟悉的气息,又不会让你觉得廉价。是一种非常有趣而独特的体验。

根据我的观察,这个方向俨然已经要形成一个完备的学科了。里面大家都形成了各种亚风格,各种不同的制作手法和专有术语,对于没有仔细学习研究过的人来说是一头雾水。

现在我还不想深入去了解这个方向,只是抱着远距离围观和欣赏的态度。

这一节也要在 SD 中尝试完成以下 8bit 风格的效果,当然和各位天天做这个方向的差太远了。仅仅是一次简单的尝试。

原理:

将原图平均分成若干个方形区域,每个方形区域填充统一的纯色,这个纯色大致能代表这一块区域的颜色。这样就可以做到像素化。

这个做法和上一节讲的色调分离类似。之前是把 0 – 1 的均匀亮度,切分成几份整数。这一次是要把 0 – 1 的像素位置信息,切分成几分整数。

这里要说道这个 get float 2 节点获取的 $pos 属性,之前说过,代表的是图片的 uv 信息。具体来说,这个属性,在图片的左上角数值是(0,0),左方中间是(0.5,0),右上角是(0,1),右下角是(1,1)这样。相信大家已经理解了这个。

如果我们给 sample color 节点输入一个不变的二维向量,比如说(0,0),那么得到的结果是一片纯色,并且这个纯色的颜色是输入图像的最左上方像素点的颜色。如果输入一个不变的二维向量(1,1),那么结果是一片纯色,并且是输入图像最右下方像素点的颜色。

其实这是一个极端的例子,相当于把整个图片都变成了一个纯色大像素。

如果我们按照这个思路对画面进行切割,就可以把图片实现像素化。

下图就演示了这个思路。每一块大像素都填充完全相同的坐标信息,那么得到的颜色也是完全相同的,看起来就像是一个方形像素。

在SD中实现:

原理和之前相同,公式可以轻易得出:
令原始UV 坐标为 uv ,单方向像素格子数量为 n。

公式:
resultUV = floor(n*uv)/n

用节点的方式表达数学公式,如图(记得将计算完毕的uv信息输入到sample color 节点中去):

n = 1

n = 2

n = 4

n = 16

同样,在 graph 里定义一个属性叫做 pixelAmount 来控制像素数量。

合体:

最后这两个滤镜可以组合在一起使用。即有色调分离的效果也有像素化的效果。

如果前面的内容你都制作完成,那么合体其实非常简单。

大家看这个图,左上是像素化的节点树,右下是色调分离的节点树。黄色框框中的节点,功能是一样的。所以我们只要把他们 插 在一起,就可以完成合体。

视频教程:

手机看着累可以去b站看 http://space.bilibili.com/81540486?

由于上面介绍的东西涉及很多操作。视频是更好的记录操作的方式。看个热闹看文章就够了。想具体学会可以看教程。

最后:

看 gif 图的动画效果真的非常有趣,这应该是这个 filter 制作出来最好玩的地方了。

当然这套计算方法是相当简陋的。从动图也可以看出来,没有一个区域的加权平均算法,仅仅是对某一个位置进行采样,然后填充一片区域,在像素量比较少的时候,是很不准的。不过效果还好,改不改也无所谓。提升一下当然也是可以做到的。篇幅有限,再扩展下去要容纳不下了。

这里有我做的 sbs 文件下载地址,方便大家学习。节点里有些地方比文章中讲得更复杂。

https://trello.com/c/G9oIrcbz/9-nprfilters

Categories: News

相关文章(Related Posts)