首页/编程/途径:光明和阴影
编程

途径:光明和阴影

2020-11-13T16:22:13 + 01:00

开发自定义Pixelart引擎。

在2014年底,中途发布后不久,Simon的尚未含糊不清的一个热闹的讨论:可以编写一个渲染引擎,使我们能够将经典的16位像素艺术美学与a结合起来现代光线和影子系统?

在机器人的第一场比赛的中途发展中,我们简要试验了这个想法,但由于缺乏时间和资源,很快就会丢弃它。一个小型原型暴露了太多问题,中途沿着其发展日程表太远了。

但是现在,虽然团队的一部分是思考新的游戏和设计,但我们终于有时间再次考虑这个问题。在几周之内,我们创建了基于中途资产的另一个非常粗暴的原型。但它在一定程度上工作并表明它是一种理论上的可能性。

我们的引擎支持场景渲染。小型场景描述了玩家目前与之交互的事件。手工模块的随机放置使我们能够生成许多视觉变化。事件场景使用不同的生成器和规则,而不是背景中的探索地图。

当然,这提出了这个问题:这个想法是如此特别?毕竟,在等距和正交发动机中渲染动态阴影没有任何神奇的神奇!

虽然这是真的,但是在不破坏像素艺术的经典外观的情况下结合手动动画像素图形并变得非常复杂。已经有许多类似的尝试,但是上述像素艺术外观和感觉大规模改变,或者技术实现并不像我们想象的那样深远。

创建和使用正常地图不是一个新的想法,以动态地照亮场景。这里的问题在于,这通常会产生类似塑料的外观,摧毁手动挑选的彩色调色板的像素艺术魅力,并故意放置像素。这是我们绝对想要避免的东西。

网眼精灵用于像金字塔这样的复杂物体。 3D网格呈现给像素 - 完美的精灵艺术家然后可以画出。

愿景
我们对这种发动机的愿景可以概括如下:

  1. 结果应该有一个完全有资格作为像素艺术的看法。
  2. 资产生产不应多次使用经典的2D像素艺术发动机。只要有可能,工具甚至应该从图形艺术家上工作。
  3. 照明和阴影应为100%动态。没有预先计算的或手绘灯具,如中间使用的。
  4. 工具应该有效,使我们的小团队能够在很短的时间内创建大量内容。
  5. 游戏还应在较弱和较旧的硬件上运行。无论实际技术复杂程度如何,我们都没有任何关于游戏玩家对系统要求的游戏玩家的幻觉。

第二点对我们来说始终尤为重要,因为我们是一个只有一个只有一个永久性图形艺术家的小团队,他们也可以作为一个级别设计师。所有其他图形艺术家都将是自由职业者暂时工作的。我们无法指望他们在特设基础上学习新的实验功能。该发动机必须以与经典的2D发动机相似的资产和工作技术或多或少地运行。

延迟渲染器允许同时允许许多本地的完全动态光源。

在表现方面,我们只是部分成功。我们无法在游戏发布时实施一些必要的优化。游戏在旧英特尔HD 4000 GPU上每秒左右30帧,也需要至少4千兆字节的免费主记忆甚至开始。这使我们赢得了很多支持查询,因为很少有一些玩家只是忽略了我们所指定的最低要求,并且正如我们所担心的那样,预计游戏有一个简单的2D游戏的要求。传达发动机在某些场景中必须在每帧中处理超过一百万多边形的事实并不容易。

在以下部分中,我们将尝试解释我们的发动机如何工作。

由于动态照明和调色板系统,我们可以轻松实现非常喜怒无常的场景。

场景,对象,光线和阴影
路径中的图形场景包括两个相同几何形状的两个重叠视图。每个场景分为块。这些块中的每一个都可以由作业系统异步构建,仅在完成后才可用于渲染到显卡。重叠多个块的元素由每个块单独处理。我们完全分配了复杂的剪辑问题–这仅由GPU通过剪辑平面渲染时完成。在实践中,这并没有成为一个性能问题。

“拓扑场景”显示了从自上而下的正交角度发生的事情。它包含播放器最终在屏幕上看到的所有内容。基本上,人们可以想象这个场景作为使用彩绘纸板风光的剧院的舞台–一旦观察者移动到侧面,效果就会丢失。

为了避免在2D引擎中常见的“回到前面”分拣问题,所有元素都具有一个位置以及“深度”,并且在具有z'= y + z的深度缓冲器中呈现。因为我们也很大程度上被分配半透明效果,GPU对我们进行排序。

除了纳粹,你还打架了一个疯狂的邪教,谁使用了奇怪的仪式来带回死者。

除了动画元素之外,拓扑场景最终由一个投射到64的许多未致盲的高度组成×64像素。每像素的早期迭代甚至使用了1个四边形(2个三角形),最终成为即使是最现代的图形卡也是一项挑战。仅稍后是一个滤镜,将“未加注”区域组合成较大的矩形,并根据场景的复杂性,将所需的几何形状降低30-60%。

