二次元描边技术现状和发展(上)

轻舟

2021-12-1711679次浏览

0评论

31收藏

7点赞

分享

很多时候我们做NPR渲染尤其是日式卡渲的时候,都知道描边是很重要的一个组成部分,手游上通常使用法线外扩的技术来实现这一效果,仅此而已。但是实际情况又是如何呢,下文结合现有二次元项目以及此领域相关历史背景、理论发展、工程实践诸多方面的一些综合性思考,希望可以抛砖引玉。

首先我想先把问题思考清楚:描边的本质是什么,它从何而来(Where),用来做什么(What),怎么做(How),未来将如何发展。

一、What & Where

1、描边本质

  • NPR VS PBR

    - PBR有完备的物理公式Rendering Equation(Kajiya 1986)支撑,所有的技术都是围绕此方程展开,程序员实现了正确的公式,美术制作出正确的Albedo/Roughness/Metalic贴图,就可以获取一个相对物理正确的效果。本质是因为PBR是真实3D世界的模拟,追求的是共性的抽象(公式)。

    - NPR本质是2维绘画(比如日式漫画、国画、油画等等)的模拟,属于艺术的范畴,艺术追求的是特性,也就是风格,千篇一律是无艺术价值的。所以利用共性思维来研究艺术,就是一种本末倒置思想。看似过于完美的线条,也绝对不是人的手笔。所以怎么样使用计算机,可以做好NPR这件事情就是我们要探讨的问题。

  • NPR中描边的是什么

    - 描边本质上是一种线条。

    - 由于赛璐璐风格的画面以色块为主,当两个遮挡关系很明显的组件颜色很接近时,如果没有线条,那么二者将丢失遮挡关系,进而导致画面层次丢失,最终造成视觉混淆。简而言之:线条的作用就是增强对比,维护遮挡关系。

    - 使用线条来绘画,是历史决定的。笔墨纸作为早期的创作者能够掌控的工具,以线条为主要载体(文字、绘画),能够高效的进行内容表达。

    - 每个人的差异化,以掌控工具的形式表达出来,被其他人认可,便形成了风格。

2、从何而来

中国画用线条表现物象的手法称为“白描”,或称为“线描”。最初,白描是以粗细均匀的线条为主的。

但经过历朝历代的发展,已经演化出来不同的艺术风格。

与此类似,当前的NPR线条也是以均匀线条主导,所以未来要做真正的风格化,历史可以作为我们的指路明灯。

"线条有粗细、曲直、连续、疏密几类主要变化。
其中画中的线条通过穿插、重叠、藏露表现画而层次,
通过快慢、转折、顿挫表现运动的节奏和韵律,
通过疏密表现画面的黑白色阶."——《解构二次元以及游戏实现方式》

白描里的描法

参考 绘画中的线条艺术

我们再来看看传统黑白格漫画的绘制过程

b站链接

基本上都要遵循"故事->分镜->草稿->线稿->上色"这么个过程

在不同漫画家的手下,线条逐渐成为作者的特性标签。

参考荒木的NARUTO

荒木作为日本目前最具个人特色的漫画家,他的作品,不用署名,一眼基本都可以看出是他画的。

  • 二次元的本质依然是内容传达,漫画/动画由于历史原因成为了内容载体,最终演化成为了艺术家的风格标签。

  • 随着计算机的普及,绘制这个过程又出现了新的形式(手绘板,各种辅助绘制软件加持)。

二、How

我们如果要在计算机上实现风格化的卡通画面,应当如何去做呢。

罗生门

有一天策划同学想做一款二次元风格的游戏,有一天,他找了4位不同专业的同学,想了解下描边应该怎么实现。

  • 美术同学:描边就是画画。

  • CV同学: 描边就是边缘检测,再进行卷积。

  • CG同学: 描边就是在3维空间中判断多边形和视角的关系。

  • TA: 描边就是法线外扩。……

虽然这只是个段子,但是你会发现,其实不同职能(业),解决同样问题的方式会不太一样。

  • 艺术家通过抽象事物之间的独有特性,使用线条/颜色或者是其他方式,进行艺术表达。

- 直截了当的使用笔或是手写板。

  • 科学家通过抽象事物之间的共有关系,使用计算机解决通用问题(物理模拟)。

