處理VR透鏡畸變的三種方法

2021-07-26 21:55:51 字數 1975 閱讀 3368

該文章英文位址,翻譯中有一些個人新增的輔助資訊,以括號標識,」注:」開頭,以粗體表示,例如(注:以下為個人翻譯,水平有限,歡迎指正).

沉浸感需要大的視場角.這可以通過將乙個大的彎曲的球形顯示器放到你的面前的方式來實現,但是這樣的方案是非常昂貴的.乙個更加實惠的解決方案是通過在乙個小的矩形的顯示屏上增加乙個透鏡,然後通過透鏡來看這個顯示屏,從而獲得更大的視場角:

透鏡靠近你的眼睛能夠極大的增加你的視場角,但是這是有代價的:影象會顯得扭曲畸變.越大的視場角,就會有越大的影象畸變.這篇文章是對三種不同的影象反畸變處理的介紹,這些方法都已經在webvr相關的專案中實現了.

這裡是乙個典型的頭帶顯示器的鏡頭畸變例子.透過鏡頭影象產生了」枕型」畸變:

解決方法是對這些畸變的影象使用」桶型」畸變.當我們通過畸變透鏡上看,這些影象(注:是指經過」桶型」反畸變處理的影象)看起來就是正常的:

透鏡的畸變從數學公式上來看是容易裂解的,方程如此所示(注:從**上看osvr openvr上所使用的反畸變演算法都是採用這個的),,特定的透鏡對應相應的畸變係數.為了更好的消除畸變,我們還需要計算兩隻眼睛中心之間的距離,為此需要知道一些關於顯示器幾何結構以及它們的外殼結構.這些都可以做到,及時是在web上!我總結了以下幾個可選的實現方案.

1.方案基於片段(bad)

最簡單的方法是通過二次渲染.首先,我們渲染左眼和右眼影象到紋理上,然後用片段(畫素)著色器處理這個紋理,將每乙個畫素向內移動到眼睛的中心上.

這是最初的、最簡單的方法,也是效率最低的方法,因為每個畫素都要被分別處理.webvr的第乙個版本是由boilerplate實現的.

2.方案基於網格(better)

第二種方案與之前相比,不是採用單獨處理每乙個畫素的方法,我們隊相對稀疏的網格的頂點做畸變處理(40x20效果不錯).

這種方案可以減少很多直接計算的資源,讓gpu做大量的插值運算.不採用對每乙個畫素(1920*1080約為2e6)做處理,我們隊網格中的每個頂點做計算(40*20 = 800).結果是極大的減少了計算量(減少了3個數量級),在效能上有不錯的提公升.webvr polyfill現在實現了這個方法.

在這個畸變方法中渲染不是唯一的占用大量資源的部分.一些時間被浪費在用來拷貝整個場景的中間紋理.

3.方案基於頂點位移(best)

這個方案是三種方案中最有效的,首先它不需要渲染中間紋理.在這種方法中,幾何結構通過自定義的定點著色器已經產生了畸變.這個方法已知攝像頭的位置,我們用已經」桶型」畸變的2d渲染結果代替頂點.在這種方案中,不需要二次渲染,我們可以節省拷貝渲染到紋理的步驟.

這種方法需要在每個已經畸變的網格上有一定的頂點密度.想象乙個簡單的例子,四個頂點的矩形非常靠近攝像頭的渲染情況,畸變這些頂點滯後,仍然是乙個4個頂點的扁平的矩形,不會有」桶型」的效果.因此,這些方法的使用通常還需要一些額外的開發工作.

這種方法已經被用於開源的vr view專案的cardboard design lab.基於幾何畸變的方法還可能導致影象看起來比較鋒利,因為之前的2種方法會導致混疊,尤其是中間紋理很小的時候.你可以閱讀更多關於畸變的方法.

三種方法 2020 11 23

利用連線類,例項化得到連線物件 連線類 連線物件 new 連線類 cmd.executescalar cmd.excutereader 關注其中一條資料 物件名.read 獲取關注列所對應的值 console.writeline 物件名 name while 物件名.read 功能,聚焦下一行資料。...

類的三種方法

方法 函式 1 例項方法 函式 預設 2 類方法 函式 classmethod 3 靜態方法 函式 staticmethod class person person number 0 類變數 def init self name,gender 構造方法 用來物件初始化 self.name name ...

tomcat deploy專案三種方法

其中path制定訪問url路徑,docbase專案真是路徑 privileged true antiresourcelocking false antijarlocking false type org.apache.catalina.userdatabase 其中,docbase與第二種方式中的含...