第二场景,精确覆盖了拓扑结构,是“阴影场景”,具有大量简化几何的3D场景。它主要用于照明和阴影,让一切都有一个体积感。

这可能听起来很简单,但它实际上证明了在开发期间最糟糕的问题之一。这两个场景叠加的丝毫偏差是明显的,并且在移动相机时作为令人不安的闪烁变得特别可见。

拓扑场景和影子场景都是在运行时动态生成的,可以从许多可以分为一些不同的基本类型。然后,我们从这些基本组件中构建了大量模块。从这些模块开始,我们的级别发生器可以在新的变化中组装复杂的情景。

或多或少的经典“瓷砖系统”构成了整体的基础。它建立了地板,墙壁和屋顶的基本结构。通过多个层和相对复杂的填充算法,TiXETET允许我们在没有大量手动工作的情况下创建变化。
我们实施的下一个技术主要适用于静态的无机物体,例如板条箱,是“体素对象”。它们是用一个名为Magicavoxel的工具创建,然后用我们自己的工具之一旋转,并以精灵的视角渲染。然后由2D艺术家手工涂上精灵。这些体素对象被“烘焙”进入现场–从渲染引擎的角度来看,它们不再作为独立对象存在。

“Voxel Decals”是简单的2D刷,这些刷子被绘制到现有的拓扑场景中。它们不会改变拓扑或施放自己的阴影,但为现场提供其他详细信息。层系统定义排序顺序,使得例如,例如,涂上墙壁上的贴花,但这些仍然被放置在其前面的物体隐藏。由于我们场景的动态结构,我们还可以在运行时创建(和删除)贴花–然后只需重建相关的块。

虽然Voxel对象已经产生了相当令人吸引人的结果,但他们的创作是复杂且耗时的,并且违反了我们将外部2D艺术家迅速整合到项目中的目标。它们也不适用于有机和动画物体,如植被或人物。 “Voxel Sprites”是我们对这些问题的答案。这些精灵首先是由2D艺术家的像素化和动画,然后在精灵片中组合。此外,生成正常地图和深度图–此过程大多使用现有工具(如Sprite Dlight)自动化,手动校正。

中途使用来自我们的第一场比赛的资产的新渲染引擎的一个非常原型。这一直是我们可以将其拉出的概念证明。

另一个自己的工具然后使用此和其他元数据首先为每个单独的精灵生成体素卷,以及从此暗影网格。在3D查看器中显示时,这些生成的网格看起来不太吸引。但它们给精灵足够“音量”,以渲染从自上而下的角度来看可信的阴影。

通过这种方法,它真的花了很多迭代,时间和耐心,产生强大和可靠的结果。但是,我们非常需要广泛的自动化。一支小团队像我们这样的小团队是不可能为所有像素化和动画精灵的暗影几何形状。

我们还专注于一段时间进行实验,将装备和动画的低聚3D网格与TOON遮蔽等技术相结合,并使用它们创建所需的像素艺术外观。不幸的是,这种方法没有带来所需的结果或无法在可用的时间内实施–但是,如果有必要,可以为未来的项目恢复足够有趣。

当我们认识到以前的方法不适合复杂的技术物体,如车辆或物体(如帐篷)的复杂技术对象?–Voxel对象似乎太“块”,详细亮起,而我们的自动生成暗影几何形状的算法只是由任务不堪重负。对于网格精灵,对象是在3D创作工具中构建的。然后,我们的另一个内部工具用于呈现出手头绘制的精灵。 Sprite用于拓扑场景,而3D网格用于阴影场景。

最后但并非最不重要的是“效果精灵”,普通的2D精灵,主要是对诸如发光等特殊效果的显着呈现。在这里,我们的层系统也确定排序顺序,并且与现有场景信息结合使用,使得可以通过它们前面的物体遮挡效果。

更复杂的场景,在低端系统上征税。此场景中的每个骷髅都有其各个暗影网格,可以互相施加阴影。

颜色调色板一路下来
为了使拓扑和阴影场景以及提到的所有单独部件,无论是烘焙进入场景还是动画,就在整个屏幕上,途径使用基于OpenGL 3.3的相当复杂的“延迟渲染管道”。延迟渲染器的最大优点是,可以单独修改和优化各个渲染通行证。

目前,使用25对顶点和像素着色器的大约十几个渲染通行证。

通过几乎整个管道运行的常见主题是我们的调色板系统:除了效果精灵和用户界面外,所有图形都是8位索引,基于具有64种颜色的主调色板 –32为字符,32为环境。所有阴影效果,即使是照明,最终只能基于此主调色板彩色操作。

我们的Voxel Sprite编辑器的屏幕截图。大多数元数据都与深度映射结合使用,以生成奇迹的暗影几何形状,如下右下方所示。

调色板是二维的–每个基色都分配多个色调,称为“颜色斜坡”。基色在完全照明中确定颜色,色调在光强度降低时确定灰度。色调可以内插。我们可以轻松控制这发生的频率–如果需要,更少(或否)插值步骤可以创建一个不错的8/16位复古外观。

