
導讀前端
FDCON2018中國前端開發者千人峯會上,來自淘寶技術虛擬互動團隊的燒鵝在現場分享了淘寶Web 3D應用和遊戲開發的實戰。首先詳細解釋了3D與2D的區別,並闡述了在有限的環境下,淘寶技術虛擬互動團隊是如何經過Canvas去實現3D效果。隨着Web GL的發展,如何在手機淘寶中實踐,以及在項目中如何與Unity結合提高開發效率。而如今,團隊但願可以實現一個可視化的編輯器,幫助開發者快速得構建出相關的應用。web
你們下午好!咱們今天講個比較有意思的話題,這個話題在業界被談及得比較少。你們在座有作過移動端開發的同窗嗎?請舉個手,人還挺多的。那作過3D應用的同窗請舉個手,有用過Threejs的請舉個手,作過遊戲的呢..人這麼少,那我就放心了,能夠大膽講了(全場笑) 。今天講的正是移動、3D、遊戲三者交叉的話題。算法
canvas
自我介紹一下,我來自淘寶虛擬互動團隊,這個團隊主攻3D/遊戲/VR/AR。其中,咱們有一個小團隊叫斜槓實驗室(</Lab>),主攻Web方向上的動畫和3D技術。爲何咱們會在這樣交叉領域去發力作一些事情?去年的雙十一淘寶去年交易額多少?一千多億,其中有80%的GMV是來自移動端的,簡單地理解就是說咱們公司在電商領域80%的成交是經過手機客戶端實現的,而不是PC。這就是爲何在咱們要在移動端作3D/VR/AR的應用。後端
我今天演講分爲三塊內容:設計模式
第一部分講述初試Web 3D瀏覽器
第二部分講使用 WebGL 微信
第三部分講工做流相關的遊戲編輯器網絡
有一句話叫:給我一個支點,我就能撬動地球。不少人都作過2D遊戲,3D最大的區別就是多了一根Z軸,而給我一個Z軸我就能創造3D世界。不少作前端的同窗對3D這個事情是有誤解的,好比說 HTML5中的 Canvas 有兩個上下文,你們認爲 2d Context 只能畫2D,WebGL context 才能畫3D,這是一種誤解。架構
其實3D和2D並非由繪圖引擎來決定的,而是由數學家決定的。假如咱們要畫這樣的曲面會怎麼畫呢?首先有描述這個面的公式,這個公式根據X、Y入參算出Z的座標值,假設Z越大顏色越紅,Z越小顏色越綠,畫出來是這樣的。若是X、Y、Z乘以一種神奇的東西叫矩陣(矩陣是數學家發明的),這是3×3的旋轉矩陣,把每一個點都乘一下,而後畫到屏幕上獲得的結果就是這樣的。你們是否是一臉懵逼呀?這裏有一篇MSDN的文章專門講解了如何用 Canvas 2d 繪製3D曲面。我有一段時間寫過CSS3D的庫,就是用 glMatrix 數學庫作出很是酷炫的效果。
2016年雙十一咱們作過一個小遊戲,這個遊戲有玩過的嗎?(觀衆舉手)。這個遊戲是用Canvas 2d 繪製,就是用的 glMatrix 數學庫畫實現3D效果。當時爲何用Canvas 2d 呢?咱們淘寶市場部的同窗說咱們要作3D,由於人家 pokemongo 作了一個3D的,可是你這個東西最後要給我搞到 iPhone 4上去。你們知道 iPhone 4是不支持WebGL的,而當時開發時間很是緊張,我只能用了 Canvas 2d 的方案。
若是點了主場景中的貓,就會進入一個AR捉貓的環境。這個不是web渲染,由於當時移動端的web還不具有獲取攝像頭數據的能力,個人一個同事正在另一個分會場講WebRTC,你們後面有興趣能夠聽一下。因此當時AR只能用 Native 的 3D 引擎渲染,叫 T3D,顧名思義Taobao 3D。另外還有一個比較有趣的AR場景,叫「黃金貓」。黃金貓在雙十一先後三天會出如今銀泰或者蘇寧的商場上方,你只要搶到了這隻貓至少有一百塊錢的紅包獎勵。
這個項目中第一個難點的是建築模型的製做。咱們的設計師是個平面設計師,不會作3D,他當時給個人圖是這樣的,你看着辦吧,我當時花了整整一天時間作模型。第二點難點是地面算法,這個地面是六邊型的結構,要把地面從地球座標系轉換成3D世界裏的場景,會分幾步。咱們小時候都看過世界地圖,怎樣把一個球形的面投射到平面上呢?這種投影叫作墨卡託投影(Mercator projection)。這個投影算法的代碼是服務端拷給個人,由於要保持先後端算法一致,我複製了後端的投影算法。相比墨卡託投影,這是簡化的算法,由於要求看到周圍的貓是在五十米左右,因此精度並非特別高,簡單的算法就可以知足了。
當時的視角是這樣的,以用戶當前的位置經緯度爲中心,輻射一圈就能夠看到周圍有多少隻貓。這裏的六邊型地面若是用X、Y兩個軸的算法去計算實際上是比較慢的,我當時看了一篇論文,這是一個斯坦福的同窗花了二十年研究六邊型的算法,他本質上是以夾角爲120度的X、Y、Z三個軸爲座標軸算,相比算X、Y兩個軸的算法快不少。上面還有不少基於這個基礎算法拓展的算法如尋路等。
好不容易跨過了雙十一的坎,咱們已經看到 Canvas 2d 的方案在模型輸入和繪製性能方面都是很是弱的。如何繼續開發 3D 類的遊戲呢?可能你們會問,WebGL在PC上都不行,在手機上行不行呀?我跟你們說,如今徹底沒問題,咱們在上億臺同時在線的設備上都試過了,前提是要作一下WebGL能力檢測。PC還有一些古董瀏覽器不支持WebGL,反而手機比PC發展快得太多。
你們以前理解了3D的概念,3D不是繪圖引擎的功能,3D是數學的概念。那CPU繪圖與GPU繪圖有什麼區別呢?你們看一個小電影,這是英偉達幾個工程師錄的視頻,CPU這樣繪圖,GPU是這樣繪圖。咱們能夠看到,GPU是並行處理每個像素的。
咱們剛開始嘗試 WebGL 當心翼翼,由於怕給手淘帶來影響,事實上也形成比較大的Crash。2016年的聖誕節,市場部同窗說要不在首淘裏下一場雪吧,那就下了。後面我會讓你們下這場雪的代價。咱們還嘗試作相似於右邊這種模型粒子動畫,這是一隻天貓的模型。這兩個都是粒子系統,由於咱們剛開始不知道怎麼作複雜的3D渲染,咱們只能從最基礎的繪製「點」出發去嘗試。
咱們團隊有一種叫 PopLayer 的技術,能夠在當前 Native View上面隨時彈出一層 Web View,好比說前一陣子搜一下鹿晗出彈幕,還有明星打電話,都是經過 PopLayer 技術實現的。我剛纔提到,在淘寶首頁的 Poplayer 裏 下一場雪致使了大面積的客戶端Crash。緣由是iOS 下的 UIWebView 使用 webgl 渲染時,WebCore 會調用到 OpenGL ES 進行渲染,而蘋果發現有在後臺調用 OpenGL ES,就會直接結束 App。你們知道 RequestAnimationFrame API嗎?解法就是監測當前用戶退出後臺時或者當前頁面不可見的時候,會把RequestAnimationFrame 中止。
剛剛有同窗也提到過Page Visibility方面的API,咱們發現安卓是支持這個API的, 但IOS仍是須要調 Js Bridge接口來監聽App的是否退後臺的狀態。接着,我把遊戲主循環(或者動畫主循環)停下來以後還發現一些用戶會Crash。最後我發現一件很是神奇的事情,這個代碼你們都知道,它是用來獲取 Canvas 的 WebGL context,這行代碼爲何Crash呢?咱們翻了 Webkit 的源碼發現它有一個 reshape 函數,reshape 會經過 GPU 獲取當前畫布的高寬,因此它仍是會Crash。
3D之旅纔剛剛開啓,我接下來會跟你們分享一下中間不少心情,以及個人思惟是如何進化的。2017年的造物節時咱們作了真正意義上的3D應用,當時跟英國一家設計公司合做叫 FRAMESTORE,這個電影(《奇異博士》)你們知道吧,特效就是他們設計製做的。
FRAMESTORE 當時給個人東西是這樣的,俯視圖是這樣的,燈光是這樣打的。雖然他們在影視特效領域很是牛逼,可是他們也沒作過Web應用。而我當時也不知道怎麼和設計團隊合做,仍是個人老方法手寫代碼。他們給個人模型,我當時也不知道其餘高級的格式,只知道 Obj + Mtl。若是發現WebGL渲染有問題,咱們就去代碼裏找緣由,模型引用的材質對不對,貼圖對不對。咱們要翻代碼看一下是否是引用錯了。工做流的問題在這個項目中沒有解決,可是促使我開始尋找問題的解法。
這個項目還有一個性能問題,廣告牌發光效果,我第一個想到的是後處理(Post Processing),你們不理解的話,能夠把它看成實時濾鏡,若是在手機屏幕這麼大的Bloom濾鏡是會卡死的。我當時的方案是在每塊廣告牌上寫一個獨立的Shader,這樣在iphone6上至少是能夠流暢渲染的。
我剛纔講了這麼多,痛苦和迷茫。其實我以前作的東西也不能稱之爲真正的遊戲,只能算是營銷互動類遊戲。咱們仍是以爲作遊戲要向業界規範的方案靠攏,因此遊戲編輯器是必需要作的。雖然我今天並無作出一款遊戲編輯器,我會跟你們分享爲何我要作遊戲編輯器(如今已經正在作了),這中間的坎坷是今天要講的重點。
跟英國團隊合做以後我很是難過,他們的設計作得那麼酷,而我只能實現成這樣。我在中國環顧一圈,沒有看到Web 3D遊戲方面比較好的方案,由於在中國作WebGL的都百裏挑一。而後2017年我去澳洲參加了Web3D大會,他們當時用了 X3dom ,像 HTML 同樣用標籤地描述3D世界。這是一種很是陳舊的技術,雖然也是基於WebGL 渲染。這個方案已經推了十幾年了,老外也不知道爲何這麼執着,有幾十個Paper都是講這個的。他們講的東西都很是學術,我以爲對咱們的幫助並非很大。而後我又去工業界尋找解決方案。這是前索尼 PlayStation 的一位同窗作的應用,他用的技術你們可能會大吃一驚,他用了Unity。第一次看到 Unity 和 Web 嫁接起來是很是令我震驚的。我當時用的是iphone6,運行這個demo都是 60 fps 滿幀,他是怎麼作到的呢?我去查了一下它的代碼,雖然代碼是壓縮過的,可是爲了突破這個技術難關,我閱讀了壓縮後的代碼而且理解了它背後的實現。
我發現裏面有各類各樣的新穎的技術。好比,Unity能夠合併3D模型的貼圖。合併貼圖這件事情是很重要的。作前端都知道雪碧圖吧,爲何作雪碧圖?你們都知道是爲了減小網絡請求數,可是其實合併貼圖對運行時的性能有很大影響。GPU讀一張圖快仍是讀十張圖快?計算機資源是很是寶貴的,圖片要適度合併儘可能壓縮。一張200K的圖片,可能佔用3-4倍的顯存。JS優化半年減小30K,圖片批量壓縮減小個幾兆都是有可能的,因此要把時間花在可以快速見效的事情上面。
這張圖中的 Texture Baker 就是用來烘培而且合併圖片。而後,這個是 ITween Path 是Unity作路徑動畫的插件。 Unity還有一個插件叫Collada Exporter 。Collada 是標準的3D模型格式,看到這裏咱們已經拋棄了以前 Obj+Mtl 的老方案。而Runtime根據我以前的開發經驗封裝了一套MVC的方案。基於這套工做流,咱們作了2017年雙十一切紅包項目。咱們有時候開玩笑:騰訊作遊戲和阿里作遊戲有什麼區別?騰訊作遊戲是收錢,咱們作遊戲是發錢(全場笑)。用Unity帶來的好處是可以直接導入設計師給的源文件,如Maya源文件、Photoshop源文件。這裏咱們看到,紅包模型是預先切開的,你們知道切水果也是這樣作的,即便你豎着切菠蘿它仍是橫着裂開的(全場笑)。
至於紅包的特效,我會常常逛一些國外的網站,這是某個遊戲開發者寫的Shader特效,我就照着他的思路來寫了一個相似的。你們看到一個紅包在天上飛,上面有光在流動,其實整個場景中一盞燈都沒有打。光照計算,特別是點光源的計算是很是耗性能的。因此你們作3D應用的時候儘可能要少放光源。這種效果其實只要在像素着色器中寫一行代碼就解決了。
紅包是怎麼切中的呢?Picking 這個話題對沒有開發過遊戲的人也許比較陌生,切紅包的遊戲裏我當時作了兩種方案:一種叫作 CPU Picker ,另外一種是 GPU Picker 。所謂 CPU Picker 在每一個紅包上面套上一個包圍盒,計算射線有沒有擊中這個包圍盒,由於 CPU Picker 的計算成本和場景的複雜度正相關, 用包圍盒會比較快;還有一種方案是 GPU Picker,經過拾取離屏畫布上面的顏色值就好了。雖然感受GPUPicker性能會特別好,但在移動端性能表現卻不佳,由於拾取顏色的過程其實是CPU和GPU通訊的過程,這個過程會比較慢。因此,CPU Picker 性能會更好一點。
還有一點就是Dom操做,在Web遊戲開發中,Dom操做就是魔鬼。我抓了比較慢的一幀花了25毫秒(約40幀)。遊戲邏輯加上WebGL渲染就花了那麼幾毫秒,而DOM操做卻耗掉很長的時間,並且還引起了重繪(紫色部分)。因此 Dom 在遊戲裏是不合適的,GUI 部分須要用2D的Canvas或者WebGL渲染去解決。
最後講一下音效,我我的很是喜歡遊戲中聲音給我帶來的獎勵。我作切紅包的時候注意到了上面幾點,這也是我上週去北京Unity大會上聽到關於CRIWare的聲音中間件的內容:
1. 背景音樂要有漸有漸出,這樣用戶體驗比較好;
2.用戶作一些操做或者比較重要操做的時候,當前聲音要強調一下,背景音樂減弱一下;
3.聲音要有變化,好比說不少射擊的遊戲,若是槍聲都同樣,用戶聽覺會疲勞的,咱們切紅包時左切和右切都是不同的。
這個軟件叫 bfxr,是一款製做遊戲音效的小軟件,在線和客戶端版本都有,人人均可以設計音效。
講了那麼多技術點,咱們總要看一下業界真正作遊戲的人是怎麼作的。我大概探索了一兩年,發現 Playcanvas 引擎是Web世界上最健全的遊戲引擎。它的引擎代碼是開源的,可是編輯器不開源。我分析了一下它的引擎源碼,大概有幾部分組成:ECS的架構,Unity 也是採用這樣的設計模式。第二個是PBR,基於物理的渲染模型,看起來更像真實世界的渲染。物理引擎也是很重要的,還有輸入設備,好比說你的遊戲手柄、手機都是輸入設備。Playcanvas 和 Threejs 有什麼區別?Threejs只是一個3D渲染庫。遊戲還有一個很是重要的東西叫編輯器,這是 Playcanvas在線的編輯器,我看了這個遊戲以後就以爲必定要作編輯器,由於編輯器是引擎的載體。若是沒有編輯器,咱們每次開發遊戲要注意的工程和技術問題太多。
最後講一下咱們團隊思考的編輯器的架構,如今只是一張工程架構圖。遊戲最後發佈的內容是什麼?就是一堆資源,圖片、模型、音頻、腳本,在Web開發環境中最後都要發上CDN。遊戲裏的大部分資源如音頻、全景圖、模型這些都是第三方軟件輸入的,模型資源的序列化、減面、合併、烘培等操做咱們暫時可能不會去作(仍是交給Unity作),中間GUI部分就是編輯器的面板操做,最後 Script 組件和 Shader 能夠經過 VS Code 來編輯。這張圖是我一兩年的心得,裏面有一些細節時間問題這裏就不展開了。OK,我講完了,你們有什麼問題。
問1:開發遊戲是否是要先學習數學知識?
燒鵝:這些都是騙人的,遊戲引擎都封裝了數學庫。遊戲開發中,邊作邊學很重要。我舉個我上週在Unity Beijing聽到的例子,開發青蛙旅行的人在他們公司是個助理工程師,一羣前輩都把活給都扔給了他,而後他就開發出來了。關於遊戲和圖形的數學方面的書,你只要搜一下游戲數學的關鍵詞,就會出來很是多的結果。
問2:老師您好,咱們這邊咱們的團隊都是Web開發的,對遊戲開發不是很清楚,以現有的Web開發爲基礎,咱們的同窗應該學習那些知識?
燒鵝:前端轉型到遊戲開發者,能夠先試着作一款遊戲,或者說別人作了一款比較好玩的遊戲,你不看源代碼的狀況下,你用本身具有的技術知識克隆出來,你在作的過程當中天然而然會接觸到遊戲開發中的各類概念和知識體系。
本文分享自微信公衆號 - 淘系技術(AlibabaMTT)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。