在Three.js上拥有旧气氛的新游戏

有很多老游戏迷。 他们不反对散发出st的怀旧之泪,不,不,而是像二十多,三十,四十岁或-代替期望的数量-在几年前演奏“打砖块”,“帕克曼”或“波斯王子”。 DOS盒和模拟器-帮助他们。 是的,在那里,我最近在YouTube上观看了第一流的2D“波斯王子”,其中一位年轻的流光在越过另一个致命障碍后,用手额头挥舞着汗水说道:“我从未在计算机游戏中如此害怕过”。 也就是说,即使年轻人也能够欣赏到旧游戏的硬性和酷劲。


我想,为什么不以类似的风格来创建新游戏? 是的,有各种各样的翻拍和克隆。 此外,像素艺术风格的现代游戏也很受欢迎。 但是,所有这些游戏通常都会重复任务,机制,有时甚至会完全根据旧游戏的等级进行设计。 好吧,或者相反,它们提供了一个全新的情节和位置,这仅仅是“古董”的视觉风格。 但是,如果您想像旧游戏的新组成部分紧随系列的最后部分,该怎么办? 我决定创建一个。

我使用了2D平台游戏,并在其中保留了经典侧视图的同时在其中添加了3D图形。 他建立了新的迷宫,提出了新的任务,介绍了任务并实现了库存位置。 稍微增加了空间感,增加了90度转弯。 也许,在那个远古时代,在具有三个自由度的3D游戏全面过渡之前,可能会出现类似的情况。

由于我喜欢为浏览器编写游戏,因此决定为浏览器编写游戏。 由于其特殊性,它没有任何疯狂的多边形,至少在同一时间在屏幕上显示,没有开放的世界。 因此,所有这些都不会给浏览器带来沉重的负担。 为了显示3D图形,我选择了自己喜欢的包装器,选择了我最喜欢的Three.js库(WebGL)。 没有其他库被使用,并且代码是用纯JavaScript编写的。

Three.js和我遇到的问题


3D图形引擎的开发人员大约每两年一次定期发布其创作的新版本。 在Three.js脚本库的情况下,开发人员会以疯狂的频率(大约每月一次)进行更新,这使我们感到高兴。 在撰写本文时,最新版本的数字为106。这似乎很好。 (不)

为什么没有人甚至考虑向后兼容性? 当Three.js开发人员将材质属性重命名为environment时,我意识到, “休斯顿,我们有问题 好的,可以说,在我的整个代码中,用搜索替换将“环境”一词更改为“颜色”并不难。 但是,当他们排除了光源在没有照明的情况下产生阴影的可能性时,我意识到现在的着陆确实处于危险之中,而冷静基地逐渐开始变成狂犬病基地。 但是,后来证明,还不错...

事实是,在我的游戏中,除了烘烤光之外,还使用了动态照明。 3D场景中的动态源数量极大地影响了性能。


我在游戏设置中选择了来源数量-从1到7。并且根据视频卡的功能,您可以尝试不同的值。

还有一个数组,其中包含每个光源的坐标和特征-强度,颜色等。 它就是这样。 当在玩家周围的某个正方形中移动游戏世界时,具有指定特征的设置中指定的光源数量将点亮。 也就是说,光源似乎跟随玩家(在他周围)被云遮住了。

那么,休斯顿,我们有什么问题? 我报告。

问题1:阴影


光源会产生阴影。 我注意到,点光源的阴影比定向阴影(点光源)消耗更多的资源。 这是可以理解的:在点源的情况下,仅在给定的圆锥体中向所有方向和方向投射阴影。 但是,我建议,当不需要所有方向的阴影时,可以一次使用两个光源:一个点将仅创建照明,而定向光源将仅在某个方向创建阴影。 事实证明,这非常适合我的游戏,确实可以大大节省计算能力。


金字塔限制了阴影出现的区域。

但是,麻烦的是,从Three.js r73版本开始,定向光源不再只能投射阴影,它现在也始终可以提供照明。 然后,它发出的光以及阴影在区域内传播。 删除点光源并仅留下定向光源是不可能的:我需要全方位的照明。 并且使用这两种光源并将其调整到所需的亮度也将不起作用:这样,圆锥体内的对象将被照亮得多。 在各个方向使用带有阴影的“诚实”照明只会严重影响游戏的性能。

并且他们删除了定向光源.onlyShadow的必要属性,仅因为引擎的作者希望如此。

