非真实渲染(卡通)
卡通着色主要分三个部分分别是阴影、高光和描边,其中主要的还是描边和阴影,常见的卡通高光的实现和一般是将光照效果梯度化来表现。阴影的实现方法和描边的实现都有非常多的方法和手段对于不同几何体、光照效果、性能要求等表现效果不同而选择。
阴影
模板阴影(Stencil Shadow)
模板阴影(Stencil Shadow)算法是基于网格几何体和模板缓冲区(stencil buffer)的阴影渲染算法。模板阴影技术由两个部分组成:从轮廓边缘构成体,并把它们渲染进模板缓冲区内。对每个光源重复这两部分,并把产生的图像加在一一起,创建一个最终的帧(称为多遍渲染的过程)。优点是阴影精度高,边缘清晰,无锯齿现象,光源的类型和位置对性能没有影响,而 shadow map 技术会受到光源类型的影响。缺点是需要对物体计算边缘轮廓来确定阴影体,渲染的阴影比较硬,无法渲染软阴影。
阴影映射技术(Shadow map)
阴影映射技术(shadow map)是从产生阴影的光源(在通常项目中为Directional Light)放置一个相机,渲染一次场景,获取深度贴图的基于深度信息的技术。在正常渲染的Pass 中把顶点位置变换到光源空间得到三维位置信息。使用xy分量对阴影映射纹理进行采样,得到阴影映射纹理中该位置的深度信息。如果该深度值小于该顶点的深度值(通常由z分量得到),那么说明该点位于阴影中。在Unity中是基于屏幕空间的阴影映射,利用摄像机深度纹理对阴影图采样。在pass标签为Shadow caster中计算阴影然后对需要接受阴影的物体进行采样计算即可。
高光
卡通着色中的高光效果就是将光照效果进行离散化处理,实时光照的具体的着色方法,一般可以理解为在片段着色器中测试每个像素漫反射中的 NdotL值,让漫反射形成一个阶梯函数,不同的 NdotL 区域对应不同的颜色。用光照模型Blinphong公式结果在阈值比较从而得出梯度范围,边缘处可进行平滑过渡处理抗锯齿效果。不需要光照信息的也可以采用一张渐变贴图实现高光效果的模拟,基于图像的渲染原理和实现效果非常多也十分强大,可以参考冯委的知乎博文简述47种Shader Map的渲染原理与制作方法:https://zhuanlan.zhihu.com/p/27339998
描边
基于视点方向的描边
基于视点方向的描边方法,即表面角描边(Surface Angle Silhouetting),其基本思想是使用视点方向(view point)和表面法线(surface normal)之间的点乘结果得到轮廓线信息。如果此点乘结果接近于零,那么可以断定这个表面极大概率是侧向(Edge-on)的视线方向,而我们就将其视做轮廓边缘,进行描边。这些模型必须保证法线与轮廓边缘之间存在一定关系。诸如立方体这样的模型,此方法并不太适用,因为往往无法得到轮廓边缘。
基于过程几何方法的描边
过程式几何轮廓线渲染核心是背面顶点沿顶点法线向外扩张包裹原模型。这种方法的主要是使用两个Pass渲染。第-一个Pass渲染背面的面片,通过偏置将这些背向表面沿屏幕 Z 方向向前移动,或者是沿着法线方向移动向外扩张,第二个Pass再正常渲染正面的面片,这样,便只有背向表面的三角形边缘是可见的。这种方法的优点在于快速有效,并且适用于绝大多数表面平滑的模型,但它的缺点是不适合类似于立方体这样平整的模型。如果线条的宽度超过这个值,那么通常会出现无法连接独立线段的情况,从而造成明显的缝隙会出现片面分离的效果。
基于图像处理的描边
可以将其理解为一种后处理操作。通过寻找相邻Z 缓冲数值的不连续性,就可以确定大多数轮廓线的位置。边缘像素之间的颜色梯度较大,用卷积核的权重判断,采用滤波算子计算梯度值从而确定边缘。借助邻接表面法线向量的不连续性,也可以确定出分界线(往往也是轮廓线)边缘的位置。除了利用边缘检测还可以使用借助command buffer来处理一些类似立方体这样规整的模型,使用command buffer实现的描边效果可以有很好的表现效果在后处理中有很广泛的应用。
基于轮廓边缘检测的描边
基于轮廓边缘检测的描边,通过检测出轮廓边缘(SilhouetteEdgeDetection)),并直接对它们进行绘制,这种形式的描边,可以很好地控制线条绘制的过程。由于边缘独立于模型,因此这种方法还有另外一个优点,就是能够生成一些特殊的效果。例如,在网格密集的地方可以突现出轮廓边缘。可以将轮廓边缘理解为朝向相反的相邻三角形的交接。也就是说,其中的一个三角形是朝向视点,另一个三角形背向视点。可以很方便地利用表面法线向量和视线方向向量的点乘计算检测边缘。不过会有动画连贯性的问题。也就是说,由于是逐帧单独提取轮廓,所以在帧与帧之间会出现跳跃性。
混和轮廓描边
混合轮廓是结合了图像处理方法和几何要素方法来渲染轮廓的方法。单一使用图像处理获得的描边精度较高而使用几何要素检测出的边缘往往有时候不是很准确,这时候结合图像处理进行双重检测即可得到更为精确或更具风格化的效果,包括变细、火焰、摆动、淡化等效果,同时还有深度和距离信息。
更多相关资料
康玉之 GPU 编程与 CG 语言之阳春白雪下里巴人
冯乐乐 shader入门精要
毛星云 《Real-Time Rendering 3rd》提炼总结
GPU Gems(中文版)