非真实感渲染
- 尽管游戏渲染一般都是以照相写实主义作为主要目标。但也有许多游戏使用了非真实感渲染的方法来渲染游戏画面。
- 非真实感渲染的目标是使用一些渲染方法,使得画面达到和某些特殊的绘画风格相似的效果。例如:卡通、水彩风格。
卡通风格的渲染
- 实现卡通渲染有很多方法,其中之一就是基于色调的光照模型。
- 在实现中,我们往往会使用一张一维纹理进行采样,以控制漫反射的色调。
- 卡通风格的高光效果也和我们之前学习的光照不同,卡通风格中,模型的高光往往是一块块分界明显的纯色区域。
- 卡通风格通常还需要在物体边缘部分绘制轮廓
渲染轮廓线
有许多轮廓线的渲染方法被提出,这里介绍其中五种:
- 基于观察角度和表面法线的轮廓线渲染。使用视角方向和表面法线的点乘结果来得到轮廓线的信息。这种方法简单快速,一个Pass中就可以得到渲染结果,但局限性很大,很多模型渲染出来的描边效果不尽如人意。
- 过程式几何轮廓线渲染。使用两个Pass渲染,第一个Pass渲染背面的面片,并使用某些技术让它的轮廓可见;第二个Pass再正常渲染正面的面片。这种方法有点在于快速有效,并且适用于绝大多数表面光滑的模型,但它的缺点是不适合类似正方体这类表面平整的模型。
- 基于图像处理的轮廓线渲染。之前边缘检测的方法就属于这个类别。这种方法有点在于可以适用于任何类型的模型。但也有局限性,一些深度和法线变化很小的轮廓无法被检测出来,例如桌子上的纸张。
- 基于轮廓边检测的轮廓线渲染。上述提到的方法无法控制轮廓线的风格渲染。我们检测一条边是否是轮廓边的公式很简单:
(n0·v>0) ≠ (n1·v>0)
- 其中n0和n1是相邻两个三角面片的法向量,v是视角到该边上任意顶点的方向。检测出两个三角面是否一个朝正面,一个朝背面。我们可以再几何着色器的帮助下实现检测过程。
- 最后一个种类就是混合了上述的几种渲染方法。例如,首先找到精确的轮廓边,把模型和轮廓边渲染到纹理中,再使用图像处理的方法识别出轮廓线,并在图像空间下进行风格化渲染。
添加高光
- 计算normal和halfDir的点乘结果,把该值和一个阈值进行比较,如果小于该阈值,高光反射系数为0,否则返回1;
float spec = dot(worldNormal,worldHalfDir);
spec = step(threshold,spec);
- 系数直接突变会使边界处产生锯齿,我们可以在边界处很小的一块区域内,进行平滑处理。
float spec = dot(worldNormal,worldHalfDir);
spec = smoothstep(-w,w,spec - threshold);
像素风格的渲染
- 使用了提前生成的素描纹理来实现实时的素描风格渲染,这些纹理组成了一个色调艺术映射
- 图中从左到右纹理中的笔触逐渐增多,用于模拟不同光照下的漫反射效果。
- 在顶点着色器中通过对物体漫反射的强度来决定不同map的权重,在片元着色器中对各map纹理采样后乘上相应的权重系数并且叠加起来得到颜色,再用白色乘上1减去TAM各map的权重之和得到纯白颜色的贡献颜色成都,将两个颜色叠加得到当前片元的漫反射颜色。