问题编号2:属性名称


我决定宁愿使用r71版本,该版本仍然需要我的照明属性。 为什么不选择r72呢? 毕竟,该属性仅在版本r73中消失。 因为我已经写了很多代码来加载r71版本的3D模型,动画和物理。 在r72版本中,大量的属性名称已更改:类型-shadowMap已变为shadow.map等。 通常,我也不想重命名所有这一切。 一个版本之间的差异很小。 因此,我们仍然使用r71版本。

问题三:烤阴影



不同版本的引擎的烘烤光看起来也不同。 我不知道他们在那里对他做什么,但是当在纹理上应用阴影贴图时,亮度甚至颜色会发生巨大变化。 通常,我以某种方式通过在GLSL代码中模拟引擎并在使用阴影贴图的地方在3D模型的加载器中设置自动颜色校正来解决此问题。 当然,这仅适用于版本r71。 对于其他版本,您将不得不使用其他一些参数。 这是保留使用r71版本的另一个原因。


实际上,切换到最新版本是没有意义的,因为与旧版本相比,工作结果在性能方面没有根本差异。

好啊 定向光源仅产生阴影。 我可以将阴影烘烤并将其加载到版本r71的程序集中。 而现在-最重要的伏击。 字符。

问题4:骨骼动画


这就是我战斗了很长时间。 总的来说,我花了几周的时间来尝试找到某种可行的算法,以将带有一组动画的角色转移到游戏中。


Three.js的最新版本不存在此问题。 在那里,我在一个著名的在线服务中成功创建了一个动画角色模型,将其转换为流行的gltf格式,并将其上传到测试场景。 但是,如果Three.js的新版本使用gltf 2.0格式,则我的仅支持1.0。 看来,问题出在哪里,转换为1.0并下载。 事实并非如此简单。 显然,gltf 1.0格式有多种变体。 我需要一个文件,除了主模型文件外,还应该存在两个扩展名为* .glsl的文件。 但是在这种情况下,主文件的格式可能会有所不同...总的来说,我找不到能满足所有参数的转换器,尤其是因为它也从新格式转换为旧格式。 我也无法完成对gltf 2.0支持的Three.js的旧版本:这种支持在代码中太深了,植根于数学中,在引擎的不同版本中以不同的方式实现...总的来说,它在gltf中不起作用。

我尝试对3D模型使用.dae格式。 结果,模型本身正在加载,但是我无法使角色动画正常工作。 还有纹理问题。

.md2格式的结果很好。 角色将立即显示,并且所有动画均可正常工作。 但是,据我所知,md2是Quake 2的模型格式,有人在Three.js中实现了对它的支持,只是为了好玩。 找不到这种格式的模型,甚至更何处设计和保存自己的角色,我都没有找到。

我尝试了其他几种格式。 但是在它们之下,没有针对three.js的引导程序,没有程序在其中创建保留角色的程序,因此它们根本不支持骨骼动画。

基本的“狂犬病”恰好可以重命名基本的“绝望”。

我已经几乎绝望了,考虑以牺牲性能(定向光源的故事)为代价切换到新版本的引擎,我最后一次决定折磨json格式,这实际上是我开始的。 但是,这是我第一次无法在Blender 3D编辑器中重复将Three.js捆绑包中的示例文件中的字符从原始.blend格式转换为.json的过程。 动画以某种方式随机变坏并表现为随机状态,并且从Blender到json的导出器有十几种变体,每一个都无法正常工作。 此外,我还在多个版本的Blender上进行了尝试。 JSONLoader本身,即json格式的模型加载器,现已从three.js中删除。 我决定查看他不再支持哪个版本,以便从他的版本中而不是我的版本中获取他和3D模型的样本。 她原来是r88。 瞧! 我设法在r71中重现了测试模型的输出,并且包括角色动画在内的所有内容在游戏中都运行良好!

“鹰”号安全着陆。

然后,我决定在Blender中编辑测试角色的动画之一,以查看是否可以制作自己的动画。 一个无赖在这里等着我。 我编辑的动画根本不想在游戏中正常工作。 角色在初始位置冻结。 尽管其他动画没有问题。 但这是东西。 也就是说,现在的问题是我对编辑动画的一些细微差别不了解。

