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的前景一片光明。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM