Unity WebGL发展计划
在今年的三月发布的Unity 5.0中,我们展现了WebGL的技术预览。之后,Google停止了(默认下的)Chrome浏览器中对于NPAPI的支持(意味着Unity Web Player将不能在Chrome上使用),这极大促使了Unity的开发者们将WebGL作为一项新的替代技术。一些人已经发布了使用Unity WebGL开发的游戏,但我们仍然听闻有些人在导入现存的Web Player游戏时遇到了问题。需要特别注意的是,WebGL和Web Player ,尽管它们针对的目标相同, 但却是两种非常不一样的平台,这意味着并不是在Web Player能实现的所有功能现在都能在WebGL上一一实现。更值得注意的是,WebGL不仅仅是一项全新的技术,它更是一个可以快速迭代的生态系统,所以我们期待或许在一年之后,这项技术能带来更多不同的可能。
因此,我们想跟大家分享在WebGL上即将发生的一些改变,以及我们对于这项技术的未来打算。
在Unity5.1中,我们的重中之重是去修复在Unity 5.0中首发的WebGL版本中存在的漏洞。并且,我们IL2CPP团队在过去的几个月中一直在致力于修复IL2CPP中的漏洞,在5.1版本中大家会看到相应的提升。因为WebGL使用IL2CPP作为它的脚本运行环境,这些提升也极大帮助了WebGL平台。
除了漏洞修复,在Unity 5.1中的另一项新特性:Crunch texture compression(材质压缩)也会使WebGL用户特别感兴趣。该功能可以用JPEG形式的压缩比例去压缩材质,然后进行传输/储存,并在运行时解压成有利于GPU的DXTn材质。这将极大降低WebGL内容的传输大小,因为材质大小往往在资源中占据最重的比例。
让我们考虑下5.1版本之后的发展,来看看我们之后的发展计划,以及WebGL平台在未来会推出的版本。
当前大家在使用Unity WebGL时遇到的最大问题之一就是,浏览器(特别是Chrome)在尝试运行Unity WebGL内容时会消耗大量的内存。以下是遇到的具体问题:
需要为WebGL内容分配鎖定的內存空間。这是用于Unity运行的内存。该内存的大小可以在Web Player的设定中进行配置,这部分内存需要支持Unity在特定时间点载入所有对象和素材。你可以使用Unity中的Memory Profiler对使用的空间进行debug。这需要在浏览器堆中有保護的内存空间。如果浏览器的内存较低或是堆损坏,会导致分配内存失败。
浏览器需要过多内存进行JavaScript解析。Unity放出的针对WebGL player构建的JavaScript代码比其他常用的JavaScript代码在体积上要大很多,而JavaScript可能需要大量的内存去解析这些代码。Chrome的V8有时会因为遇到这样的问题而导致崩溃,因为它无法分配出足够的内存进行解析。在Firefox中,这样的问题没有那么严重,因为Firefox使用asm.js对JavaScript进行AOT编译,这会带来更小的内存开销。
从许多使用案例来看,以上的问题是当前WebGL遇到的最大的问题,而且这处理起来并不简单。现在,我们能做的是减少代码的发送,我们已经在上个HackWeek(Unity内部头脑风暴活动)对此做了实验,来测试我们能在一个项目中降低多少WebGL的分发体积。经过一周的测试,我们能够创建一个分发包大小仅有1.2MB的简单Unity项目,这是通过代码剥离,提升编译设置,以及删除冗余等方式达到的。然而这些只是理论上的可实现的,其中一些改进是不具推广性的。我们在这一周收获了很多,我也期待从Unity 5.2版本开始构建的产出大小能够大幅度降低。同时,我们也在开发相关的工具,让开发者可以直观可视地了解哪些代码模块被包含在了构建中,有多少代码被生成,以及它们被包含进构建中的原因。我们计划在Unity未来的版本中(最早在5.3版本中)发布这些工具,而这会使极大帮助用户去分析和优化他们的构建产出大小。降低代码产出大小也能极大地优化启动时间,并降低解析代码的延迟时间。
但是,我们期望能依靠更先进的浏览器技术来最终改善这些内存问题。所有浏览器都在朝着64-bit的构建发展,这会使得构建的地址空间变大。更重要的是,Mozilla, Google和Microsoft正在研发一种名为WebAssembly的全新技术,将asm.js代码转换为字节码形式,而这些字节码能够非常高效地被编译为原生代码。我们非常期待这项技术,因为它能极大降低读取时间,内存开销和WebGL的分发包大小。
这点与上文谈论的内存问题联系紧密,分发包大小是Unity WebGL当前需要处理的问题根源。分发包大小会影响下载时间和内存使用。为了保持下载时间合理,我们想让数据以压缩的形式被传输。现在,我们依靠http协议中的gzip压缩支持来达到这个目的,因为该技术能让浏览器在下载过程中进行解压处理。然后,使用它其实并不十分便捷,因为它经常需要在服务器端进行手动设置来保证正确运行。此外,gzip与更现代的压缩算法比起来效率大大降低了。
在未来的版本中(当前计划为Unity 5.3),Unity会原生支持全平台的数据文件内部的素材压缩,也将使得WebGL用户不再需要依靠http进行素材数据的压缩(我们可能会针对代码做一些定制化的压缩处理)。这会使WebGL内容的分发变得更为简捷,数据也会在被使用前一直保持压缩的状态,进而降低素材的内存占用(我们的一些测试也说明,因为更少的内存带宽占用会使素材的读取时间降低。)
我们在去年发布了一些WebGL性能表现的参照基准,对比了基于浏览器和原生环境的情况,发现了在某些领域拥有不俗的性能表现,也通过对比在浏览器,WebGL和原生环境,发现了性能表现的差距。我们希望在未来能够缩小这些差距。我们发现,大多数存在于原生环境与WebGL间的表现差距,可以通过使用SIMD和/或者多线程的方式进行优化。这两项功能在未来会出现在WebGL中。
SIMD.js:可以将SIMD支持添加到JavaScript语言中。Mozilla, Google和Microsoft都在计划添加此项支持。我们可以使用这项技术在WebGL上得到与其它平台相同的表现提升。
Shared Array Buffers:可以让WebWorkers (JavaScript中相当于线程) 分享同样的内存,这使得将当前的多线程代码编译成JavaScript成为可能。Mozilla已经实践了这项技术,他们已经成功地运行了Unity WebGL内容,而这些内容也能通过多线程运行。他们运行了我们的参照项目,在某些方面达到了非常好的基准效果,并比运行多线程取得了更高的分数。Google已经宣布增加Shared Array Buffers支持的计划。
另一个大家关心的问题是,我们何时打算推出Unity WebGL的移动端支持。现在我们并没有做任何打算,并且会尽量避免在移动端运行内容(然而运行并不会出现警告)。总得来说,运行成功率还非常低(一些高端的安卓移动设备产生了不错的结果,但是在大部分用户常用的设备上,效果仍不理想)。在极大改善上述的内存和性能表现的问题之前,我们不会看到移动端太大的改变,但在之后移动端的表现也会得到整体地提升。我们无法给出任何关于移动端支持的具体时间。我们相信随着未来的技术进步,这个方面会有所改观。
另一个常见问题是,在WebGL项目中往往会花费很长的时间进行构建。Mozilla现在正在努力将整个emscripten 编译工具链移植到原生代码中(当前是基于混合语言操作),我们认为这将加大提升构建时间。在Unity 5.1中我们已经将emscripten升级成了新版本,将JavaScript优化转移到了原生代码中,相较于5.0版本,缩减了构建时间。
现在,Unity WebGL使用一套定制的基于Web Audio的执行音效,这与其它所有使用FMOD的Unity构建平台有所不同。这让我们可以控制所支持的音效格式进行基本的播放,并调节音量和音高。这对任何目前可执行的音效功能都有效(我们会修复不能执行的漏洞)。
WebGL是一个基于OpenGL ES 2.0的JavaScript API。相比于其他平台,这在某些程度上限制了图像的处理能力,因为OpenGL ES 2.0无法支持许多我们可以在其他平台上实现的特性。Unity现在有一些硬性的编码规定使得图像功能与图像APIs绑定在了一起,这在以前是合适的,因为OpenGL ES 2.0被当做一个“移动”图像API,但当WebGL有可能在更高端的GPUs上运行该代码时,以前的假设就不再适用了。这使得视觉效果难以达到预期,尤其是运用到阴影和新规格的着色器上时。我们正在努力修复这一问题,使得着色器的特性可基于每个项目进行配置,而不是被硬性编码成各个图像API。
此外,在GDC2015上,我们演示了在WebGL 2.0上运行的Unity 5原型(基于OpenGL ES 3.0),这也会使WebGL的图像功能更进一步。在Unity 5.2中,我们计划加入实验版的WebGL 2.0支持,但我们不期望浏览器会支持在今年年底前发布版本中的API。
现在,Unity WebGL支持Chrome, Firefox和Safari。在主流浏览器支持中,我们还欠缺Microsoft浏览器支持。当前的Internet Explorer版本中有WebGL支持,但是缺少Web Audio支持(所有我们无法播放任何的音频),而且表现也不尽人意。所以虽然IE浏览器可以读取内容,但是当前我们没有官方宣布支持。
我们期待在Microsoft Edge发布后情况会有所改变,这个即将发布在Window 10上的默认浏览器将取代IE。IE会支持Web Audio,也会支持asm.js,这会让Unity内容得以更好的呈现。
Unity的MovieTexture现在尚未支持WebGL,理论上视频是可以进行播放的,但是我们现在没有这方面的支持打算,因为我们的MovieTexture音频播放无法在当前WebGL上使用。其实,简单地使用浏览器中的html5视频功能就将功能齐全的视频纹理解决方案整合到Unity WebGL上来。
点击“阅读原文”查看更多关于Unity WebGL的未来发展计划。