用于 Unity 和虚幻引擎的 Asm.js 与 WebGL 已翻译 100%

oschina 投递于 2015/08/05 11:32 (共 27 段, 翻译完成于 12-01)
阅读 9994
收藏 64
2
加载中

本文来自微软,是一个 web 开发系列文章的一部分。感谢你对实现了 SitePoint 的成员的支持。

The Unity development stack

Unity 以及 Epic 的虚幻引擎,是频繁被游戏开发者使用的中间件工具,并不被限于去创建被编译成作为可执行文件运行的应用程序。Unity 之前有一个 web 播放器,它是一个使用了 ActiveX 的可下载插件。Chrome 停止了对 NPAP (网景(Netscape) 插件 API)的支持,但却在一年前才公布这个消息。

在 4 月份,随着 Chrome 42 stable 的发布,他们终于把斧头挥向了他。要说为什么,可以有很多原因,而“挂起、奔溃、安全问题还有代码复杂性”则是最常被他们挂在嘴边的。Google 建议转移到 web 标准支持的技术,比如 WebGL,这种技术我下面会提到。

LeoXu
LeoXu
翻译于 2015/09/01 21:00
1

因为有了 web 技术标准,微软也正效仿上面的做法,吐槽自家的 ActiveX,VBScript,attachEvent,以及其它传统的技术。对于 ActiveX 空间的需求已经因为 HTML5时代的功能而减少了很多, 其同样支持跨浏览器间互操作的产生。

随着 WebGL 和 asm.js 的出现,开发者现在在浏览器中就可以充分利用他们计算机设备的能力,并接触到之前无法企及的市场。在本教程中,我会告诉你他们如何做到这一点的知识:

为什么要编译成 JavaScript?

JavaScript 是唯一一种能在所有的浏览器上运行的语言。尽管只有 JavaScript 将会在浏览器上面运行,但你还是可以用其他语言编写代码,然后仍然编译成 JavaScript,如此就可以让它们运行在浏览器上了。这是由一种以 emscripten 而闻名的技术变成可能。

LeoXu
LeoXu
翻译于 2015/09/01 21:11
1

Emscripten 是一种基于 LLVM 的项目,能以 asm.js 形式将 C 和 C++ 代码编译成高性能的 JavaScript 代码。简言之: 近乎于使用 C 和 C++ 直接运行与浏览器里面的原生速度,甚至更好。emscripten 将 OpenGL, 一种桌面图形 API,转化成 WebGL,它是这类 API 的 web 变体。

那么这些代码是如何转成 WebGL 的呢?

Unity 最近也为他们的运行在 WebGL 上的软件做了一些基准测试

然而,让代码进行交叉编译 (经常也被叫做 transpiling ) 并非没有缺陷。静态类型语言中发掘出来的通用的性能增强技术,比如多线程 (JS 是单线程的) 以及 SIMD (单指令多数据) 都无法使用。

Mozilla,近来也跟着其他领头的技术公司搞起 SIMD.js 来,因此性能的提升和处理器使用的降低应该会是不久的未来将发生的事情。点击这里可以了解更多。出来上述的那些性能上的调整, Unity 还有赖于他们新的脚本运行,IL2CPP (内联 2 C++)。那是另外一篇文章要讲的事情了,不过 Unity 已经在每隔几个星期就做一个的华丽的系列网站中向诸位呈现 IL2CPP 的功能了。

LeoXu
LeoXu
翻译于 2015/09/01 21:26
1

IL2CPP 拥有两个独立的部分:

  • 一个预先 (AOT) 编译器

  • 一个用于支撑虚拟机 (VM) 的运行时库

来自.NET的中间语言 (IL) 经由 AOT 编译器编译成 C++ 源代码。一些诸如独立于平台的对线程和文件的访问,还有垃圾收集器,这些服务和抽象都是运行时库带来的好处。

这里就能看到:

Unity compilation diagram

图片来源于 Unity

 当你在一台 Windows 机器上运行一个 .exe 时,在那个点上它实际上还不是字节码 (0 和 1). 它仍然还处在 VM 在运行时读取的一个二进制文件中, 然后才被转成字节码。Windows 机器上的 DotNet CLI 就是能读取这个二进制文件的虚机示例。CPU 除了二进制谁都不认,所以这一额外的步骤是需要的。