- 使用程序模拟线条,甚至基于现有风格进行抽象,尝试使用机器模拟艺术家的风格。

最终我们选择的方式成为定势后,想要突破当前的困境,就需要看看其他领域,同样的问题是怎么处理的。而一个好的解决方案,可以综合各家之长,在有限的硬件资源上,达到最好的效果。


通常来说,计算机模拟的线条基本都是基于Geometry表达的网格数据和所处的场景信息(ViewMap/Gbuffer)。根据应用场景通常有以下技术类型:

1、传统的可见性线条提取+视线剔除。

  • Blender Freestyle

  • PSoft Pencil +

2、将几何&Mask信息写入Gbuffer,基于ScreenSpace进行逐像素的卷积(filtering),同时进行线条提取和线条着色。常用于基于Deferred管线的传统日式PC/主机游戏。

  • 《二之国》

  • 《蓝色协议》

3、基于GPU光栅化管线,借助Vetex&Fragment Shader,常用于Forward管线下的Mobile游戏。

  • 《Guilty Gear Xrd》


思路一:基于模型结构的线条模拟

1. 基于CPU的线条模拟

理论上,计算机模拟线条的思路和方法包含下面几个步骤。

  • 线条定义

  • 线条提取

  • 线条绘制

线条定义和提取

我们以Blender的FreeStyle为例,了解下线条的常见类型。

参考链接:
https://docs.blender.org/manual/en/2.92/render/freestyle/parameter_editor/line_set.html#edge-types

  • Silhouettes View相关

    Draws silhouettes around your closed objects by rendering lines where the surface normal transitions between pointing toward and away from the camera.

    提取时设V为视向量,N1,N2是边的两个相邻的法向量,当(N1·V)*(N2·V) < 0的line。

  • Contours View 相关

    Draws lines around each object, separating it from other objects behind it, or the scene background.

    通常用来提取外轮廓。External Contours会把相同的object进行merge,只包含最外层轮廓。提取算法

  • Creases View 无关

    Crease是在给定的阈值角度(图例135°)的前提下,夹角<=阈值的那些"折缝"边。

  • Borders View 无关

    遍历所有lines,如果某一条边仅和一个面相邻,那么这条边就是Border

  • Edge Mark(Custom)

    用户自己标记的那些line

线条的绘制(Shade)

基于笔刷的勾线方法,通常分为以下几步,以Freestyle render为例。

《Programmable Rendering of Line Drawing from 3D Scenes》 GRABLI 2010

这是条可编程的NPR渲染管线,Select Chain Split Shade是Programmable Stage.

1、Collect Scene Properties(depth, normal, line……)

2、Select: 抽取Feature lines生成View Map

3、Split: 基于ViewMap分割不希望连接边

4、Chain: 基于ViewMap连接不希望分割的边

5、Shade: 基于ViewMap对线条进行着色处理,完善笔触信息

最终可以达到如下效果:

问题:性能开销较大,可以用于CG品质渲染,但不适合直接在游戏中使用。

除了CG上的应用,有些4格漫画场景的绘制,也在一定程度上融合了工具的自动化流程。

另外,靠程序生成线稿步骤,艺术家们再进行后续阶段的创作,也是一种比较可行的辅助方案。

demo:(CGWorld 2018.6)

还有就是拿来实验了下《永远七日之都》的安

2、基于Project Matrix的顶点偏移

  • 早期自研手游实现的描边线条算法,当时(2014年左右)可能连模型法线都不舍得用的条件下,采用的屏幕空间顶点偏移法。图示来源于《永远七日之都》

- Pass1 绘制相应mesh的stencil mask,关闭color write

- Pass2-3-4 计算3组偏移量(x, y, z), (-x, y, z), (0, -y, z),分别对mesh的Project Matrix进行 移动,开启 color write,同时基于1的mask,绘制移动后的mesh作为线条使用。

- Pass5 取消Pass1的stencil mask,恢复之前的状态。

  • 常用于选中角色这种非常驻状态的标记应用。基本不符合二次元风格化描边线条需求。

3、Triangle Shell Technique

参考论文Raskar 1999 《Image Precision Silhouette Edges》

论文提出了利用背面translation(图中是往camera方向前移),借助z-test把Backface作为描边线条使用。

此外,论文还提出了View-Dependent的描边线条思路,通过将Backface推出z/(V·N),保持Edge在V上的投影维持不变。

