Unity3D未来时:WebGL

做者:小玉
连接:https://zhuanlan.zhihu.com/p/19974794
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。

随着Unity5.0的发布,WebGL平台的部署也正式登场(目前还处于Beta状态)。WebGL是一项利用JavaScript API呈现3D电脑图形的技术。区别于其余须要浏览器加载插件的形式(好比Flash和Unity的Web Player),经过使用WebGL技术,咱们只须要编写简单的网页代码便可以实现3D图像在浏览器中的展现。使用WebGL的好处是显而易见的:在玩游戏以前无需下载任何插件,打开浏览器,输入游戏地址,就能够直接进行游戏了。并且WebGL的这套JavaScript API透过浏览器直接和系统的显卡打交道,效率也能够获得保证。


WebGL在Unity中的实现
具体到技术细节,WebGL在Unity中是经过IL2CPP,Emscripten和asm.js这几大关键技术来实现的。

  • IL2CPP:将脚本代码翻译成C++代码的模块。具体细节在上两篇有详细的讨论()这里直接略过。
  • Emscripten:将编译后的Byte Code翻译成Javascript,经过这个步骤之后,代码就能够在浏览器中直接运行了。虽然Emscripten大多数状况下是翻译c/c++的代码(在Unity中的使用状况就是如此),可是它也能够接纳任何由符合LLVM标准的编译器生成的其余语言的Byte Code,将其转换成JavaScript。
  • asm.js:相比前面两个模块,asm.js是最有趣的部分。也是Unity用来保证WebGL游戏运行效率的关键。他的主要做用就是对Javascript进行优化!提升JavaScript在浏览器中的运行效率。后面咱们就具体的讲讲asm.js是如何作的。

    ASM.JS
    此次咱们先直接看代码比较:
    先来个简单的C代码:
    int f(int i){
      return i+1;
    }
    相应的asm.js代码:
    function f(i){
      i=i|0;
      return (i+1)|0;
    }
    能够看到咱们在每句后面都”比特或”上了0,这个操做对原来的变量里的值没有任何影响,看上去是无用的操做。可是它却保证了咱们代码里的i和(i+1)都是整数而不是其余类型。

    另一段:计算字符串长度
    size_t strlen(char *ptr){
      char*curr = ptr;
      while(*curr !=0){
      curr++;
      }
      return(curr-ptr);
    }
    相应的asm.js:
    function strlen(ptr){//calculate length of C string
      ptr=ptr|0;
      var curr=0;
      curr=ptr;
      while(MEM8[curr]|0!=0){
         curr=(curr +1)|0;
      }
      return(curr-ptr)|0;
    }
    在代码中,MEM8是一个Byte类型的“View”,用来操做实际的”typed buffer”。(在这个例子中是ptr指向的内容。有关View和typed buffer的概念请参考 JavaScript typed arrays
    相似的处理出如今asm.js的各个地方:asm.js中包含了JavaScript的一个严格子集 —— 包括严格类型的整数、浮点数、数值计算、函数调用和堆访问,使得其在被执行的时候跳过了致使JavaScript变缓慢的动态转换和其余一些操做,大大加快了速度。

    咱们能够在代码中加入“use asm”开关开尝试开启asm.js模式。
    function MyAsmModule(){
         "use asm"
         //module body
    }
    asm.js有一套本身的规范(具体能够参考这里),你彻底能够本身手写asm.js代码,但更多的状况是利用上面提到的Emscripten自动的生成代码。
    若是浏览器支持asm.js,那么程序的代码会获得加速,可是若是浏览器不支持asm.js,也无需担忧。asm.js本质上是JavaScript的一个子集,它用到的全部语法和JavaScript彻底一致。在不支持asm.js的浏览器上执行的效率和通常的JavaScript脚本是同样的。目前支持asm.js的浏览器只有FireFox一家。IE和Chrome也在积极跟进。按照微软的说法,在Windows 10中所使用的Chakra引擎将支持asm.js,而且微软正与Mozilla进行合做,以争取尽快实现它。Chrome则将经过TurboFan这一在V8上通过优化的编译器提供对asm.js的支持。若是你的Chrome版本是41,这意味着其已经内嵌的TruboFan Beta版,能够加速asm.js了。

    Unity例子测试
    首先你得有Unity5.0,使用官方或者本身的项目,切换到WebGL平台。我这里用的是官方的Space-shooter,将编译好的整个包放入到Web Server的目录中,而后在浏览器访问。
    在浏览器中打开项目的Html页面,找到并打开WebGL_Build.js,发现其中除了少许能够阅读的函数之外,文件的绝大部份内容都是相似用汇编形式写出的asm.js代码。

    咱们游戏的绝大部分逻辑代码就出如今此

    总结
    Unity5.0中的WebGL平台部署是一个使人激动的选项,纯html的方式运行游戏意味着咱们能够把更加复杂和有趣的游戏直接部署在网页上。让其在诸如微信这样的平台上直接传播。

    这个魔术的背后离不开IL2CPP,Emscripten和asm.js。asm.js有着化腐朽为神奇的力量,经过一套工做流转换,使咱们得到高效的代码。
    高效的代码只是其中的一个好处,另一个好处是代码混淆:因为asm.js的天性使然,这些看上去像极了汇编的代码很好的解决了html5游戏客户端源码直接暴露的风险。这一点对于商业游戏来讲也很是重要。能够说asm.js天生就是为了WebGL游戏准备的!而从各大浏览器厂商对其支持力度也能看出之后的流行非它莫属。其实Emscripten+asm.js不光光是Unity可使用,其余引擎也同样可使用。例如Unreal3也使用一样的方法来将游戏带到浏览器上。而cocos2d-x也有尝试使用该技术。WebGL的前景一片光明。
相关文章
相关标签/搜索