前言
卡通渲染也叫非真实感渲染(英文简写:NPR),"描边"在图形学和数字图像里都叫边缘检测。因此你可以在很多文献网站上面找到很多这类文献,但最后我发现基于图形学使用的方式基本都是类似的,没有太多特别的做法。最后忙着研究unity3d的坑,都忘记记下来了,只保留了几个映像比较深的文献。有误请指正。
一、模型上的边缘
1.1、边缘的分类
很长一段时间我在网上找到的描边法,给我的感觉都是或多或少地漏掉很多边缘,然后我开始反思这边缘是不是有很多种类,并尝试对边缘进行分类。仔细翻阅文献就会发现3d模型的边缘在学术上分成四类,参考文献[1],这里直接引用。
实际中在非真实感上用得很多的“背面法”在很多文献上都有提及,但我们会发现“背面法”是没办法把模型的所有边缘都获取到,这种方法在很多文献上被记载只能得到模型的轮廓边缘。
1.2、边缘的检测
四种边缘都有各自的检测方法,这一部分的研究也已经有前人做了。这里直接引用文献[1]的部分。
1.3、边缘的小总结
经过上面两个部分,就可以看出3d模型的边缘其实很简单,只需要知道一条边的两个相邻面可以完成除材质边缘的其他三类边缘检测。但我们也能看出,这些方法是基于模型三角面的三条边进行检测,因此很容易得到模型精度过低无法使用的结论,对于这类模型很多人是直接画在贴图上。
二、3d渲染
渲染的3个主要对象,网格mesh、材质material、着色器shader,本文不做阐述。通过这3个对象我们有很多做边缘检测的方法,这里就使用着色器shader。在着色器中,有一个着色器叫几何着色器,它提供一个三角图元(面)相邻的另外3个三角图元(面),这正好符合我们的需求。
三、实现渲染
3.1、unity3d几何着色器的限制
在directx的手册上几何着色器支持这几种类型的输入:
(1). point:输入的图元为点。
(2). line:输入的图元为线。
(3). triangle:输入的图元为三角形。
(4). lineadj:输入的图元为相邻的线段。
(5). triangleadj:输入的图元为相邻的三角形。
很自然地,我们会直接开始着手去写我们的程序,但在中途你会很不幸地发现unity3d的几何着色器的支持度貌似并不完善,它不支持triangleadj相邻三角图元作为输入。因此我通过搜索在国内找到了一些讨论,但数量极少,随后我跑去unity3d的官网搜索,找到了一些相关的讨论,参考文献[6][7]。