2016年最令科技界激動的話題,莫過於VR會如何改變世界。有些電影已開始涉足VR,讓用戶不僅能看到3D影像,更能以「移形換影」之術身臨其境,帶來前所未有的沉浸式觀影體驗;此外,遊戲領域也開始VR化,用戶再也不用忍受遊戲包裡的單一場景。這些酷炫效果帶來了巨大想像空間,VR正走近人們的生活。然而現實是,除了偶爾體驗下黑科技的奇妙外,VR並沒有真正普及,在資本和硬體廠商狂熱的背後,質疑聲也此起彼伏。
目前,雖然VR硬體的發展已經走上了快車道,但內容卻非常單薄。一部VR電影的成本相當高昂,VR遊戲也不遜色。內容創作成本的居高不下,導致了VR的曲高與寡。要脫下那一層高冷的貴族華裳,飛入尋常百姓家,VR尚需解決內容供給這一難題。以HTML5為代表的Web技術的發展,或將改變這一僵局。目前,最新的Google Chrome和Mozilla Firefox瀏覽器已加入面向HTML5技術的WebVR功能支持,同時各方也正在起草並充實業界最新的WebVR API標準。基於Web端的這些虛擬實境標準將進一步降低VR內容的技術創作成本及門檻,有利於全球最大的開發者群體—HTML5(JavaScript)開發者進入VR內容創作領域。這不僅是Web科技發展歷程上的顯著突破,也為VR造就了借力起飛的契機。
Web端VR的優勢
Web可降低VR體驗門檻
Web技術不僅使創作VR的成本更加低廉,而且大大降低技術門檻。 Web VR依託於WebGL技術的高速發展,利用GPU執行運算以及遊戲引擎技術針對晶片級的API優化,提高了圖形渲染運算能力,大大降低開發者進入VR領域的門檻,同時Web VR還可以更好地結合雲端運算技術,補足VR終端的運算能力,加強互動體驗。
可以肯定,Web擴展了VR的使用範圍,廣告行銷,全景影片等領域已經湧現一批創新案例,許多生活化的內容也納入了VR的創作之中,如實景旅遊、新聞報道、虛擬購物等等,其內容展示、互動都可以由HTML5引擎輕鬆創建。這無疑為其未來發展帶來更多想像空間。
Web開發者基數龐大
除了技術上的實現優勢,Web還能為VR帶來一股巨大的創新動力,因為它擁有著廣泛的應用範圍與龐大的開發者基數,能幫助VR技術打贏一場人民戰爭,讓VR不再只是產業大亨們的資本遊戲,而是以平民化的姿態,進入廣大用戶日常生活的各個層面。
相信假以時日,VR應用會像現在滿目皆是的App一樣,大量的VR開發者藉助於Web端開發的低門檻而大量進入,同時各種稀奇古怪的創意層出不窮,虛擬實境成為電商商家必須的經營手段等。若到了這個階段,VR離真正的繁榮就不遠了。
開發Web端的VR內容
接下來我們透過實作作業來真正製作一些Web端的VR內容,體驗WebVR的便利優勢。我們知道,許多VR體驗是以應用程式的形式呈現的,這意味著你在體驗VR前,必須進行搜尋與下載。而Web VR則改變了這種形式,它將VR體驗搬進了瀏覽器,Web+VR = WebVR。在進入實務之前,先來分析一下WebVR實現的技術現況。
WebVR 開發的方式
在Web上開發VR應用,有以下三種方式:
HTML5+ Java Scnipt + WebGL + WebVR API
傳統引擎+ Emscripten[1]
第三方工具,如A-Frame [2]
第一種方法是使用WebGL與WebVR API結合,在常規Web端三維應用的基礎上透過API與VR設備進行交互,進而得到對應的VR實作。第二種是在傳統引擎開發內容的基礎上,例如Unity、Unreal等,使用Emscripten將C/C++程式碼移植到Java Scnipt版本中,進而實作Web端的VR。第三種是在封裝第一種方法的基礎上,專門針對沒有程式設計基礎的一般使用者來生產Web端VR內容。在本文中我們主要以第一和第三種方法為例進行說明。
WebVR草案
WebVR是早期和實驗性的JavaScript API,它提供了訪問如Oculus Rift、HTC Vive以及Google Cardboard等VR設備功能的API。 VR應用需要高精度、低延遲的接口,才能傳遞一個可接受的體驗。而對於類似Device Orientation Event接口,雖然能取得淺層的VR輸入,但這並不能為高品質的VR提供必要的精度要求。 WebVR提供了專門存取VR硬體的接口,讓開發者能建構舒適的VR體驗。
WebVR API目前可用於安裝了Firefox nightly的Oculus Rift、Chrome的實驗性版本和Samsung Gear VR的瀏覽器。
使用A-Frame開發VR內容
如果想以較低的門檻體驗一把WebVR開發,那麼可以讓MozVR團隊開發的A-Frame框架。 A-Frame是一個透過HTML創建VR體驗的開源WebVR框架。透過此框架建構的VR場景能相容於智慧型手機、PC、 Oculus Rift和HTC Vive。 MozVR團隊開發A-Frame框架的是:讓建構3D/VR場景變得更容易更快,以吸引Web開發社群進入WebVR的生態。 WebVR要成功,需要有內容。但目前只有很少一部分WebGL開發者,卻有數百萬的Web開發者與設計師。 A-Frame要把3D/VR內容的創造權力賦予給每個人,其具有如下的優勢與特點:
A-Frame能減少冗餘程式碼。冗餘複雜的程式碼成為了嚐鮮者的障礙,A-Frame將複雜冗餘的程式碼減至一行HTML程式碼,如建立場景則只需一個
A-Frame是專為Web開發者設計的。它是基於 DOM,因此能像其他網路應用程式一樣操作3D/VR內容。當然,也能結合box、d3、React等JavaScript 框架一起使用。
A-Frame讓程式碼結構化。 Three.js程式碼通常是鬆散的,A-Frame在Three.js之上建立了一個宣告式的實體元件系統(entity-component-system)。另外,元件能發布並分享出去,其他開發者能以 HTML的形式進行使用。
程式碼實作如下:
// 引入A-Frame框架<script src="./aframe.min.js"></script><a-scene> <!-- 定义并创建球体 --> <a-sphere position="0 1 -1" radius="1" color="#EF2D5E"></a-sphere> <!-- 定义交创建立方体 --> <a-box width="1" height="1" rotation="0 45 0" depth="1" color="#4CC3D9" position="-1 0.5 1"></a-box> <!-- 定义并创建圆柱体 --> <a-cylinder position="1 0.75 1" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder> <!-- 定义并创建底板 --> <a-plane rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane> <!-- 定义并创建基于颜色的天空盒背景--> <a-sky color="#ECECEC"></a-sky> <!-- 设置并指定摄像机的位置 --> <a-entity position="0 0 4"> <a-camera></a-camera> </a-entity></a-scene>
使用Three.js開發VR內容
上文中我們提到另外了一種更靠近底層同時更靈活生產WebVR內容的方法,就是直接使用WebGL+WebVR的API。這種方法相對於A-Frame的優點在於可以將VR的支援方便地引入到我們自己的Web3D引擎中,同時對於底層,特別是渲染模組可以做更多優化操作從而提升VR運行時的性能與體驗。
如果沒有自己的Web3D引擎也沒有關係,可以直接使用成熟的渲染框架,例如Three.js和Babylon.js等,這些都是比較流行且較為出色的Web3D端渲染引擎(框架)。接下來就以Three.js為例,說明如何在其上製作WebVR內容。
首先,對於任何渲染程式的三個要素是相似的,也就是建立好scene、renderer、camera。設定渲染器、場景以及攝影機的操作如下:
var renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // 创建Three.js的场景 var scene = new THREE.Scene(); // 创建Three.js的摄像机 var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000); // 调用WebVR API中的摄像机控制器对象,并将其与主摄像机进行绑定 var controls = new THREE.VRControls(camera); // 设置为站立姿态controls.standing = true; // 调用WebVR API中的渲染控制器对象,并将其与渲染器进行绑定 var effect = new THREE.VREffect(renderer); effect.setSize(window.innerWidth, window.innerHeight);// 创建一个全局的VR管理器对象,并进行初始化的参数设置 var params = { hideButton: false, // Default: false. isUndistorted: false // Default: false. }; var manager = new WebVRManager(renderer, effect, params);
上述程式碼即完成了渲染前的初始化設定。接下來需要在場景中加具體的模型對象,主要操作如下:
function onTextureLoaded(texture) { texture.wrapS = THREE.RepeatWrapping; texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(boxSize, boxSize); var geometry = new THREE.BoxGeometry(boxSize, boxSize, boxSize); var material = new THREE.MeshBasicMaterial({ map: texture, color: 0x01BE00, side: THREE.BackSide }); // Align the skybox to the floor (which is at y=0). skybox = new THREE.Mesh(geometry, material); skybox.position.y = boxSize/2; scene.add(skybox); // For high end VR devices like Vive and Oculus, take into account the stage // parameters provided. setupStage(); } // Create 3D objects. var geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); var material = new THREE.MeshNormalMaterial(); var targetMesh = new THREE.Mesh(geometry, material); var light = new THREE.DirectionalLight( 0xffffff, 1.5 ); light.position.set( 10, 10, 10 ).normalize(); scene.add( light ); var ambientLight = new THREE.AmbientLight(0xffffff); scene.add(ambientLight); var loader = new THREE.ObjectLoader(); loader.load('./assets/scene.json', function (obj){ mesh = obj; // Add cube mesh to your three.js scene scene.add(mesh); mesh.traverse(function (node) { if (node instanceof THREE.Mesh) { node.geometry.computeVertexNormals(); } }); // Scale the object mesh.scale.x = 0.2; mesh.scale.y = 0.2; mesh.scale.z = 0.2; targetMesh = mesh; // Position target mesh to be right in front of you. targetMesh.position.set(0, controls.userHeight * 0.8, -1); });
最後的操作便是在requestAnimationFrame設定更新。在animate的函數中,我們要不斷地取得HMD回傳的資訊以及對camera進行更新。
// Request animation frame loop functionvar lastRender = 0;function animate(timestamp) { var delta = Math.min(timestamp - lastRender, 500); lastRender = timestamp; // Update VR headset position and apply to camera. //更新获取HMD的信息 controls.update(); // Render the scene through the manager. //进行camera更新和场景绘制 manager.render(scene, camera, timestamp); requestAnimationFrame(animate); }
經驗與心得
透過上述介紹我們基本上可以實現一個具有初步互動體驗的Web端VR應用,但這只是第一步,單純技術上的實現距離真正的可工程化還有一定差距。因為最終工程化之後面向使用者的產品必須比技術原型要考慮更多具體的東西,例如渲染的品質、互動的流暢度、虛擬化的沉浸度等,這些都最終決定使用者是否會持續使用產品、接受產品所提供的服務等,所以將上述技術在工程化應用之前還有很多的最佳化與改進工作要做。以下是個人在做Web端VR應用過程中體會的一些心得經驗,分享出來供讀者參考。
引擎的選用。如果是使用現有的WebGL引擎,則可參考[5]中的文件來進行VR SDK整合。這裡邊需要做到引擎層與VR SDK層相容,以及VR模式與引擎的工具部分的整合,也可以參考桌面引擎如Unity3D和Unreal在VR SDK整合上的開發模式。如果選用第三方的WebGL引擎則有Three.js或Babylon.js等可選,這些主流的WebGL引擎都已經(部分功能)整合了VR SDK。
調試的設備。調試Web端的VR應用同樣需要有具體的VR設備的支援。對於桌上型WebM內容還是要盡量使用HTC Vive或Oculus等強力沉浸感VR設備。對於行動Web應用,由於Android平台上的各瀏覽器的差異較大,表現也會不太一致,所以建議使用iOS設備進行開發與調試,但是在最終發布前仍要對更多的Andnoid設備進行適配性測試與優化。
性能的最佳化。在Web端做三維的繪製與渲染,效能還是主要瓶頸,因而要盡可能的提升即時渲染的效能,這樣才能有更多資源留給VR部分。目前的WebVR在渲染即時中並沒有像桌面VR SDK一樣可以呼叫眾多的GPU底層介面做諸如Stereo rendering等深層的最佳化,因而對效能的佔用還是較多。
已知的問題。目前,WebVR仍然不太穩定,還會有許多的Bug,例如某些情況下會有設備追蹤遺失的情況,而且效率也不是太高。大多數WebVR應用可以作為後期產品的儲備和預研,但要推出真正可供用戶使用並流暢體驗的產品,還是有較長的路要走。
我們不妨來一起來看看一個VR DEMO的開發歷程究竟是怎麼樣的。
下面把大家可能會關心的開發環節簡單介紹一下:
1、關於開發一個具有一定體量的VR DEMO需要的時間
60天前在我們的會議室的桌子上擺了一本叫《UNITY從入門到精通的書》,我們也搞不清楚這個開發時間是不是好事,是否容易被人認為是另一種「中國速度」搞出來的玩意。
後來我們換成了UE引擎,當然UE有可能會挺高興的,你看我們的引擎多高效,效果多好,藍圖多麼便捷,商城資源多麼的好用……
另外需要指出的是其實這60天的時間不是零基礎開始的,我們這個團隊歲數偏大,基本上都30+了,都有十年的基礎三維美術經驗積累,並且長期扮演乙方角色,導致在技術落地和時間觀念上比較好。加上這個是自己在創作東西,大家投入的狀態比較徹底。所以我說這是一段奇特而幸福的時光,當然付出的代價也是很大的,這段期間我們沒有接任何新的業務單子。
2、關於開發VR用什麼引擎
其實什麼真的不重要,之前也看到知乎上面大神們的各種機靈文章探討VR開發是用UE還是UNITY,意見幾乎是一邊倒的傾向於UNITY,類似用UE就會掉坑裡……但我們研究了一陣覺得我們還是適合用UE,然後現在也還相對幸福地活著,《小馬過河》的故事都讀過嗎?
我回憶了一下我們之前用的工具:MAX和MAYA。這兩個都好,看你做什麼用,如果是做建築動畫,就用MAX,因為快;做角色為主的動畫電影,就用MAYA,動作模組好用,利於團隊協同。
另外其實現在UE已經特別用心在做,看他的官方教程,商城一看就是下了很大的功夫,而且藍圖這個工具也特別合適偏視覺的團隊去使用。
但看UE官方的公眾號每次的閱讀量都少得感人,與國內這麼火熱的VR題材形成有趣的反差,真不知道都在關注什麼號。
還有個比較大的問題就是UE會的人比較少,我們只能花時間自己去摸索,現成的人不好找,這種方式叫死磕。
3、CG團隊開發VR的優勢和劣勢
我覺得我們的優勢還是在視覺設計上,比如我們認為不同的場景,作為互動工具的Vive手柄也應該有不同的主題,於是就出現了各種漂亮的手柄,我覺得都可以上官方商城了。
現在國內做VR內容開發的出身我覺得可以分成幾種:
第一種是技術門檻相對較低的全景視頻 ,這個大部分出身是之前搞實拍的,之前的名聲一般是導演。
第二種是遊戲公司,優勢是在程序以及工作流程上和VR比較類似,容易在技術上轉型,但尷尬的是如果想追求視覺效果的話最好是做次世代遊戲的,但國內現在基本上都是行動端的網路遊路數,做次世代又以外包加工為主業。
第三種是之前CG產業的,就是我們這種,優勢是對視覺比較有追求,國外有一些現在做得還挺好的團隊之前也都是這個路子,但需要在技術上做一定的升級和轉型,但好在底層的原理是類似的,一說都能明白。
第四種是程式猿團隊,優勢是能開發出來比較牛X的程式碼,寫自己想要的shader,弄出來自己想要的功能,需要使勁的地方是怎麼把東西弄好看了。
最後還有一種是說自己是做VR的。
4、UE引擎的藍圖
藍圖是UE專門為了提高工作效率開發的一個可視化模組編程,這個東西對我們的幫助很大,沒有它我們的DEMO出不來。
舉一個栗子:
DEMO後半程出現的你的雙臂變成了翅膀,你揮動翅膀飛向蒼穹,來到一片水天一色的鹽湖,翅膀化為漫天飄散的羽毛…好浪漫的場景。
實現這個東西就需要藉助藍圖的幫助,當然我們這個標註非常接地氣,能看懂的一定能看懂。
總之,這是全藍圖的DEMO,沒有寫一行程式碼,聽起來不夠高大?其實UE開發藍圖是為什麼呢,不就是讓你把精力放到對最終效果幫助更大的事上嗎,適合你團隊的流程就是對的流程。
5、另一個技術點:PBR流程
PBR流程說起來還是遊戲產業借鑒了CG產業引入的,但慚愧的是我們在CG產業後期因為專案類型的原因連UV都很少去展。
PBR材質系統可以讓物體在引擎中表現出更真實的質感與豐富的細節,這也是這一代遊戲引擎的通用材質系統,美術師在工作時以更符合現實世界光照原理的邏輯繪製貼圖,調節材質。基於此系統的Substance Tools系列工具軟體將貼圖、材質、shader等系統由原本的多軟體工具協作整合成一個完整的系統,同時靈活的工作流程極大地節省了製作時間,方便系列化貼圖材質的迭代與更新,讓材質貼圖工作環節更直觀,有效率。
使用軟體Substance painter,這個流程比我們早年PS和MAX展平貼圖之間來回倒騰好了很多。
技術很重要,但面對一個新的視聽體驗方式,創作Very重要,更是VR體驗設計的困難。
7、關於VR體驗的選題
我們選的這個其實是個比較冷門的題材,現在能看到的大部分VR是打槍題材,我覺得我們好像對文化題材更感興趣,再加上我們有幾位同事都是航空迷,就選了這個題材。
我們注意到在STEAM上有個國外團隊做的阿波羅登月的體驗,就下載下來學習了一下,但我們認為他給我們的是一些錯誤的經驗,這個團隊我認為是一群悶瓜工程師,太悶了,受不了。文化輸出是個我們比較擅長的東西,這可能和之前的工作經驗有點關係,而且應該用新的技術做點有意義的東西吧,打怪必須要有,但要是都打怪就不對了。
我自己的總結是,題材最好是你自己喜歡的,有深入研究的,然後又是適合VR表達的就是好的題材。
8、VR的敘事語言會和之前有什麼不同
從創作角度來說,之前導演手裡攥著攝影機,讓你看哪就看哪,還有蒙太奇什麼的逗你琢磨;但在VR在的世界裡,你就是臨場參與者,導演需要引導你去看他希望你看的、參與的。
從2008年開始我們參與策劃執行了好些現場活動,我覺得這個經驗其實和VR是有相通之處的,在一個很大的空間中,在哪鬧動靜,哪給光,如何引導視線,推動情節發展,都是講究、好玩的事。
所以我覺得VR的視覺語言不是影片路子,而是個現場活動或表演的路數。
從技術流程上來說,原來的合成和剪輯崗位退休了,但是呢,又沒有全退,還在但只是換了個平台,UE裡居然加了非線編輯,也可以有後期濾鏡什麼的,真是有趣。
9、關於流程和分工
前後大致有20個左右的人參與,大部分的人員會集中在三維美術素材這個崗位,和遊戲開發的人員分佈類似。有一位導演,我們正直的樸岸老師來統籌整個事,在藝術上做把握,然後我和其他同事會一起配合從技術流程上往前推。
從根上說,可能開始這個選題有點大了,好處是對整個試聽語言的探討會更充分和深入,壞處就是導致要做的資源特別多,雖然我們在過去的十年中是個特別擅長做大體量,販賣偉大的團隊。但在有限的時間內會導致有些資源精度做得還是不夠到位,如果時間再多一點就會更好。 預計有可能爬不出來的坑居然很幸運的沒遇到,總是逢兇化吉,比如開始覺得這麼多物件最後肯定會卡成翔,但透過合理的加載和隱藏居然在幀率上還好,就是其實引擎的承載力比我們想像的還要好。