此方法也就是手游上应用最广泛的法线外扩法

来自GUILTY GEAR Xrd

整个流程大概描述如下:

  • 添加美术的控制力

 (1)控制粗细

A、使用顶点色/uv作为mask,修正以下

- 线条宽度,比如发尖处勾线会逐渐变细

- 线条顶点的z bias,控制线条的visibility

B、结合摄像机距离,进行粗细的自适应

- 拉远线条不会线性变细,拉近不会增粗

- 控制线条宽度(screen space)在一定的变化范围

(2)控制颜色

A、纯色线条

B、结合Diffuse的混色线条

(3)控制转角

A、硬边问题的处理,基本都是利用平滑法线思路解决,把当前顶点的平均法线,bake 到其对应的tangent space后储存到顶点色当中。

B、转角变细,使用顶点色控制。

C、添加美术的控制力,max中自动生成平滑法线后,可以进行二调。

《永七日文版》目前的描边线条正是采样了此方案,以丽为例,注意头发尖端的线条变化。

同样的,方案也有其对应的问题:

  • 内部细节缺失。

  • <数据冗余>点法线分拆面法线。拆一次点,数据double。

  • <数据冗余>双套法线顶点色不够用加uv?

  • 第二套法线不随skin动

- 扩展cpuskin or gpu skin实时算?

- 类似法线贴图做法保存到切线空间?

4、Geometry Shader

上述方案问题:不能在非边缘的尖锐折线处产生勾线。 而这些折线在硬表面模型上是很常见。

贺甲: “ 为了解决这个问题,我们添加一个预处理过程来提取这些边缘,并将它们保存到额外的 Mesh 资源中,并使用 Geometry shader 绘制它们。对于这些折线我们使用了和 Backface 法类似的调整参数,从而使它们看起来完全相同。增加了折线的绘制之后,我们可以看到右侧的图片捕获到了更多的勾线细节。”

《米哈游技术总监首次分享:移动端高品质卡通渲染的实现与优化方案》

猜测 基于此流程实现 参考方案《Two Fast Methods for High-Quality Line Visibility》:

(1)【预处理 Edge提取】扫描每条边索引(index0,index1) 邻接面共2个顶点(index2, index3)的索引, 将4元组作为顶点数据保存, 构造为新的顶点Rect Mesh。(比如写入顶点色)

(2)Render Line index Mesh

  • VS阶段: 需借助原始mesh顶点StructBuffer,在vs中拿到Rect的索引后,获取对应的边和邻接面,判断是否为Edge,再根据参数,调整edge对应顶点的位置(譬如法线外扩)。

  • GS阶段: Draw Outline Rectangele. 如果为edge,则对edge上的两个顶点升维成为线条,绘制对应宽度的矩形。

  • FS阶段:对line进行着色处理,可选添加笔触(Strokes),以实现可控的风格化。

(3)上述过程的扩展性较高,可以根据线条规则生成完全的线条,亦可调整线条判定规则生成局部细节。

面向手机端的发展:由于手机上对GS支持较差,像Metal都没有GS这么个阶段,与此同时随着目前GPU计算的发展,Compute Shader正日益强势,因此基于CS进行线条生成,甚至完善风格化,也许可以打开新的世界(实践部分有尝试)。

思路二 手绘线条

1、贴图绘制

解决游戏中,实时渲染的内描边问题。给与美术最大控制力,直接绘制到贴图上。

我们看看一些日式游戏的做法。

七大罪
赛马娘

《永七日文版》贴图:也会有一些手绘线条在贴图上

问题:一般贴图上只要存在斜线就一定有锯齿,在镜头拉近时特别明显,因为内线条一般都只有1-2个像素。

2、本村线

为了解决锯齿的问题,罪恶装备GGX的本村氏提出了一种uv绘制法

本村线一种纹理,其中作为线条给出的实线仅由垂直和水平线组成”

问题:UV线条非常耗时,通常需要大概三个月时间才能制作一个角色,尤其是复杂的布线,需要非常有经验的美术来应用此方案。和美术有仇可以拉这个。


▼▼▼

二次元描边技术现状和发展(下)

▲▲▲

评论 0

0/1000
网易游学APP
为热爱赋能
扫描二维码下载APP