专栏/揭秘《泰拉瑞亚》中的光照系统——“骗过”所有人的极简实现

揭秘《泰拉瑞亚》中的光照系统——“骗过”所有人的极简实现

2022年11月16日 21:34--浏览 · --喜欢 · --评论
粉丝:1625文章:3

《泰拉瑞亚》的光照系统,是大家熟悉又陌生的东西,在我上千小时的游戏时间中,我很少深入思考它的光照机制到底是如何实现的,它为什么能在低性能设备上流畅运行,直到我发现了一些从未注意到的东西…

比如…光照只用CPU计算?

比如…光线穿过液体会变色?

比如…光线会拐弯,但是不会走迷宫?

白光经过水体变色,注意房间内的颜色

实际上,TR的光照系统非常非常简单,可以概括为

——从光源出发,严格地上下-左右-上下-左右走四次,光照的扩散随着距离、依据物块类型衰减

或者从游戏实现上讲

——做两次“两步高斯模糊”,但是把一维的“高斯模糊”过程换成逐个物块的衰减的模拟

(极致节省,但又保持了不错的效果。搜索?不存在的。光线追踪?不存在的)



光的传播

我们来做个实验

请放大观察这张图片——

光线迷宫,注意暗处的细节

有没有注意到什么细节?

放大看看,右侧是不是产生了阴影,而上面没有
注意1和2区域,如果不明显可以看上一张图

没错,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玩家也是如此)——这也侧面证明了泰拉瑞亚光照系统的成功。因此我大半夜拍案惊奇,写了这篇专栏来分享我的发现。

感谢大家读到这里!希望大家有所收获,看到你所不知道的另一个《泰拉瑞亚》

投诉或建议