仍然感到迷惑? 这篇文章解释了机器码、字节码和VM间的不同之处。

LeoXu
LeoXu
翻译于 2015/09/02 21:42
1

asm.js 是如何适应需要的?

Asm.js,Assembly JavaScript 的简称, 它是 JavaScript 的一个自己。一个 asm.js 程序,不管是运行在一个现有的 JavaScript 引擎中,还是一个能识别并优化 asm.js 的预先(AOT)编译引擎中,其行为都是一致了 — 当然,速度要除外!

速度方面,很难就它与原生代码的比较进行精确的测量,而之前对被编译成 asm.js 的 C++程序所进行的基准测试显示,一般会比使用 clang 这个面向 C,C++ 以及 Obj-C 编程语言的编译器所进行的原生编译慢两倍,有一点很重要,那就是这一测试是在对单线程程序运行最有利的情况下进行的。下面有更多关于 JavaScript 语言局限的内容。

LeoXu
LeoXu
翻译于 2015/09/05 18:48
1

在后天, Clang 使用了 LLVM,它是一个用于构建,优化并产品中间甚或二进制机器码文件 (还是那些0和1)的库。LLVM 可以被当做一个编译器框架来用,其中你可以提供 “前端”(解析器和词法分析器,比如 Clang) 和 “后端” (将 LLVM 展现转换成实际的机器码的代码)

想阅读更多: Mozilla 的 Alon Zakai 有一个美轮美奂的幻灯片 详细描述了这是如何运作的。

那么 asm.js 有多酷呢? 好吧它有自己的 Twitter 账户, @asmjs。不过 asm 的站点有点冷清,它包括 W3C 的文档,以及一个内容全面的 FAQ。更好的是,Mozilla 在 2014 年对 Humble Mozilla Bundle 进行了整合,让你可以买到一堆利用 asm.js 的游戏。

LeoXu
LeoXu
翻译于 2015/09/05 18:59
1

为什么不把 JavaScript 转成 asm.js呢 ?

JavaScript 因为其动态特性,并不能被编译成 asm.js,并提供诸多好处。当尝试将其编译成 C 甚至是 本地代码 是也会遇到同样的问题 – 使用了它的 VM 有必要关注那些非静态的方面。不过,你也可以手写 asm.js.

如果有人已经以一种完全静态的方式对标准的 JavaScript 进行了翻译,那就有可能会有要使用 asm.js 的需要了。Asm.js 的存在是为了保证不需要开发做出额外的努力就让 JavaScript 变得更快。让 JIT 去理解一门动态语言及其静态编译器是非常困难的。

LeoXu
LeoXu
翻译于 2015/09/05 19:06
1

为了更好的理解这一点,重点在于理解为什么 asm.js 会提供一种性能上的优势;或者说为什么静态类型语言执行起来能比动态的类型语言更好。原因之一就是“运行时类型检查需要花费时间”而思想更加深刻的一种回答应该要把对于优化静态类型代码的增强特性包含进来。来自于一种诸如 C 这样的静态类型语言的终极天赋就是事实上在这类语言的代码将要被编译时,编译器就知道每个对象的类型。

Asm.js 是 JS 的一个受限子集,能很容易的被翻译成字节码。为了让这个子集获得这种优势,第一步必须做的就会是需要去分离 JS 所有的高级特性,这会有些复杂。不过 JavaScript 引擎是被优化过的并被设计成能将所有的那些高级特性直接翻译成字节码 – 因此像 asm.js 这样的一个中间步骤并没有提供太多的好处。

LeoXu
LeoXu
翻译于 2015/11/02 19:55
1

WebGL 是做什么的?

