《泰拉瑞亚》的光照系统,是大家熟悉又陌生的东西,在我上千小时的游戏时间中,我很少深入思考它的光照机制到底是如何实现的,它为什么能在低性能设备上流畅运行,直到我发现了一些从未注意到的东西…
比如…光照只用CPU计算?
比如…光线穿过液体会变色?
比如…光线会拐弯,但是不会走迷宫?
实际上,TR的光照系统非常非常简单,可以概括为
——从光源出发,严格地上下-左右-上下-左右走四次,光照的扩散随着距离、依据物块类型衰减
或者从游戏实现上讲
——做两次“两步高斯模糊”,但是把一维的“高斯模糊”过程换成逐个物块的衰减的模拟
(极致节省,但又保持了不错的效果。搜索?不存在的。光线追踪?不存在的)
光的传播
我们来做个实验
请放大观察这张图片——
有没有注意到什么细节?
没错,2区域离光源更近,但是反而在阴影里;1区域却被照亮了。
那么照明是会绕着墙拐弯扩散的吗?也不完全是,因为1和2区域绕过墙到光源的格子数是完全一样的。
实际上,正如我们一开始提到的,光能传播的方向只能是严格的上下-左右-上下-左右,
从光源到1需要经过 左-上-右
从光源到2需要经过 左-上-右-上
是的,从光源到2的路径并不能用上下-左右-上下-左右的路径达到
(上下-左右-上下-左右,少一个上)
但是从光源到1的路径可以。因此1区域会被光照到,而2区域照不到!
光的衰减
此外,光会根据经过的物块类型和液体类型衰减。
TR里最小的照明单位是一整个物块(一格)。你所看到的这个小于一个物块的细致光照,实际上都是在单个物块的光照算完之后,用旁边相邻物块的光照结果过渡给你看的。
因此光的衰减也是一格一次,按照指数衰减。空气和墙等等有不同的衰减因子,这就产生了光在空间中扩散的效果。
光的RGB三个颜色分量也是分别衰减的,尽管它们大多数时候都一样(我倒是希望RE给刷漆玻璃块加个有色光的细节,这从代码上其实很好实现)——唯一的例外是被水覆盖的物体
水会根据所在环境不同而对RGB三个分量产生不同的衰减。比如森林群系的水体对于红和绿的衰减大,对蓝色衰减小,结果呈现蓝光。
有一个小细节,就是这个衰减颜色并不是和水体颜色一致,而是每种群系单独设置了一个。猩红群系的水透光居然意外地变成了青色而不是红色,别有一番风味23333
“两步模糊”?
作为玩家,了解到这些冷门知识其实已经足够了,
不过作为一个泰拉瑞亚的模组开发者,还可以更深挖一下其中的道理。
如果你做过Bloom之类的常见后处理滤镜,那么你会对“两步高斯模糊”十分熟悉。
如果你不熟悉?那么这里是简要的解释——
高斯模糊本质上是对每个像素,取周围的若干个像素的值按照一定比例混合在一起,产生模糊的效果。但是这会带来很大的开销,如果这个周围区域直径是11,那就会对每个像素取周围11*11=121个额外像素参与计算,带来很高的开销。
但是高斯模糊的系数有某种特殊性质——如果先对y轴做一维的高斯模糊(即只取同一竖列的像素混合),做完了之后,再对这个中间结果的图,做x轴的一维高斯模糊(只取同一横行的),结果和一开始的二维结果保证一样。那么,通过这样“两步”的方式,就把开销从121降低到了11+11=22,优化巨大。
而说回TR的光照系统,它并不是用的高斯函数,也不是纯粹的模糊,但是它进行的是完全相同的过程。
它想要做到的不是二维高斯模糊,那么是什么呢?
最短路算法。
它有点像一个限制了拐弯次数的spfa,或者想的更简单一些,像bfs。
从光源出发,经过不同的衰减路径,问衰减后最亮还有多亮
(这应当是TR光照系统理想的建模)
刚刚的两步高斯模糊过程,把一维高斯模糊换成刚刚提到的,分别向两侧的光线衰减过程就好了!(比如图中1就是往上下的衰减过程,2是往左右的;1和2合起来是一轮)
此外,只要在往某个方向传递的过程中,遇到了一个更亮的光源,就可以以它为光源继续传播。这样能对图上所有的光源一起做这个操作,而让光照计算开销与光源数量无关!
捷径就是做两轮!
其实我们也可以注意到,这个近似的“高斯模糊”过程中,进行一轮“两步模糊”只能让光的传播拐成水平再拐成竖直,除此之外的路径都不会被计算覆盖。
如果上面这幅示意图中只留下橘色的1和2两组箭头照到的区域,这个光照系统的破绽就会十分明显,而显得违和。但是因为这整个过程又进行了两次,就又产生了绿色的3、4箭头照到的区域。
——能够拐弯好几次的折线光线,效果和真的跑最短路已经很相似了!
(以至于我曾经一直以为TR有高效跑最短路计算的方法)
毕竟平时游戏的环境很少会出现这种专门构造来卡光线的“迷宫”
如果轮数继续增加,最终会趋于真正的最短路模型!
结语
在仔细研究之前我完全没有想到TR的光照算法如此简单,制作组的这种小trick骗过了我和我身边的所有人(我相信绝大多数TR玩家也是如此)——这也侧面证明了泰拉瑞亚光照系统的成功。因此我大半夜拍案惊奇,写了这篇专栏来分享我的发现。
感谢大家读到这里!希望大家有所收获,看到你所不知道的另一个《泰拉瑞亚》