作者:小玉
链接: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的前景一片光明。

Unity3D将来时:WebGL的更多相关文章

  1. Unity3D将来时:IL2CPP(上)

    http://inpla.net/thread-8197-1-1.html Unity3D将来时:IL2CPP(上) (注:本文详细的讲述了C#,Mono,.Net, IL等Unity使用到的概念,如 ...

  2. Unity5和WebGL移植指南的一些总结

    对于手游开发者来说,更新版本往往意味着非常复杂的过程,你需要根据反馈做更新.测试.提交然后等待审核,而由于不需要客户端依赖,页游往往是快速测试游戏版本的最佳途径,很多人可能都知道Unity 5可以再不 ...

  3. unity发布的WebGL部署到IIS

    一.创建WebGL代码 在win7下,Unity3D中发布WebGL,然后部署到IIS,只要代码是对,关键是添加mime类型 二.为网站添加mime类型 .json text/json .unity3 ...

  4. 触控的手牌—Cocos Creator

    科普 Cocos Creator是触控最新一代游戏工具链的名称.如果不太清楚的,可以先看一些新闻.   新编辑器Cocos Creator发布: 对不起我来晚了! http://ol.tgbus.co ...

  5. IL2CPP

    [官方教程] IL2CPP 深入讲解系列介绍 (汇总帖) http://forum.china.unity3d.com/forum.php?mod=viewthread&tid=8960&am ...

  6. Unity游戏开发中的内存管理_资料

    内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...

  7. 64bit upload app store

    Unity将来时:IL2CPP是什么? http://zhuanlan.zhihu.com/indieace/19972689 Unity3D将来时:IL2CPP(下) http://www.game ...

  8. Unity3D 5中增加WebGL 播放插件

    http://www.csdn.net/article/2014-03-18/2818822-Unity-5-game-engine 其实我是搞3d的,这篇文章里所有的术语看了都有很强的亲切感. Un ...

  9. Unity3D和Egret3D的基情

    Unity3D依靠多平台发布这个核心特点,目前如日中天,屌丝引擎之王绝无来者.Egret白鹭引擎,也着实在微信上刷了一屏又一屏.这二者似乎风马牛不相及,但是这个无处不搞基的年代,让一切皆有可能. U3 ...

随机推荐

  1. string、Empty和null三者的区别

    string.Empty和null三者的区别 本文转自  http://www.bitscn.com/pdb/dotnet/201003/181883.html 时间:2010-03-01 00:00 ...

  2. SOC芯片的FPGA原型验证

    FPGA验证在SOC设计非常重要,一般而言,做一些RAM和FIFO的替换以及相应代码转换.具体分下面几步: 1 替换RAM,FIFO和时钟 RAM和FIFO控制器需要RAM的接口都放在了设计顶层,方便 ...

  3. OLE/COM 对象查看器 & OLE常用术语

    "OLE/COM Object Viewer"(OLE/COM 对象查看器)查看你系统上安装的所有 COM 对象时,是一个非常便利的工具. 它是 Windows 2000 资源套件 ...

  4. javaSwing

    一.使用java Swing写个登陆界面,感受一下布局管理器的特性和熟悉一下控件的使用 package com.swing; import java.awt.BorderLayout; import ...

  5. SOA架构介绍和理解

    SOA架构介绍和理解 SOA的正确方法论及目标模型,其实SOA在实现架构落地上,需要考虑到对服务的组合,不断的重用现有的服务,让企业应用可以逐步集成,快速实现业务的迭代. 通过SOA架构分层将服务按照 ...

  6. 关于oracle数据库的导出导出

    Oracle数据导入导出常用两种方式: 1.是通过plsql-->tool-->export/import进行bmp文件的导入与导出: 2.使用命令imp/exp执行oracle数据导入与 ...

  7. 转 Visual C++ 将整合Clang

    原文见:http://www.solidot.org/story?sid=45898 微软在11月释出的Visual C++更新将整合Clang开源C和C++编译器,开发者将可以用Clang编译Win ...

  8. Spring+springmvc+Mybatis整合案例 xml配置版(myeclipse)详细版

    Spring+springmvc+Mybatis整合案例 Version:xml版(myeclipse) 文档结构图: 从底层开始做起: 01.配置web.xml文件 <?xml version ...

  9. Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute'

    [TypeLoadException: Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from as ...

  10. 游戏中的人工智能——初探AI

    一.游戏中的人工智能 让游戏具有挑战性: 让游戏好玩的关键因素是为之找到合适的难度等级: 人工智能在游戏中的作用是通过提供富有挑战性的竞争对象来让游戏更好玩,而在游戏中行动逼真的非玩家角色(NPC), ...