WebGL (Web 图形库) 是一套 JavaScript API,使用它无需使用插件就能在任何兼容的 web 浏览器上渲染交互式的 3D 计算机图形和 2D 图形。WebGL 有三个明显的优势:

  • 多任务 : 对反光材质或者复杂光照环境的绘制会产生大量的开销,而鉴于 JavaScript 是单线程的而且受限于 CPU 的性能,为什么将这些任务分一些给 GPU,让其承担一些重任呢 ?

  • 性能 : 利用(GPU内置于设备中的)硬件加速,WebGL 非常适合用来实现游戏和复杂的视觉效果。

  • 着色器 : * * 复杂的视觉效果可以用被称作”着色器(shader)“的小程序来产生。这可能跟产生一个怀旧的棕色效果,或者对诸如水或者火焰这样更加复杂的模拟一样简单。看看 Shadertoy 所展示的一些例子,它们着实突出了这一点.

LeoXu
LeoXu
翻译于 2015/11/02 20:10
1

当你对一个 WebGL 工程执行 build 操作时,Unity 会穿件一个目录,里面包含下面这些文件:

  • 一个 index.html 文件,将你的内容嵌到一个 web 页面中。

  • 一个 JavaScript 文件,包含面向播放器的代码。

  • 一个 .mem 文件,包含一个二进制镜像,用来初始化播放器的堆内存。

  • 一个 .data 文件,包含了资源数据和场景。

  • 一些辅助性的 JavaScript 文件,用来初始化和加载播放器.

你也可以定制页面的样式来更好的契合游戏主题,而全屏 API也被推荐用来获得一个更加身临其境的体验。

WebGL project

对学习 WebGL 感兴趣吗? 进入 WebGL 学院 去看看完整的课程吧。

LeoXu
LeoXu
翻译于 2015/11/10 20:36
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(8)

人头马没面
人头马没面
唉 没长进啊
shawumu
shawumu
这翻译很蹩脚啊
wmlgl
wmlgl
线程是硬伤
eechen
eechen
Mozilla进行BananaBread项目的几个目标:
首先,作为一个测试用例,在浏览器中运行复杂的3D游戏,它可以让我们尝试应用浏览器的新特性.
另一个目标是证明这种性质的游戏可以基于JS和WebGL在浏览器上运行,因为现在很多人都持怀疑态度.
最后,在这个项目中的所有代码是开放的(以及所有的美术资源),以便其他人可以从这一努力学习和使用这个代码来创建自己的网页游戏.

Emscripten是Mozilla的一个实验性项目,目的是把C/C++开发的应用编译成JS或HTML5的应用,
编译过程中需要首先把C/C++程序编译成LLVM的中间代码,然后再转换成JS代码,
这样做的主要原因是可以很好地复用现有的针对LLVM的优化.

Asm.js是由Mozilla提出的一个基于JS的语法标准,主要是为了解决JS引擎的执行效率问题,
尤其是使用Emscripten从C/C++语言编译成JS的程序的效率.

Sauerbraten引擎:
http://sauerbraten.org/
eechen
eechen
Mozilla开源WebGL FPS游戏BananaBread
https://developer.mozilla.org/zh-CN/demos/detail/bananabread/download
BananaBread是一款BSD开源的,能够运行在浏览器的在线第一人称射击游戏.BananaBread基于由C++和OpenGL技术写成的Sauerbraten引擎,并使用Emscripten(基于LLVM)编译成为JavaScript和WebGL,以便它可以使用基于标准的Web API的现代浏览器中运行,无需安装其它任何插件.BananaBread还用到了asm.js来提升游戏的速度,使用WebRTC技术来实现多人通信.

Ubuntu 14.04(i5-3230M集成显卡HD4000)在Firefox 37里满帧(60FPS)跑WebGL FPS游戏BananaBread:
http://static.oschina.net/uploads/space/2015/0905/142046_aVTz_561214.png

BananaBread按键说明:
Esc:暂停退出.
0:主菜单,可以添加敌人.
9:切换视角.
大洋的顶端
大洋的顶端
然并卵,一是网速;二是设备;三是各大浏览器标准;目前玩个2d flash网游勉强还行,3d 的别想了,想想浏览器内存飙升不停崩溃谁受得了?缓存还是个问题,
攻伤菊菊长
微软自家人写的文章,居然不顺便推广一下BabylonJS
攻伤菊菊长
基于浏览器的编辑器的顶部

应该是基于浏览器的编辑器前端吧,而且直接翻译成基于浏览器的编辑器就行了
返回顶部
顶部