原文地址:http://blog.csdn.net/mao_xiao_feng/article/details/52454560
沉浸體驗(yàn)是VR的核心也是一直以來的技術(shù)難點(diǎn)宁玫,虛擬現(xiàn)實(shí)的發(fā)展一直專注于怎樣讓用戶獲得更好的沉浸式體驗(yàn),這涉及到多個(gè)領(lǐng)域的多項(xiàng)技術(shù),上至渲染優(yōu)化嘹裂,性能優(yōu)化有鹿,下至人眼的構(gòu)造,肢體的運(yùn)動(dòng)與感知蠢箩。Cardboard也為沉浸式體驗(yàn)提供了一種方案,本篇主要介紹Cardboard是用哪些技術(shù)實(shí)現(xiàn)VR體驗(yàn)的事甜。
之前有人和我說谬泌,用Unity實(shí)現(xiàn)VR效果,很簡單逻谦,新建兩個(gè)Camera掌实,相隔一定長度,然后把兩個(gè)攝像機(jī)的viewport邦马,分屏輸出贱鼻,就實(shí)現(xiàn)了VR宴卖,乍一聽還挺有道理的,但是仔細(xì)一想邻悬,這種實(shí)現(xiàn)方式症昏,漏洞百出,更夸張的說父丰,它可能根本算不上VR
首先我們要明白沉浸式的虛擬現(xiàn)實(shí)系統(tǒng)是怎樣的系統(tǒng)肝谭?
以下摘自百度百科:沉浸式虛擬現(xiàn)實(shí)其明顯的特點(diǎn)是:利用頭盔顯示器把用戶的視覺、聽覺封閉起來蛾扇,產(chǎn)生虛擬視覺攘烛,同時(shí),它利用數(shù)據(jù)手套把用戶的手感通道封閉起來镀首,產(chǎn)生虛擬觸動(dòng)感坟漱。系統(tǒng)采用語音識(shí)別器讓參與者對系統(tǒng)主機(jī)下達(dá)操作命令,與此同時(shí)更哄,頭芋齿、手、眼均有相應(yīng)的頭部跟蹤器成翩、手部跟蹤器沟突、眼睛視向跟蹤器的追蹤,使系統(tǒng)達(dá)到盡可能的實(shí)時(shí)性捕传。臨境系統(tǒng)是真實(shí)環(huán)境替代的理想模型惠拭,它具有最新交互手段的虛擬環(huán)境。那么我們從第一個(gè)特征開始:虛擬視覺虛擬視覺是一個(gè)很抽象的概念庸论,要去理解他职辅,必須要進(jìn)行具體化,而我們手上正好有Unity這樣的工具可以幫助我們實(shí)際去感受聂示,什么是虛擬視覺域携。
這是Cardboard的主物體,我們把它全部展開鱼喉,發(fā)現(xiàn)CardboardMain下面有三個(gè)層級秀鞭,Head是CardboardMain的子物體,GazePointer和Main Camera分別又作為Head的子物體扛禽,而Main Camera下又附帶著兩個(gè)Camera锋边,,可能有人不明白為什么這樣設(shè)置编曼,別擔(dān)心豆巨,等我們介紹完你就明白了。
縱觀整一個(gè)CardboardMain掐场,發(fā)現(xiàn)帶有Camera組件的只有Main Camera和他所屬的兩個(gè)子物體往扔,如上圖所示贩猎,三個(gè)Camera的近裁面大小并不一樣,我們截圖進(jìn)行一下對比
Main Camera Left和Main Camera Right的近裁面分別是相比Main Camera的近裁面等高但是寬度減小的兩個(gè)矩形萍膛,而且兩個(gè)矩形不重疊吭服,它們相差了一定間隔。
這個(gè)間隔看似不起眼蝗罗,實(shí)際就很有講究了噪馏,要闡明其原理,首先要從3D電影的原理講起:
/***********************************************************************************************************************************/
不知道大家有沒有在脫掉3D眼鏡的情況下绿饵,觀察3D電影的屏幕,會(huì)發(fā)現(xiàn)其實(shí)屏幕上的畫面瓶颠,很模糊拟赊,看起來像是兩幅畫面的疊加。但是戴上眼鏡以后瞬間清晰了粹淋,而且更加逼真震撼吸祟。
3D電影的原理其實(shí)很簡單,它確實(shí)是利用兩臺(tái)并列安置的電影攝影機(jī)桃移,同步拍攝出兩條略帶水平視差的電影畫面(要注意的是屋匕,這樣的兩幅畫面,并不是時(shí)間上的先后關(guān)系借杰,而是在拍攝時(shí)过吻,攝影機(jī)攝像位置的空間上的間距),所以蔗衡,一部只用一個(gè)攝像機(jī)拍攝的電影纤虽,無論用什么方法也成為不了3D電影,3D的基礎(chǔ)绞惦,就是兩幅在不同點(diǎn)觀察的畫面逼纸。
為什么要這樣做?
做一個(gè)小實(shí)驗(yàn)吧济蝉,先閉上左眼杰刽,同時(shí)睜開右眼。
然后迅速睜開左眼王滤,同時(shí)閉上右眼
再回到第一步贺嫂,不停的循環(huán)。比對一下雁乡,左眼中的世界涝婉,和右眼中的世界,是一樣的嗎蔗怠?
這就是我們視覺的運(yùn)行方式墩弯,兩眼在不同的空間位置去觀察這個(gè)世界吩跋,接受不同的反射光線,然后被大腦所接受渔工,形成一個(gè)條件反射锌钮,我們在看“現(xiàn)實(shí)”的世界,所有物體都是實(shí)際存在的引矩,都是有空間大小的梁丘。這就是我們感覺的“3D”
問一個(gè)很玄乎的問題。在看一幅畫的時(shí)候旺韭,為什么我們知道是在看一幅畫氛谜,而不是畫中的世界?
也許我們的雙眼在看這幅畫的時(shí)候区端,大腦就已經(jīng)確定了這是一幅畫值漫,里面的物體都是處于“畫”這個(gè)平面上的,我們永遠(yuǎn)不可能進(jìn)入到畫中去看畫中的世界织盼。
然而科學(xué)的進(jìn)步告訴我們杨何,真的可以進(jìn)入畫中的世界,只要在畫中給我們的眼睛建模沥邻,形成“畫中的視覺“危虱。
如何建模呢?
很簡單的一種方式唐全,像3D電影拍攝一樣埃跷,用攝像機(jī)替代我們的雙眼,但是攝像機(jī)獲得的畫面并不能直接投射到我們的視網(wǎng)膜上被大腦感知邮利,我們還需要一樣?xùn)|西捌蚊,3D眼鏡。
3D眼鏡將匹配的偏振光接受近弟,拒絕不匹配的光線缅糟,這樣的設(shè)計(jì)導(dǎo)致了,我們的左右眼可以獲取到對應(yīng)的畫面祷愉,而兩個(gè)畫面互不影響窗宦。
于是,兩幅用攝像機(jī)模擬眼睛拍攝的畫面二鳄,就在我們的左右視網(wǎng)膜上分別投影出來了赴涵。
這就是虛擬視覺。
用一句話概括就是订讼,把自己的雙眼“放”到虛擬世界中去髓窜,“感知”這個(gè)世界的光線,讓你覺得這個(gè)世界像是實(shí)際存在的,于是“虛擬”就變成了“現(xiàn)實(shí)”寄纵。
/***********************************************************************************************************************************/
現(xiàn)在我們來看Cardboard是怎么實(shí)現(xiàn)虛擬視覺的鳖敷,Main Camera Left和Main Camera Right上都有一個(gè)腳本,叫Cardboard Eye.cs
這是關(guān)于此腳本的介紹:
Controls one camera of a stereo pair. Each frame, it mirrors the settings of the parent mono Camera, and then sets up side-by-side stereo with an appropriate projection based on the head-tracking data from the Cardboard.SDK object.To enable a stereo camera pair, enable the parent mono camera and set Cardboard.SDK.vrModeEnabled = true.
控制一對立體攝像機(jī)中的其中一個(gè)程拭,每一幀都復(fù)制其父物體上的單攝像機(jī)的設(shè)置定踱,然后根據(jù)從Cardboard.SDK對象得到的頭部追蹤數(shù)據(jù)同合適的投影來建立立體像對。
要啟用立體攝像機(jī)對恃鞋,先啟用父物體的單攝像機(jī)并置Cardboard.SDK.vrModeEnabled = true
顯然Cardboard是用這對攝像機(jī)來產(chǎn)生立體圖像的崖媚,這個(gè)攝像機(jī)Cardboard給了個(gè)定義叫stereo camera,介紹里還涉及到一個(gè)攝像機(jī)恤浪,叫mono Camera畅哑,這個(gè)mono Camera就是Main Camera物體上camera組件
為什么要叫mono Camera或者說這個(gè)mono Camera有什么用呢?上面介紹過了mono Camera的近裁面是一個(gè)大的矩形,而兩個(gè)stereo Camera的近裁面只是包含于mono Camera的近裁面中的矩形水由,這說明stereo Camera獲得的投影來自于mono Camera投影的一部分荠呐。Cardboard把mono Camera的投影作為世界的投影,而stereo Camera的投影作為輸入眼部的投影绷杜,為了與現(xiàn)實(shí)保持一致,stereo Camera使用函數(shù)public void CopyCameraAndMakeSideBySide(StereoController controller, float parx = 0, float pary = 0)保證相機(jī)的所有settings是與mono Camera保持一致的濒募。這樣做的目的鞭盟,就是希望我們看到的,是和世界一致的瑰剃,這是想當(dāng)然的問題齿诉,我們肯定不會(huì)希望我們眼睛看到的與世界表現(xiàn)的不相同,即使在虛擬世界中晌姚。
細(xì)心的同學(xué)會(huì)發(fā)現(xiàn)一個(gè)問題粤剧,在工程運(yùn)行的時(shí)候,Main Camera Left和Main Camera Right上的camera組件是關(guān)閉的挥唠,但是我們依然能看到圖像抵恋,這是怎么回事呢?
Alternate means of rendering stereo, when you don't plan to switch in and out of VR mode:In the editor, disable the MainCamera's camera component. Enable the two stereo eye camera components.
Cardboard給了兩種渲染stereo的方式宝磨,一種是啟用mono Camera弧关,關(guān)閉兩個(gè)stereo Camera(默認(rèn)方式),還有一種是關(guān)閉mono Camera唤锉,啟用兩個(gè)stereo Camera世囊。
這是在UnityEditor里的功能,所以Android運(yùn)行時(shí)應(yīng)該用不到
當(dāng)然實(shí)現(xiàn)視覺的虛擬不僅僅是以上這么簡單窿祥,我們獲得了兩個(gè)不同視點(diǎn)觀察的經(jīng)過投影變換后的圖像(準(zhǔn)確的來講株憾,這個(gè)圖像應(yīng)該叫做RenderTexture),現(xiàn)在我們需要將攝像機(jī)輸出的視口(viewport)擺放到屏幕的準(zhǔn)確位置晒衩,這一步很重要嗤瞎,因?yàn)槲覀儾幌M谟肰R眼鏡觀察的時(shí)候因?yàn)檩敵龅膙iewport位置不對墙歪,導(dǎo)致看不全viewport或者看到了viewport外圍黑色背景的現(xiàn)象,我們希望猫胁,我們的視野(視野這個(gè)詞箱亿,后面都簡寫為FOV,field of view弃秆,這個(gè)視野可能是眼睛的視野届惋,也有可能是眼睛透過VR透鏡觀看的視野),正好覆蓋輸出的viewport菠赚,一分一毫也不能偏差脑豹,差一點(diǎn)點(diǎn)可能就會(huì)毀了我們的沉浸式體驗(yàn)過程。
這個(gè)過程衡查,我自己定義了一個(gè)名字瘩欺,叫做外部的FOV適配。(不同于內(nèi)部的FOV適配拌牲,后面會(huì)講)俱饿。
完成了外部的FOV適配,至少我們已經(jīng)將我們的眼睛“放”到了游戲場景中塌忽,但是這僅僅是一個(gè)開始拍埠,我們還需要解決很多問題。
例如土居,VR透鏡的使用造成的最典型的一個(gè)問題枣购,圖像畸變。
下一章我們會(huì)從扭曲矯正開始繼續(xù)介紹擦耀。