你好 欢迎来到Fearghall的星期五报道!(FearghallFactoriolFridayFacts,FFFF如果你想这么简称的话。)
在过去的几个月里,你已经多次看到小行星作为其他星期五报告的背景部分,尽管它们看起来不显山不露水,但实际上制作它们需要相当复杂的技巧!和我一起出发,我将带你踏上3720比1的小行星之旅。
小行星确实与我有关
我们首先从最初的小行星开始,它们与任何其他部分都一样 —— 一个包含灯光和阴影的2D预渲染图像。这很有效,但看起来很奇怪,小行星都从同一个方向出现,只在XY平面上移动并且不旋转。
星期五报道#411- 关于小行星的一切 视频#01
在设计小行星的过程中我们讨论了旋转部分。
小行星设计
当我们确定了3种不同的小行星类型后,我们就可以开始真正的小行星设计了。考虑到这种安排,很明显,这些小行星需要在视觉上尽可能不同。
我们本来打算对所有小行星类型使用相同的传统小行星形状,只使用颜色来区分它们,就像使用占位符一样。不过需要他们比我们希望的更有活力,总体上看,做出来的效果没有那么好。
于是,我们决定将小行星设计的在各个方面都有所不同。
第一,整体造型。这一点很重要,因为小行星上有光影。鉴别它们主要是靠它们光影形状。金属小行星像是严重变形凹陷的金属。碳质小行星像是凸起的砾石和尘埃,有点像混合在一起的球体。氧化物小行星像是几何形状,有更多的直线和锐角。
至于它们在游戏中的材质,金属小行星会有金属光泽。碳质小行星会非常粗糙,表面会有更多类似砾石的缺陷。氧化物小行星会更闪亮,更像玻璃,但不像一颗干净的宝石,更像是一个破旧的尘封或霜冻的物体。
有了这些东西,我们可能会有一些看起来很漂亮、很明显的小行星,但这让另一个问题变得更糟:这些小行星非常显眼,重复出现时,也会非常容易识别。为了避免明显的重复,我们需要大量的变化,而且因为有些小行星非常大,所以这样做的成本非常高。
另一种选择是通过让小行星旋转来隐藏一些相似之处,但是。。。
不选择旋转的理由:7680
通常,对于需要旋转的物品,如角色或车辆,我们会为每个旋转渲染一个单独的图像,以便光影匹配。虽然这种方法可能仍然适用于这种情况,但这将是一场性能噩梦——每个小行星类都有5个大小,每个大小都需要一些变体,可能至少需要64帧才能让旋转动画看起来正常,如此我们会需要7680帧的动画。
显然,需要一个不同的解决方案。
编译着色器
很明显,我们需要一些将光影信息动态应用于小行星的方法。这就是游戏艺术家最好的朋友,法线贴图的用武之地。对于不太了解的人来说,法线贴图是一种基本上存储其所代表的斜率图像。
轴(左/右)被保存到红色通道, 轴(上/下)被保存到绿色通道
为了使用这些信息来应用光影,我们需要在着色器中对其进行一些巧妙的数学运算,以参考固定光线的方向。
星期五报道#411- 关于小行星的一切 视频#02
这让我们得到了“漫射”照明,但没有颜色信息!由于我们不想创造50年代风格的太空歌剧,我们需要我们的小行星不是黑白的。因此,在渲染它们时,我们需要将颜色信息与照明信息分离出来。
我们可以将法线贴图生成的光照混合到原始彩色图像上,这给了我们一个很好的结果
漫反射颜色
应用照明的漫反射颜色
然而,你会注意到一些事情,光线非常“平坦”,金属小行星的金属和冰的光泽无法穿透。这是因为着色器尚未考虑材质的光泽。但我们不希望亮度均匀增加,不同地区的亮度应该不同!所以我们渲染出另一个过程,这次是镜面反射照明。
我们只需使用漫射颜色来处理反射颜色,并使小行星在正确的区域更亮。
仅镜面反射
具有先前步骤的镜面反射
但是冰看起来还是不对!它太坚固了,冰让一些光穿过它并散射,使它发出美丽的蓝光。这被称为亚表面散射(SSS)。因此,再进行一次图像和渲染过程,仅在光线间接照射的区域混合。
然而,所有小行星上仍然有太多的阴影。虽然这在技术上是准确的,因为太空中没有任何东西可以反射光线,但在我们地球进化的眼睛看来,这是不自然的。因此,我们可以降低阴影的强度,并以与第一个光源互补的角度添加第二个光源。
无SSS或反弹光
SSS和反弹光
我们做完了!感谢Earendel和Posila帮助解决照明计算中的一些问题。
星期五报道#411- 关于小行星的一切 视频#03
星尘着色器
虽然Jerzy的星场着色器和小行星的运动在一定程度上向玩家展示了平台正在移动,但效果总体上很难看到,我们需要一些明显的、无处不在的东西,但不能过于夸张。
一个解决方案是《星际迷航》或《神秘博士》等经典的曲速效果,但这感觉有点卡通化,与Factorio的伪现实风格略有脱节。因此,我们决定折衷一些,采用可能来自所有爆炸的小行星的运动模糊的微陨石和星际尘埃的方式来表现。
星期五报道#411- 关于小行星的一切 视频#04
创建这种效果的一种方法是产生大量烟雾和带有一些运动模糊的粒子,然而粒子大量占用大量资源,而且由于这种效果需要根据您正在观看的任何大小的平台进行缩放,这将导致成本呈指数级增长。
相反,我选择创建一个带有所有“粒子”的纹理。为了进一步优化,这个纹理与着色器中使用的其他几个纹理“打包”在一起,降本增效。
所有4张图像合并为1张RGBA图像
通过对纹理坐标进行一点数学运算,我们可以使图像移动,通过屏蔽红色、绿色、蓝色和alpha通道,我们可以访问所需的“打包”数据。
星期五报道#411- 关于小行星的一切 视频#05
然而,灰尘仍在以或多或少相同的速度移动,这看起来很奇怪。因此,我们将通过简单地修改平移功能中的速度,使斑点和灰尘以不同的速度移动。我们也不希望所有的斑点都以相同的速度移动,它看起来太像一个单一的内聚结构了。这就是一些掩蔽纹理的作用所在。我们可以使用图像#1在不同的时间选择性地掩蔽单个粒子,这有助于制造许多小东西独立移动的错觉。这需要一些数学运算来绘制一个值周围的峰值,然后我们将目标值分配给一个时间变量,并将其循环回来。
星期五报道#411- 关于小行星的一切 视频#06
目前,粒子一直以100%的速度使用轨迹图像,但如果它们移动缓慢,则应该不会太模糊。由于在创建图像时进行了一些预先规划,我们可以通过剪切阈值以下的像素来做到这一点。由于轨迹图像是线性梯度,这意味着我们可以很容易地控制长度,我们只需从图像值中减去目标值。
星期五报道#411- 关于小行星的一切 视频#07
如果我们以不同的速度和尺度重复这个过程几次,我们就会产生一种强制视差效果。离视野越近的灰尘越大,移动得越快。 现在我们所需要做的就是将所有这些结合在一起,并将强度与缩放级别联系起来,这样在构建时就不会太分散注意力,我们就完成了!
星期五报道#411- 关于小行星的一切 视频#08
不管怎样,表面元素已经完成了。
虽然灰尘有助于体现运动的状态,但这个空间仍然感觉很2D。为什么所有的小行星都与我们的平台在同一个平面?
所以我们需要一些背景元素,更多的小行星!同样,我们可以创造更多的小行星,它们会在平台后面呈现,不会碰撞,但这似乎不是最理想的。
相反,我使用了一种名为“纹理飞溅”的技术,从一个只包含少数图像的纹理图谱中创建了无限数量的小行星。这篇报道已经很长了,所以我不会详细介绍,但该函数基本上将屏幕分割成一个网格,目标是在每个网格中放置一颗小行星,并带有随机偏移。
对于那些对该技术感兴趣的人,Daniel Elliot创建了一个关于其实现的非常深入的youtube系列视频讲解,这几乎就是这里使用的确切实现。
所有背景小行星的纹理图谱
着色器通过修改纹理样本的UV坐标将此图像拆分为单个小行星。如果我们创建一个随机UV网格,我们可以将这些小行星放置在其中。然而,如果一颗小行星被放置在网格中两个单元格的边界上,它将被切断。因此,我们需要参考相邻的单元格,以确定它们是否与当前单元格重叠。值得庆幸的是,这可以通过在任何给定方向上简单地使用相同的函数+/-1来管理。
星期五报道#411- 关于小行星的一切 视频#09
我们给每一颗小行星一个随机的旋转速度、运动速度和尺度,并在不同的视差尺度上再次完成整个过程。然后,我们和以前一样,对动态照明进行同样的计算,我们得到了无限的小行星带!
星期五报道#411- 关于小行星的一切 视频#10
非常感谢你和我一起踏上这段漫长而技术性的旅程。看来我们的船完好无损地幸存了。