重新想象飞行模拟器:过去和现在

本文是Microsoft的Web开发系列的一部分。 感谢您支持使SitePoint成为可能的合作伙伴。

Apple于1980年推出了Flight Simulator的第一个版本,令人惊讶的是,它是3D版本! 那是一个了不起的成就。 当您考虑到所有3D都是手工完成,精心计算和低级像素命令的结果时,这会更加令人惊讶。 当布鲁斯·阿特威克(Bruce Atwick)处理早期版本的Flight Simulator时,不仅没有3D框架,而且也根本没有任何框架! 这些版本的游戏大多是用汇编语言编写的,与流经CPU的1和0仅一步之遥。

当我们开始为网络重新构想Flight Simulator (或称为Flight Arcade)并演示在新的Microsoft Edge浏览器和EdgeHTML渲染引擎中可能实现的功能时,我们不禁想到创建3D的对比,然后现在-旧的Flight Sim,新的Flight Sim,旧的Internet Explorer,新的Microsoft Edge。 当我们使用诸如Babylon.js之类的出色框架在WebGL中雕刻3D世界时,现代编码似乎几乎是豪华的。 它使我们能够专注于非常高层次的问题。 在本文中,我们将分享我们应对这些有趣挑战之一的方法:一种创建逼真的大规模地形的简单方法。

注意:本文的交互式代码和示例也位于: http : //www.flightarcade.com/learn/

建模和3D地形

大多数3D对象都是使用建模工具创建的,这是有充分理由的。 在代码中很难创建复杂的对象(例如飞机,甚至是建筑物)。 建模工具几乎总是有意义的,但是也有例外! 其中一种可能是类似Flight Arcade岛的起伏山丘的情况。 我们最终使用了一种发现更简单甚至可能更直观的技术:高度图。

高度图是一种使用规则的二维图像来描述岛屿或其他地形等表面的高程释放的方法。 这是一种处理海拔数据的非常普遍的方式,不仅在游戏中,而且在制图师和地质学家使用的地理信息系统(GIS)中。

为了帮助您了解其工作原理,请查看下面的交互式高度图。 尝试在图像编辑器中进行绘制,然后检查结果地形。

图像1-互动式高度图演示

在此处尝试交互式演示。

高度图的概念非常简单。 在上面的图像中,纯黑色是“底”,纯白色是最高的峰。 中间的灰度颜色表示相应的高程。 这为我们提供了256个海拔高度,这对于我们的游戏来说是很多细节。 现实生活中的应用程序可能会使用全色谱来存储更多级别的细节(如果包含alpha通道,则为256 4 = 4,294,967,296个细节级别)。

与传统的多边形网格相比,高度图具有一些优点:

首先,高度图要紧凑得多。 仅存储最重要的数据(海拔)。 需要以编程方式将其转换为3D对象,但这是经典做法:您现在可以节省空间,以后再进行计算。 通过将数据存储为图像,您可以获得另一个空间优势:您可以利用标准的图像压缩技术,使数据变小(通过比较)!

其次,高度图是生成,可视化和编辑地形的便捷方法。 当您看到一个时,它非常直观。 感觉有点像看地图。 事实证明,这对于Flight Arcade尤其有用。 我们在Photoshop中设计并编辑了我们的岛屿! 这使得根据需要进行小的调整非常简单。 例如,当我们要确保跑道完全平坦时,我们只需确保在该区域上涂上单一颜色即可。

您可以在下面看到Flight Arcade的高度图。 看看是否可以找到我们为跑道和村庄创建的“平坦”区域。

image2-heightmap的飞行岛

Flight Arcade岛的高度图。 它是在Photoshop中创建的,它基于著名的太平洋岛屿链中的“大岛”。 有什么猜想吗?

image3-texture-mapping-3d结果

在对高度图进行解码后,将纹理映射到生成的3D网格上。 下面的更多内容。

解码高度图

我们使用Babylon.js构建了Flight Arcade,Babylon为我们提供了从高度图到3D的非常简单的路径。 巴比伦提供了一个从高度图图像生成网格几何的API:

image4代码创建高度图

详细信息的数量取决于该细分的属性。需要注意的是,该参数是指高度图图像每侧的细分数量,而不是像元总数。 因此,稍微增加该数目可能会对网格中的顶点总数产生很大影响。

20个细分

