描边的艺术
因为个人能力有限,所以本文艺术讲解篇中参考了大量的资料,现学现卖,如有不足还请多多指教。
在讲解技术之前,先探究一下描线的艺术表达效果。描线在ACG艺术中起着非常重要的作用,是漫画绘制的基础,线条掌握得好与坏,关系着漫画人物、服饰、景物的质感好与坏。这些线条可以帮助读者/观众速认识物体的轮廓和特征,使其更易于识别和区分,是表现物体立体感和形态的关键要素之一。
漫画

通过描线的线条粗细、弯曲和方向,艺术家可以传达更多关于物体的信息,如材质、运动状态、情感等。粗重的描线可能暗示物体的坚固性,而柔和的描线则可能传达出柔软或温和的特性。这是描线笔触的好处,所谓笔触,从漫画创作的角度,可以说借助不同的画笔表现。

不同笔尖可以带来不同的线条:
G笔尖:

丸笔尖:


D笔尖:

还有很多不同类型如毛笔、百丽笔等就不再一一举例了,更多可以参考附录1相关PDF。

艺术家可以通过使某些部分的描线更加明显,来引导观众的注意力。这有助于将视觉焦点放在作品中的重要元素上。而且 描线不仅可以在物体的外部轮廓上使用,还可以用于描绘内部的细节,如肌肉、纹理等,从而增强物体的立体感。描线的样式可以成为艺术家表达自己独特风格的方式之一。不同的笔触可以创造出不同的视觉效果和情感。
比如漫画中:
- 物体的边缘会变粗(轮廓线);
- 两个线条转角比较大的地方会变粗(类似于书法中折角的顿笔);
- 形状与形状的交界处会变粗(体现遮挡关系);
- 凹陷下去比较深的地方会变粗;
- 阴影部分的线条会变粗;
- 线条中间比两边略粗。
这种笔触的美感有点类似于书法,通过人类几千年来书写出来的经验,对于线条控制的美感有多种多样的归纳,例如:刚健、柔韧、朴厚、丰润、工稳、灵动、华滋、涩劲、稚拙、精到等等。
动画
讲完漫画我们来讲讲动画中的描线风格(下文关于动画描线部分总结大多引用自:【可米说】从线条所见的动画制作技术运用史,感兴趣的小伙伴可以观看原视频):
由于本篇是专栏的第一篇,所以在谈论描线在动画中的发展和运用前,我们先谈谈动画的概念。由于篇幅太多我单独将这部分拆成一篇文章:
了解了动画的概念之后,我们把主视点放在赛璐璐动画(或者平面动画)上。赛璐璐动画遵循着包括描线在内的特定流程。早期这一步是通过手工描线班完成的,由于工期和成本高昂,渐渐由机器(转印机)替代。


转印机时代有着能够表现特殊笔触的线条,这样的线条能够带来不同的情绪表达作用:



引用扫描技术后,动画线条带来了均一化,同质化的缺陷,这是由于光栅化的特点带来的:



通过加强主轮廓线强调线条的粗细对比:

视频中最后介绍到
目前主流的处理方式,均不是从“如何还原动画师本人的笔触”上去解决,而是利用摄影人员的后期努力让线条模拟出转印机时代的笔触与质感,但这不是从业人员的问题,这是时代与商业市场需求的问题,是计算机图形学的问题。
描边的技术
描边的技术多种多样,本篇介绍的描边技术不止外描边,也包含内描边在内的多种描边技术。
Procedural Geometry Silhouetting 法线外扩
中文一般称为“法线外扩”、“背面膨胀”,日文资料中会称作「背面法」,英文又可以叫做Backing Face/Vertex Extrusion等,它们指的是同一个技术,Procedural Geometry Silhouetting 的叫法来源于《Real-Time Rendering 4th》15.2.2
https://zhuanlan.zhihu.com/p/446473650
最简单的方法就是在物体空间移动一定的距离,但是这样做会有缺陷,就是每个顶点移动的距离并不等距,于是想到沿法线移动:
positionOS += normalOS * _OutlineWidth;
不过,如果你希望描边不会因相机距离变化而变化。则应当在NDC空间下进行修正。
float3 normalCS = TransformWorldToHClipDir(normalInput.normalWS);
float2 offset = normalize(normalCS.xy);
output.positionCS.xy += offset * output.positionCS.w *_OutlineWidth * 2.0;
同时需要修正由于窗口视口比例的问题导致的不等宽问题:
offset.x *= abs(_ScaledScreenParams.y/_ScaledScreenParams.x);
修正窗口视口比例的问题前后对比(16:9):
描边效果前后对比:
此外还有平滑法线,此工具我单独写一篇博文。
法线平滑前后效果对比:
大部分文章到这里就结束了,实际上真正落地时,运用此方案,当模型距离视口过远时,描边会出现外扩。

一种解决思路是根据物体到摄像机的距离做相应的变化,还有一种是设定描边的边界值,MiToon中采用的第二种思路。不仅如此,为了兼容正交相机,对描边在正交相机下做了同理的限制。

除此之外,在实际落地中,还可以根据相机类型(如果是透视相机则根据FOV)调整positionCS.z。这样做的目的是为了调整一些在脸部/眼睛区域的法线效果,还可以根据FOV变化程度保持描边的宽度,同时能够解决ZFighting问题。如果是透视相机,根据近剪裁平面和远剪裁平面的Z分量,即UNITY_MATRIX_P[2].zw的值(等价于使用_ProjectionParams.yz),对描边进行处理, 《原神》中就采取了类似的做法。
许多描线的文章中并没有提及半透明描线的落地方案,或者干脆就放弃。实际上很多地方都存在着类似的需求:比如衣服上的半透明部分(丝绸/透明胶质),场景中一些neon effects/科技感/赛博风的建筑。
就半透明物体的法线外扩法描边方案来说,最大的缺陷是需要借助Stencil才能保证描线颜色对物体本身不产生影响。

法线外扩在落地时需要应对多种工程上不同的case,还是存在很多处理上的细节的。