打造H5里的“3D全景漫游”秘籍
近來風生水起的VR虛擬現(xiàn)實技術(shù),抽空想起年初完成的“星球計劃”項目,總結(jié)篇文章與各位分享一下制作基于Html5的3D全景漫游秘籍。
QQ物聯(lián)與深圳市天文臺合作,在手Q“發(fā)現(xiàn)新設(shè)備”-“公共設(shè)備”里,連接QQ物聯(lián)攝像頭為用戶提供2016年天體大事件的直播,大家可以通過手Q實時觀看到世界各地***觀測點的日食,流星等天體現(xiàn)象。承載整個“星球計劃”活動的運營頁面,經(jīng)多方討論,我們決定嘗試3D全景漫游模式的H5運營頁進行推廣,今天就不詳述活動的具體內(nèi)容,先和大家聊一聊這H5里“3D全景漫游”的制作方法。
先貼一個體驗地址(請忽略GIF錄屏的卡頓及字體,iOS開啟陀螺儀體驗***),Page3的宇宙部分-轉(zhuǎn)動手機在模擬的宇宙里搜尋各大行星,就是我們今天要說的基于Html5的3D全景漫游。
要制作全景漫游,首先得有全景圖像。全景圖像的獲取通常是借助魚眼的全景攝像機的拍攝來完成的,或者是單反相機、魚眼鏡頭、云臺和三角架的組合。需要按照一個方向旋轉(zhuǎn)360度拍攝一組照片,照片之間要有部分重合的部分,方便進行后期的拼接和融合。在拍好照片后需要將它們無縫拼接在一起,生成的全景圖像可分為球面全景圖、立方體全景圖以及柱狀全景圖等。(咋們騰訊地圖的街景體驗,就是最常見的全景漫游技術(shù)啦)
沒有全景攝像機,也可以通過一些素材站點拿到適合我們項目的全景圖。例如:某素材站點
當然,星球計劃的背景圖是宇宙星際,相對而言是無序的,所以靠視覺設(shè)計師進行拼接繪制也是可以的。
而什么是全景漫游呢,全景漫游技術(shù)可以讓體驗者在全景圖像構(gòu)建的全景空間里切換視角的瀏覽。它是通過拍攝全景圖像,再采用計算機圖形圖像技術(shù)構(gòu)建出全景空間,讓使用者能用控制瀏覽的方向,或左或右、或上或下觀看物體或場景,仿佛身臨其境一般。與傳統(tǒng)的3D建模相比,全景漫游技術(shù)制作簡單,數(shù)據(jù)量小,系統(tǒng)消耗低,且更有真實感。故近年來,也是VR技術(shù)的一大熱門實現(xiàn)手法,用前面的貼圖例子來個demo。而在移動端的全景漫游,更是可以綁定陀螺儀,讓你更有身臨其境的感覺。
在項目初期,預(yù)研了一些全景漫游制作方案,包括目前最為常用的全景漫游制作工具是Pano2vr & Krpano,以及用Flash,QuickTime,基于Java,js等其他方式制作全景漫游,但據(jù)預(yù)研所了解的個方案優(yōu)劣勢對比圖如下圖,結(jié)合“星球計劃”項目的具體情況,最終優(yōu)先選擇了Threejs的實現(xiàn)方案。
這里順便和大家聊聊目前最為常用的全景漫游制作工具是Pano2vr & Krpano。
(1)Pano2vr操作簡單功能雖少但非常實用,“導(dǎo)入全景圖-設(shè)置交互熱點-微調(diào)-導(dǎo)出”即可直接生產(chǎn)flash,html5,Quicktime等格式。
Pano2vr對于僅用在PC,iOS上的需求非常合適快捷,但對Android機的支持表現(xiàn)不佳。
(2)Krpano,功能強大完善,各平臺兼容性高,拓展性很強,各類VR場景特效都可承載。但自成體系,需要遵循Krpano xml的這套編程語言,沒有g(shù)ui的軟件界面,新手上手及后期維護成本較大,生成的全景漫游專業(yè)但對載入速度,內(nèi)存占用都有影響。但對于想做高階的,個性化,定制化全景漫游項目,Krpano是不二選擇。
但這2個工具都需要購買授權(quán)碼才可商用,非免費。
(3)Three.js源自Github的一個開源項目,https://github.com/mrdoob/three.js,官網(wǎng):http://threejs.org/ 。
看到一個同行的解釋,說理解成Three + js就可以了。Three表示3D的意思,js表示javascript的意思,故three.js就是使用javascript來寫3D程序的意思,格外的直白清晰啊。依靠javascript的語言編寫,自然給這個方案帶來了高拓展,高兼容,低開發(fā)成本,可高性能且免費的幾大優(yōu)勢。
(4)Flash,QuickTime,基于Java,js等其他方式這里就不一一詳述,大致的優(yōu)劣勢對比請參考上面的表格(具體評分僅供參考,軟件版本更新也許會有各方面的升級)。
想要利用Three.js制作一個物體渲染到網(wǎng)頁中去,需要構(gòu)建這3個組建:場景(scene)、相機(camera)和渲染器(renderer):
(1)場景(scene)
即是畫布,是所有物體object的容器。在最開始的時候?qū)鼍皩嵗?,將之后?gòu)建的物體都添加到場景中即可。
(2)相機(camera)
用戶是通過相機Camare來查看在scene下的3d場景,在three.js里包含了正交投影照相機(Orthographic Camera)和透視投影照相機(Perspective Camera)2種,從模擬人眼看物體的方式來選,透視投影照相機更適合。如下圖所示,fov是相機視角的夾角,aspect等于相機畫幅比例,near和far分別是照相機到視景體最近、最遠的距離,均為正值,且far應(yīng)大于near。
(3)渲染器(renderer)
渲染器是用來設(shè)定渲染的結(jié)果會在頁面的什么元素上面呈現(xiàn),以及按什么規(guī)則來渲染。
在Three.js中,場景是容器,把我們星球計劃的星星們放置在構(gòu)建的3D場景中的不同位置;相機對著下場景拍攝,拍攝結(jié)果通過渲染器實時的繪制在我們的瀏覽器上。
(4)構(gòu)建宇宙并置入場景中
定義了這三大元素之后,下一步,就是構(gòu)建我們的星球計劃所需的宇宙了。前文有提到,全景圖像可分為球面全景圖、立方體全景圖以及柱狀全景圖。
雖然球面全景圖具有和人眼最接近的構(gòu)建模式,但需要很多個立面才可以構(gòu)建成一個球體,球面的經(jīng)緯度坐標無法展開成一個平面貼圖,相對于其他方案,性能消耗過高,拼接方法過于繁瑣;而柱形全景圖的垂直視野小,不好做頂部底部的俯仰視角。我們選定了最常見的立方圖全景圖來構(gòu)建我們的3D場景。
立方體全景圖有6個面,我們需要定義每個面貼圖的背景圖片,3D位置,旋轉(zhuǎn)角度(默認的6個面都是朝著我們的,我們需要定義朝坐標軸的各個方向做90度的旋轉(zhuǎn),才可以搭建成一個立方體)。
然后添加到THREE.Object3D 的數(shù)組中,這樣我們就在場景中構(gòu)建好了一個3D的宇宙空間。
這里,考慮到星空背景主要為了氛圍烘托,我們將6個面的貼圖減少成2個,以此縮減了資源文件的大小,如下圖所示。
(5)渲染
這里我們用的是Threejs的 實時渲染:就是需要不停的對畫面進行渲染,即使畫面中什么也沒有改變,也需要重新渲染。其中一個重要的函數(shù)是requestAnimationFrame,這個函數(shù)就是讓瀏覽器去執(zhí)行一次參數(shù)中的函數(shù),這樣通過上面animate中調(diào)用requestAnimationFrame()函數(shù),requestAnimationFrame()函數(shù)又讓animate()再執(zhí)行一次,就形成了我們通常所說的渲染循環(huán) 了。
通過上面這些步驟,我們就構(gòu)建好這個3D的宇宙空間了。
(6)構(gòu)建星球放置在宇宙中
一期的星球計劃中,需要增加8顆星球,為了避免畫面過于擁擠,星球們被分散定位在了6個面上。之前我們定義宇宙六個面的時候給了每個面一個固定的section id,通過簡單的js 我們可以往平面中加入星球的DOM結(jié)構(gòu)。
因此也可以很輕松的利用CSS給這些星球定位及增加個性的動畫效果,這里要特別注意,不要增加陰影等耗內(nèi)存特別大的動畫效果,它們是Crash罪魁禍首。
‘
(7)綁定陀螺儀
***一步,將全景漫游綁定陀螺儀,這里涉及到需要對陀螺儀事件做個保護代碼,判斷機器是否支持陀螺儀。完成以上幾步,既可以實現(xiàn)一個在移動端的全景漫游啦。
(8)其他
在項目完成的初期,對部分安卓機的內(nèi)存消耗還是過大,為此在完成項目之后繼續(xù)嘗試了一些優(yōu)化工作,包括 縮減宇宙的尺寸,合并全景貼圖,禁用陀螺儀,預(yù)加載和懶加載,星球CSS3動畫縮減,資源文件深度壓縮等工作,但還是無法避免在內(nèi)存不足的安卓機下存在Crash的風險,為保證項目的穩(wěn)定上線,退而求其次對安卓機做了兼容版的體驗,預(yù)期在后續(xù)的項目迭代中再優(yōu)化頁面在安卓下的表現(xiàn),實現(xiàn)全平臺的體驗統(tǒng)一。
***,僅以此文總結(jié)在移動端構(gòu)建3D全景漫游的試水總結(jié),該嘗試基本上能夠滿足項目的需求,但在性能優(yōu)化,細節(jié)完善上還繼續(xù)打磨,希望能對有興趣的小伙伴帶來一些幫助^^。