=

400个细胞

50个细分

=

2500个细胞

100个细分

=

10,000个细胞

500个细分

=

250,000个细胞

1000个细分

=

1,000,000个细胞

在下一部分中,我们将学习如何对地面进行纹理处理,但是在尝试创建高度图时,查看线框很有用。 这是应用简单线框纹理的代码,因此很容易看到高度图数据如何转换为网格的顶点:

image5-简单线框材料

创建纹理细节

一旦有了模型,映射纹理就相对简单了。 对于Flight Arcade,我们仅创建了一个非常高的图像,该图像与高度图中的岛屿匹配。 图像在地形轮廓上拉伸,因此纹理和高度图保持关联。 这真的很容易可视化,并且所有的制作工作都是在Photoshop中完成的。

原始纹理图像的创建尺寸为4096×4096。 好大! (为了使下载合理,我们最终将尺寸减小到2048×2048,但是所有开发工作都是使用全尺寸图片完成的)。 这是原始纹理的全像素样本。

岛岛图像的全像素样本

原始岛纹理的全像素样本。 整个城镇只有300像素左右的正方形。

这些矩形代表岛上城镇中的建筑物。 我们很快注意到,在地形和其他3D模型之间可以达到的纹理细节层次上的差异。 即使我们拥有巨大的岛屿纹理,差异也很明显!

为了解决这个问题,我们以随机噪声的形式将其他细节“混合”到了地形纹理中。 您可以在下面看到之前和之后。 请注意,附加噪声如何增强地形中细节的外观。

image7-带有混合的其他详细信息

我们创建了一个自定义着色器以添加噪点。 着色器为您提供了对WebGL 3D场景渲染的无与伦比的控制,这是着色器如何有用的一个很好的例子。

WebGL着色器由两个主要部分组成:顶点着色器和片段着色器。 顶点着色器的主要目标是将顶点映射到渲染帧中的某个位置。 片段(或像素)着色器控制像素的最终颜色。

着色器使用类似于c的高级语言GLSL(图形库着色器语言)编写。 此代码在GPU上执行。 要深入了解着色器是如何工作的,请参阅本教程 ,了解如何为Babylon.js创建自己的自定义着色器

顶点着色器

我们不会改变纹理在地面网格上的映射方式,因此我们的顶点着色器非常简单。 它仅计算标准映射并分配目标位置。

image8-vertexdx着色器

片段着色器

我们的片段着色器稍微复杂一些。 它合并了两个不同的图像:基本图像和混合图像。 基础图像映射到整个地面网格。 在Flight Arcade中,这是岛屿的彩色图像。 混合图像是用于在近距离为地面提供一些纹理和细节的小噪声图像。 着色器组合来自每个图像的值以在整个岛上创建组合的纹理。

Flight Arcade的最后一课在大雾天举行,因此像素着色器的另一项任务是调整颜色以模拟雾。 调整基于顶点与摄影机之间的距离,而远处的像素被雾“遮盖”得更多。 您将在主着色器代码上方的calcFogFactor函数中看到此距离计算。

image9-calcFogFactor函数

我们的自定义Blend着色器的最后一部分是Babylon使用的JavaScript代码。 该代码的主要目的是准备传递给我们的顶点和像素着色器的参数。

image10准备用于着色器的参数

image11-混合材料原型

Babylon.js使创建基于着色器的自定义材质变得容易。 我们的Blend材料相对简单,但是当飞机低落到地面时,它确实对岛的外观产生了很大的影响。 着色器将GPU的功能带给浏览器,从而扩展了可应用于3D场景的创意效果的类型。 就我们而言,这就是画龙点睛!

使用JavaScript进行更多操作

微软在许多开源JavaScript主题上有很多免费的学习知识,我们的使命是利用Microsoft Edge创造更多的知识。 这里有一些要退房:

还有一些免费的入门工具: Visual Studio CodeAzure试用版跨浏览器测试工具 -所有这些工具都可用于Mac,Linux或Windows。

本文是Microsoft的Web开发技术系列的一部分。 我们很高兴与您共享Microsoft Edge和新的EdgeHTML渲染引擎 获取免费的虚拟机或者在你的Mac,iOS设备,Android或Windows设备上远程测试modern.IE

From: https://www.sitepoint.com/reimagining-flight-simulator-then-and-now/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值