下一个逻辑步骤是交换调色板。建筑物中的场景,碉堡或地牢只是使用不同的调色板而不是明亮的沙漠中的场景。但为什么只有在您也可以插入时才交换?我们的日/夜间周期基本上只是彩色调色板之间基于时间的插值,与可变照明设置(例如,太阳角和强度)和场景元素组合,可以打开/关闭,例如火炬或篝火。

在路上,你经常遇到神秘的老废墟。但像往常一样,纳粹不远。

实际的活动,就绪混合的调色板仅用于最终渲染通行证。这是一个相对复杂的着色器,但只有每像素一次运行一次作为屏幕空间效果–这对我们的需求充分效率。在此之前,所有其他渲染通过非常简化的术语,基本上仅计算索引此调色板所需的参数。

所有渲染通行证的详细描述可以轻松占用自己的文章,因此我们只需提到这里的一些亮点:

内部,“原生”分辨率为640×360,适应纵横比。只有在最后一步中,它只是升级到实际分辨率。

全拓扑场景(调色板指数,法线,深度映射)呈现为单个通行证中的多个屏幕外缓冲区。

定向光(阳光)和点灯呈现为使用阴影场景的单独阴影贴图。特别是点灯仍然是整个管道中最大的瓶颈,所以我们也花了很多时间在这里优化。

“光累积”通过累积在视野中的所有灯光。结果是两个具有各种用于组合物的照明信息的偏移缓冲区。

“组合”通过基于主动调色板计算每个单独像素的最终色调。在“当前”通过中,然后将其缩放并覆盖UI。

相同的场景,只有彩色调色板和灯光设置更改。调色板和颜色坡道允许令人兴奋的效果。

超过“只是2d”
猜测我们在开发过程中遇到了各种技术挑战,这可能并不难以遇到或至少由发动机的特殊性引起的技术挑战。我们首先为工具和编辑创建了许多资产和元格式,并以JSON或类似的文本格式存在。对于比较:虽然中途随着几十万行的JSON运送,但路径的原始数据超过了最后一计数的70亿线标记。解析大量的JSON既不是节省空间,也不是高性能。

我们最初从中途采用的其他技术和格式也在遇到来自途径的数据量时达到了它们的极限。在开发期间,由此产生的负荷时间从“忍耐”到“痛苦”,并且在较弱的测试系统上是不可接受的。因此,我们在开发期间更加紧凑地保存数据并显着降低负载时间。

通过一些例外,路径中的所有场景(地图,事件,抗辩)在运行时从大量较小的元素动态编译。即使在强大的计算机上,我们的水平发生器的第一次迭代需要几秒钟的小型场景。在某些测试系统上,它可能需要30秒钟来构建更大的场景。在这里,我们也投入了很多时间进入优化。

为了实现更老的帧质率和更少强大的系统也表明是非常挑战。各种微妙的差异,错误 &不同提供商(NVIDIA VS AMD VS Intel)的OpenGL驱动程序的QUIRK在不同的操作系统上成为一个恒定的麻烦源。

但是,我们投入了开发资产的最具技术努力,并为照明和影子效应提供管道。孤立地看待,任何必要的建筑块都没有正常火箭科学。挑战是将所有这些组合成功能,良好的结构,具有可靠的结果。

很难向大多数玩家传达,如据称经典的2D像素艺术外观的游戏,即在硬盘驱动器上分配大约1 GB也希望在运行时提供4 GB的免费RAM。在开发过程中,该值也显着提高。大多数内存由场景/体素数据,暗影几何和其他图形资产使用。场景发生器使用的一些数据结构并不像空间节省,因为它们在某些情况下,这仍然是真的。

我们编辑的早期原型。我们挣扎的一个方面是让视觉效果不那么嘈杂,易于阅读玩家。该解决方案是降低资产中的细节和复杂性。

结论
最后,我们留下了这个问题:这一切都值得吗?旨在实现我们的原始想法,以超越个人满足感吗?

简短的答案是,如在许多事情中:“是的,但......”它需要很多时间和资源来实现这项技术。途径的生产变得明显更复杂和昂贵。它会挽救了很多压力,时间和金钱,继续依靠“经典”2D发动机。

另一方面,独特的艺术风格吸引了对社交媒体的大量关注,特别是当我们开始将小型Dioramas发布为动画GIF时。这种视觉实力使我们和我们的出版商Chucklefish更容易获得游戏。
人类是非常视觉的。一个有吸引力的游戏使得从人群中脱颖而出,并在竞争激烈的市场中得到注意到。在这方面,我们成功了。


Daniel Ludwig
编码牛仔

Daniel has been working in the games industry for more than 20 years. As a coder, he loves to excavate and reinterpret graphics development methods of old. He shares his hoary findings at //twitter.com/code_disaster.

关于作者: 13. 11月20日
类别:
去顶级