深度分析VR頭顯分辨率:渲染、失真與校正
來源:
52vr |
責任編輯:傳說的落葉 |
發布時間: 2019-04-24 08:26 | 瀏覽量:
我曾撰寫過一篇關于當前頭顯顯示器光學屬性的長文(那個時候的“當前”)、一篇關于寬視場頭顯投影與扭曲的文章、以及一篇關于測量頭顯顯示器有效分辨率的文章,但從未涉足過真正的顯示器分辨率。而現在正是時候。
當然,一個簡短的答案取決于頭顯的型號。但如果你恰巧擁有 HTC Vive,不妨看看圖1和圖2中的數據(其他頭顯類似,但實際數字不同)。這些數字顯示了顯示分辨率,單位為像素/度(pixels/°),以及通過我的Vive頭顯右邊透鏡中心的兩條線(分別為水平和垂直)。紅色,綠色和藍色曲線分別代表紅色,綠色和藍色基本色的分辨率,但這一次不是由我本人測量所得,而是通過分析工廠對每個頭顯進行測量后所得的并存儲在固件中的顯示器校準數據。
在這一點上,你可能會認為上述圖表十分奇怪。對于這一點,建議閱讀以下這個冗長的答案。在開始闡釋之前,我要先給你一個數字:在我的Vive的右邊透鏡中心(像素是492602),綠色通道的分辨率為11.42像素/度,包含水平方向和垂直方向。如果你希望引起一個分辨率數字,這是我會選擇的數字,因為當你看向正前方或遠處時,這就是你得到的數字。然而,圖1和圖2清楚表明了一個數字無法解釋完整的故事。
下面,我們將開始詳細解釋這個冗長的答案。
為什么上文的分辨率圖表會如此怪異呢?我們都十分清楚不同顯示器的分辨率都不盡相同,我們同樣明白三個基本色的分辨率同樣不同。但圖中的鋸齒是什么意思呢?要理解這一點,我們首先需要仔細研究現代VR頭顯是如何把3D環境渲染成一對2D圖片,然后又是如何將其映射至左邊和右邊顯示器。
使得當今頭顯成為可能的主要創新之一是,廠商排除了復雜的,笨重的和昂貴的光學元件,并在軟件中校正由簡單,輕便和廉價單透鏡帶來的缺陷,亦即幾何失真和色差。這種校正是通過在標準3D渲染管道末端添加額外的處理步驟來完成。現代VR頭顯不是直接把3D環境渲染到顯示器,而是通過標準的(扭曲的)透視投影將3D環境渲染為中間圖像,然后使用能夠抵消由透鏡(感知近眼屏幕的必須品)引起的失真的非線性校正函數,以此來把中間圖像翹曲至實際顯示器上。
第1步:對中間直線式圖像進行渲染
詳細來說,第一個渲染步驟如下。每個VR頭顯已經在固件中存儲了渲染適當3D環境視圖所需的各眼投影參數(水平和垂直視場),以及中間圖像的推薦像素大小(Vive為1512×1680)。對于我的Vive的右眼,視場參數如下:左(left) = -1.24627,右(right) = 1.39228,下(bottom) = -1.46862,上(top) = 1.46388。這些數值位于所謂的“切線空間(tangent space)”之中,以兼容3D圖形庫。轉換為角度,它們就會變成這樣:左(left) = 51.257度,右(right) = 54.312度,下(bottom) = 55.749度,上(top) = 55.662度。它們為什么不是對稱的呢?左右值不同是為了將每只眼睛的視場“偏斜”至外部,從而以立體重疊為代價來提供更多的周邊視覺。由于制造公差的不同,上下值有所不同。所有這些值都是在工廠單獨測量所得。
在這一點上,你可能會試圖簡單地將水平和垂直視場相加,并得到總數105.569度×111.411度(左右:51.257+54.312;上下:55.749+55.662),但這是過于輕率的做法。這個矩形是頭顯實際視場的上限值,但不一定是實際尺寸,因為不是所有中間圖像的像素都呈現在實際顯示器之上,而且并非所有像素都對用戶可見。
我們不妨設想一下不存在透鏡,并且直接顯示中間圖像的情況。以像素/度為單位的分辨率是多少呢?將總像素數除以總視場可能看起來是相當可行,這將產生水平分辨率為14.322像素/度,垂直分辨率為15.079像素/度。但這是錯誤的做法。問題是,由于圖像在概念上為平面,所以整個圖像的分辨率將不會均勻。下面請參考圖3:兩個相同大小的像素,一個直接位于眼睛前方,一個位于側面,涵蓋兩個不同的角度α1和α2。
圖3
一般來說,如果圖像的一個軸是N像素長,并且覆蓋從x0到x1的切線空間視場,則像素n(其中n介于0和N-1之間)覆蓋的角度范圍是α1-α0,其中α0=tan-1(n⋅(x1-x0)/N+x0) 和α1=tan-1((n+1)⋅(x1-x0)/N+x0),得出的分辨率為1/(α1-α0)。記住這一點,用微分進行繪圖將更加容易。
根據前面的段落,將像素索引與角度相關的函數為α(n)=tan-1((n+0.5)⋅(x1-x0)/N+x0),其中0.5與n相加以計算像素中心角。對于α(n)=((x1-x0)/N)/(1+((n+0.5)⋅(x1-x0)/N+x0)2)的總導數,tan-1(x)的導數可以合宜地設為1/(1+x2)。反相這一點并且從弧度轉換為角度,我們可以得出(π/180)/(d/dn α(n))像素/度的像素位置n的分辨率。插入從我的Vive接收到的值,我們可以繪制圖4中的函數結果(因為沒有透鏡,因此沒有色差,三原色的分辨率曲線合并為一):
圖4
我們可以從圖表中得出大量的信息。首先,平面中間圖像不適合VR渲染,因為分辨率在中心和邊緣之間增加了2.5到3倍,這意味著不成比例的大量渲染像素被分配到外圍,而它們在那里不是十分有用。盡管平面上投影為3D圖形所固有,但沒有人規定3D仿射空間(affine space)上的平面必須是平的。在3D投影空間中使用平坦平面會產生很好的渲染技巧,但這不是本文的話題。
不過,圖4中的曲線是否令你想起什么呢?我們設想一下將圖4垂直縮放3.5倍,然后取出剪刀,將其切成31個相同大小的垂直條狀。接下來,我們通過增加從中心往四面的量來向下移位這些條狀。現在將這幅畫面與圖1進行比較。是否看到任何相似之處呢?前方劇透:這正是下一個渲染步驟中會發生的事情。
第2步:透鏡失真和色差的非線性校正
成功校正透鏡失真的秘訣是:在校準步驟中測量失真情況。理想情況下是在工廠中對每個頭顯進行相關處理。確切的校準步可能有所不同,但一個選項是利用校準的相機來捕捉顯示在頭顯顯示器上的已知校準圖像將如何呈現給用戶。
這里的要點是:創建一種可信的虛擬現實幻覺。如果虛擬對象位于虛擬用戶的特定方向,則虛擬對象需要呈現在與真實用戶相同的方向。換句話說:對于頭顯顯示器的每一個像素,我們需要知道像素呈現給頭顯用戶的確切方向。最容易表達這一方向的方法是利用水平和垂直切線空間參數。
現在,如果校準為我們提供了每個顯示像素的切線空間方向映射,我們在渲染過程中又該如何為任意像素指定顏色呢?幸運的是,我們已經擁有了一個用于表示切線空間中的虛擬3D環境的圖像:在步驟1生成的中間圖像。這為透鏡失真校正提供了一個簡單的步驟:對于每個顯示像素,在校準映射中查找切線空間坐標,然后在中間圖像復制具有相同切線空間坐標的像素。由于中間圖像的直線式結構,最后一部分的查找其實相當簡單。
更幸運的是:相同的步驟可以校正色差。我們無需為每個顯示像素儲存一個切線空間坐標,我們只需儲存三個:為紅,綠,藍顏色組件各儲存一個。因為三種顏色在相同透鏡下的衍射程度不同,因此它們對于同一像素的切線空間坐標將有所不同。
這非常好,但剩下的問題是如何表示校準映射。原則上,校準映射是一個1080×1200像素的圖像(對Vive來說),每個像素有六個組件:三種顏色各一個切線空間(x,y)。由于技術原因,表示這樣的映射在渲染性能方面效率不高。更好的方法是(這也是Vive和所有其他OpenVR頭顯所使用的方法),將映射簡化為NxM相同大小(在顯示空間中)矩形的“畸變網格”,每個顏色的切線空間坐標僅存儲在那些矩形的邊角,并在每個矩形的邊角值之間進行插值。這樣做更好,因為它非常緊湊(N和M可以很小),而且性能很好(因為現代顯卡非常擅于繪圖,以及在矩形中插值)。圖5顯示了我的Vive的右屏幕綠色通道失真網格,包括顯示空間和切線空間。對于后一種情況,失真網格都疊加在中間圖像的矩形邊界上。
圖5
圖5告訴了我們一些有趣的事情。最重要的是,這表明Vive的透鏡會導致相當多的枕形失真。靠近透鏡中心的網格被壓縮,而周圍的網格被拉伸。這實現了把更多實際顯示像素分配給重要的中央注視點區域,并且把更少顯示像素分配給周邊視覺的預期效果。換句話說,透鏡遠遠消除了圖4所示的糟糕分辨率分布。證據是中心位置的最終顯示分辨率高于周邊,如圖1和圖2所示。
通過在切線空間中拉伸網格單元可以平衡分辨率。一個小單元會為實際顯示的固定尺寸區域分配少量中間圖像像素,從而增加局部分辨率;而拉伸單元會把更多像素填充至相同的固定尺寸區域,從而降低局部分辨率。這解釋了圖1和圖2中倒置分辨率分布,但尚未出現鋸齒的現象。
結果表明,問題的解釋十分簡單:利用線性插值,顯卡使用來自矩形邊角的值進行插值,這意味著生成的失真映射是分段線性函數。分段線性函數的導數是片段間不連續跳變的分段常數函數。正是那些恒定分段(由每個網格單元內逐漸變化的局部分辨率調制)導致了圖1和圖2中的現象。導數中的不連續性不是問題,因為觀察者無法知覺導數,只能知覺函數,而函數在什么地方都是連續的。
對于圖5,另一個有趣的觀察結果是,切線空間中的畸變網格和中間圖像之間的重疊并不完美。中間圖像的一部分未被覆蓋(沿著左邊界的透鏡形狀區域),而且畸變網格的一部分落在中間圖像之外。第一部分意味著用戶無法看到中間圖像的一部分,以及它的視場;第二部分意味著實際顯示的部分不接收有效的圖像數據,因此這變得無法使用。
Vive的設計師在這里作出了一個有趣的決定:他們將右邊中間圖像的左邊界延伸到右邊顯示器的左邊緣之外(左邊顯示器也同樣如此),從而獲得與另一只眼睛的部分立體重疊。在直接向左看時視場不會延伸,因為那里沒有更多的顯示像素,但在向左或向上或向下看時視場將會延伸。“缺點”是Vive渲染的中間圖像會出現奇怪的“偏食”形狀,在內邊緣缺失了兩大塊。
最后要提的一點是:1512×1680像素的推薦中間圖像大小來自于哪里呢?選擇它的原因是:為了令中間圖像的分辨率在通過畸變網格饋送之后能夠大致與透鏡中心區域中的真實屏幕分辨率相匹配,從而讓重新采樣過程中的混疊最小化(在把一個光柵圖像翹曲到另一個光柵圖像之上時的固有現象)。具體來說,中間圖像在透鏡中心的分辨率略低于實際顯示的分辨率(10.01像素/度 vs 11.42像素/度),但往外來說中間圖像能夠快速超過實際顯示的分辨率,請參見圖6。
-
分享到:
相關文章
網友評論
全部評論:0條
推薦
熱門