本节书摘来自华章计算机《Unity着色器和屏幕特效开发秘笈(原书第2版)》一书中的第2章,第2.8节,作者 [英]艾伦朱科尼(Alan Zucconi)[美]肯尼斯拉默斯(Kenneth Lammers),译 占红来,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.8 创建全息着色器
每年都有越来越多的太空主题游戏问世,科幻游戏的一个重要组成部分是如何在游戏中集成一些未来科技感。全息技术就是这样一种非常适用于创造未来科技感觉的着色技术。全息着色有很多不同的表现形式,但是通常都是用来渲染一些半透明的尖锐物体。这一节会告诉你如何创建类似的特效。首先要记住一点:可以通过噪声、动画扫描线以及振动来创建一些非常卓越的全息特效。下图是一个使用全息特效制作的物体的图像:
2.8.1 准备工作
因为全息特效只会显示物体的轮廓,所以我们将这个着色器称为Silhouette。将着色器附着到一个材质然后将材质指定给三维模型。
2.8.2 操作步骤
按照下面的步骤,可以将已有的着色器转换为一个全息着色器:
- 给着色器添加如下属性:
- 给CGPROGRAM部分添加如下变量:
- 因为材质是透明的,所以添加如下标签:
根据所使用的物体类型的不同,你可能想要显示物体的背面,如果这样的话需要添加Cull Off来确保物体的背面不会被移除掉。
- 这个着色器不是用来模拟真实材质的,所以没有必要使用PBR光照模型。这里使用朗伯反射(Lambertian reflectance),朗伯反射是一种非常廉价的光照模型。此外需要通过设置nolighting来禁用所有光照,还需要通过alpha:fade来告知Cg这应该是一个透明着色器:
- 修改Input结构,让Unity知道在当前视角方向和世界法线方向如何填充Input:
- 使用下面的表面函数。记住一点:因为这个着色器使用朗伯反射作为其光照函数,所以表面函数的输出结构应该相应地修改成SurfaceOutput而不是SurfaceOutputStandard:
现在可以使用Rim effect滑块来选择全息特效的强度了。
2.8.3 工作原理
前面已经提过,这个着色器只是渲染物体的轮廓。如果从另外一个角度观察物体,其轮廓会相应地发生变化。从几何学的角度来讲,模型的边缘是由那些法线垂直于当前视线方向的三角形构成的。相应地,在Input结构中,我们声明了参数wordNormal和viewDir。
判断两个向量是否正交可以通过计算其点积得知。如果两个向量是正交的,则二者的点积为0。我们使用_DotProduct来判断点积需要多么接近于0时才将三角形视为其轮廓。
这个着色器中的第二个方面是模型的边(完全可见)与_DotProduct确定的角度(不可见)之间的渐变褪色。这是通过下面的线性插值完成的:
最后,纹理中的初始alpha值与新计算的系数相乘来获得我们想要的全息效果。
2.8.4 更多内容
这个技术本身非常简单也相对比较廉价,可以用在大量其他特效上,比如:
- 科幻游戏中包裹有某种颜色气体的星球
- 某个选中物体或者当前鼠标下面的物体的轮廓
- 鬼或者幽灵
- 引擎中散发出的烟雾
- 爆炸的冲击波
- 太空飞船在遭到攻击时的泡泡护盾
2.8.5 参考
点积在计算反射的时候起了重要作用,在第3章中会详细解释其工作原理以及为何其广泛应用在很多着色器中。