太强了!外国小哥花16个月用Three.JS打造了一个无缝切地图的3D开...
外国一位小哥耗时16个月打造的3D版赛车游戏,这两天忽然火了起来。
只需一个浏览器,就能驾车从森林、海滩,“无缝切换”到广袤的沙漠甚至平原。甚至还可以选择春夏秋冬或者白天黑夜的环境风格。
在不想自己开车的时候,竟然还可以开启自动驾驶模式,感受一波“AI飙车”的快乐。
△甚至有“自”行车&自动驾驶小巴
网友们也是嗨得不行:此情此景怎能少得了经典BGM逮虾户(Deja Vu)
下面我们来看看它究竟是怎么实现的。
他是怎么实现的!
这个游戏完全使用Three.js来开发,经大帅测试,这个游戏可以在大部分网页浏览器中运行,甚至在移动端上也有着非常优秀的表现。
此外,开发者 还给出了不同级别的渲染设置来保证性能,玩家可以自由选择适合自己设备的配置。是【模糊粗糙】还是【细节丰富】,丰俭由君哦~
除了开头提到的随意切换地点、季节和天气以外,这个赛车游戏也可以随意切换各种车型和视角。
那么这个赛车游戏中“任意变幻”的环境到底是如何生成的?
01
生成高度图
-
使用类似于PerlinNoise的算法生成无限平铺的高度图,并加以修改以实现更为逼真的山景。
-
使用Alea这个库来生成伪随机数。https://www.npmjs.com/package/alea
02
规划道路
-
公路的起点要选择整个地形世界中不太陡峭,也不能太深的某个地方。将这里作为道路中线的第一个点。
-
选择一个方向来测试周围的高度图用以评估横向和纵向的梯度。
-
然后,使中线向一个坡度最小的方向移动10米。这个点的信息被写一个双向链表中,每个点位信息都包含坡度,道路宽度,曲率等元数据。
-
实现一个永无止境的道路,以距离车辆位置15KM的地平线为界,这是开发过程中耗时最久,让小哥掉了最多头发的一个问题。
-
使用二次贝塞尔曲线以1m的单位做路线的平滑处理。
03
地面环境
-
为了进一步提升性能,靠近道路和远离道路的地块使用了不同网格密度来处理。
-
道路被渲染为一个简单的矩形网格,由3个高细节块和9个低细节块组成,每个长100m,随着车辆的前进而循环。
04
图形
-
地面纹理采用世界坐标UV,并混合PerlinNoise以改变植被的颜色。
-
基于坡度混合悬崖面纹理和顶点位移。
-
小哥一开始想实现动态阴影贴图,但过于复杂从而放弃后选择采用一种更简单的方案,就是在树木的下方应用深色纹理,造成有阴影的视觉假象。
-
所有树叶都由简单的精灵图和几何体组成,将多种变化存储在一个纹理图中,该纹理使用顶点着色器中的噪声采样。
05
物理系统
-
每个轮子都单独结合重力,摩擦力和地面法线来独立计算物理上动力学的特性。以此来解决车辆底盘的位置问题。
-
道路两侧的围挡没有真正的采用物理碰撞算法,而是使用距离检查来解决。
-
物理特性的计算极其消耗性能,为此小哥去除了树木,指示牌等其他东西物理特性的计算。
06
优化
-
通过合并相近网格的几何图形,非常细致的管理实例化对象从而节省提升渲染效率。
-
车辆在道路中的进行情况会被不断追踪计算,并依据远景能见度来释放不可见的元素并使其重复使用。
-
提供一系列和质量有关的设定以满足不同设备上的渲染。
开源了吗?
目前这款游戏还没有开源。不过小哥表示,虽然没有开源整个项目的计划,但后续可能会开源部分子系统,如图形MOD接口等。
对于这款游戏的未来,小哥也立下了几个flag,包括在环境上,开发更多的越野地点、加入更多环境细节,包括建筑、动物、植物阴影、灯光效果等;
赛车上,加入更多的赛车皮肤和车辆类型;天气上,细化天气类型(下雨、下雪、刮风等),也进一步改善已有天气的效果;
功能上,将来会加入竞争模式和全球排行榜(包括限时竞速、比拼距离等),同时对系统进一步进行优化,未来适配手柄、赛车模拟器等。
体验地址
https://ezshine.jnsii.com/cases/slowroads/
最后
如果你觉得这篇内容对你挺有启发,我想邀请你帮我个小忙:
-
点个「喜欢」或「在看」,让更多的人也能看到这篇内容
-
我组建了个氛围非常好的前端群,里面有很多前端小伙伴,欢迎加我微信「sherlocked_93」拉你加群,一起交流和学习
-
关注公众号「前端下午茶」,持续为你推送精选好文,也可以加我为好友,随时聊骚。