然后我想-如果我问这个例子的作者怎么办? 但是要找到作者并不容易。 他在Github上没有人脉。 搜索昵称和他的Twitter上的几个其他参数,但是,私人消息被关闭。 但是从那里我得知他是美国某大学的教授,并去了这个教育机构的网站。 事实证明,这位教授以他的例子作为方法学材料,与学生们一起从事3D图形的研究。 然后我回到了Github,浏览了所有的存储库。 在这里,我在等待成功。 如我所料,他的示例存储在单独的存储库中。 不仅是我在three.js示例中看到的内容的副本,而且是一个仔细地附有说明的示例(显然,适用于学生)。 我下载了档案,并按照说明进行了所有操作。 万岁!

这对人类来说是很小的一步,但是对于一个人和他的游戏来说却是巨大的飞跃!

没问题,休斯顿!



现在,我了解到,如果我坚持使用这种格式,这些说明以及Three.js,JSONLoader和Blender的这些版本,并且以相同的方式进行所有操作,则可以创建我的任何角色并将其加载到浏览器游戏中。 好消息是,尽管使用了旧版本的引擎,您仍可以使用最新版本的3D Blender编辑器并使用动画创建任何角色。 此时,您需要使用此特定工具包根据严格定义的方案导出它们。

是的,我注意到新版本的Three.js还有一个问题:在游戏过程中,由于某些原因,滚动屏幕时会观察到不断的fr。 这不是由于资源消耗增加所致-处理器和视频卡未加载100%。 在旧的r71中,没有这样的耻辱。

现在,剩下的工作只需要在带有动画的3D角色编辑器中进行。 当然,还有关卡的几何形状。 我不知道要花多少时间。 但是到目前为止,我刚刚在Webkit上收集了一个免费的演示版本,并将其上传到流行的应用程序商店。

关于游戏的一点


名字 我将游戏称为Percy Lancaster。 这里的一切都很明显:“我是一名艺术家,我知道。”

图形是如何创建的 。 我在3D编辑器中创建了两个平面,将它们彼此隔开一定距离布置,以便将远一个平面隐藏在最近的平面后面,在它们上面拉一个石头纹理,在最近的一个平面上切孔,然后删除不必要的部分(即看不见的部分)。 然后,他为飞机的地板和天花板建模。 因此,事实证明这是玩家行走的走廊。 我通过各种纹理使地点多样化。


在游戏本身中,没有这种类型,只有侧视图,没有明显的黑色空间。 这只是走廊的一般视图。

我决定创建相交的走廊。 在转弯期间,另一条走廊的一堵墙完成,整个结构转弯,然后移除第一条走廊的墙。 基于这种机制,我还计划创建塔,您可以在其中爬上螺旋楼梯。


实际上,使用静态图形是没有问题的,它可以轻松地从任何3D编辑器导出到json。 正如我已经提到的,困难仅出现在烘焙阴影和角色动画上。

性能。 在高清屏幕分辨率(即1280x720)上,我不太强大的GT-730显卡的负载约为35-40%,而至强E5440处理器的负载约为30%。 我认为这不仅仅是可以接受的结果。

操作系统 到目前为止,该演示仅在Windows下作为Webkit的程序集提供。 将来,我计划启动浏览器版本。 我发现并非所有浏览器都能平滑滚动屏幕。 我仍然需要管理和调用图形输出功能。 同时,我选择了Webkit 26.0版。 她体重很小,一切都很好。

声音。 声音部分来自免费库,部分产生。 总的来说,到目前为止,它们已经做到了“成为”。 虽然我没有为它们打扰太多。

录影带 全程演示级别。


计划


我计划进行众筹,并用募集的资金聘请3D建模者,这将为他创建一个正常的角色和动画。 不过,这些图形不是我的。 但是现在我知道如何在游戏中引入角色了。

另外,我计划为最新版本的Chrome和Firefox启动浏览器版本。 让我告诉你一个秘密,我什至设法在MS Edge上运行游戏,但是由于某种原因,没有任何物体上的烘焙阴影纹理重叠,但我仍然没有弄清楚。 接下来,我将调试适用于Linux和Android的浏览器,如果我获得供他人测试的Apple设备,则还将调试iOS和MacOS上的浏览器。

从长远来看-编写自己的库来使用WebGL,例如Three.js:我不喜欢它们突然重命名属性并删除我需要的功能。 相反,Three.js提供了我不需要的大量机会。

我想以后,当我找出适用于不同操作系统的所有浏览器的正确游戏操作时,我会写一篇有关此技术细节的文章。

Source: https://habr.com/ru/post/zh-CN468261/


All Articles