計算機圖形學 - 可見表面檢測
當我們檢視包含非透明物體和表面的圖片時,我們無法看到那些位於更靠近眼睛的物體後面的物體。為了獲得逼真的螢幕影像,我們必須移除這些隱藏的表面。這些表面的識別和移除稱為隱藏面問題。
有兩種方法可以解決隱藏面問題:物體空間方法和影像空間方法。物體空間方法在物理座標系中實現,而影像空間方法在螢幕座標系中實現。
當我們想要在二維螢幕上顯示一個三維物體時,我們需要識別從選擇的觀察位置可見的螢幕部分。
深度快取(Z 快取)方法
該方法由卡特莫爾開發。它是一種影像空間方法。其基本思想是測試每個表面的 Z 深度以確定最近(可見)的表面。
在這種方法中,每個表面都單獨處理,一次處理一個畫素位置,跨越整個表面。比較畫素的深度值,最近(最小的 z)表面決定在幀快取中顯示的顏色。
它在多邊形表面上應用非常有效。表面可以以任何順序處理。為了覆蓋遠離觀察者的多邊形,使用兩個緩衝區,名為幀快取和深度快取。
深度快取用於儲存 (x, y) 位置的深度值,因為表面正在處理 (0 ≤ 深度 ≤ 1)。
幀快取用於儲存每個位置 (x, y) 的顏色值的強度值。
z 座標通常歸一化到 [0, 1] 範圍。z 座標的 0 值表示後裁剪平面,z 座標的 1 值表示前裁剪平面。
演算法
步驟 1 - 設定緩衝區值 -
Depthbuffer (x, y) = 0
Framebuffer (x, y) = 背景顏色
步驟 2 - 處理每個多邊形(一次一個)
對於多邊形的每個投影 (x, y) 畫素位置,計算深度 z。
如果 Z > depthbuffer (x, y)
計算表面顏色,
設定 depthbuffer (x, y) = z,
framebuffer (x, y) = surfacecolor (x, y)
優點
- 易於實現。
- 如果在硬體中實現,則可以減少速度問題。
- 它一次處理一個物件。
缺點
- 需要大量的記憶體。
- 這是一個耗時的過程。
掃描線方法
這是一種識別可見表面的影像空間方法。此方法僅對單個掃描線具有深度資訊。為了需要一行深度值,我們必須在處理下一條掃描線之前,同時對與給定掃描線相交的所有多邊形進行分組和處理。為此,維護兩個重要的表:邊表和多邊形表。
邊表 - 它包含場景中每條線的座標端點、每條線的反斜率以及指向多邊形表的指標,以將邊連線到表面。
多邊形表 - 它包含平面係數、表面材料屬性、其他表面資料,並且可能是指向邊表的指標。
為了便於搜尋與給定掃描線相交的表面,形成了一個活動的邊列表。活動列表僅儲存與掃描線相交的邊,並按 x 遞增的順序排列。此外,為每個表面設定一個標誌,以指示掃描線上某個位置是在表面內部還是外部。
從左到右處理每條掃描線上的畫素位置。在與表面的左側交點處,表面標誌開啟;在右側交點處,標誌關閉。您只需要在多條表面在某個掃描線位置的標誌都開啟時執行深度計算。
區域細分方法
區域細分方法透過定位表示單個表面一部分的檢視區域來利用優勢。將總檢視區域細分為越來越小的矩形,直到每個小區域都是單個可見表面的一部分的投影或根本沒有表面為止。
繼續此過程,直到細分很容易被分析為屬於單個表面,或者直到它們被縮減到單個畫素的大小。一種簡單的方法是在每個步驟中將區域依次分成四個相等的部分。表面與指定區域邊界可能存在四種可能的關係。
包圍表面 - 完全包圍該區域的表面。
重疊表面 - 部分在區域內部,部分在區域外部的表面。
內部表面 - 完全在區域內部的表面。
外部表面 - 完全在區域外部的表面。
確定區域內表面可見性的測試可以用這四種分類來表示。如果以下條件之一為真,則無需進一步細分指定區域 -
- 所有表面相對於該區域都是外部表面。
- 該區域中只有一個內部、重疊或包圍表面。
- 包圍表面遮擋了區域邊界內的所有其他表面。
背面檢測
一種快速簡單的物體空間方法,用於識別多面體的背面,是基於“內部-外部”測試。如果點 (x, y, z) 在具有平面引數 A、B、C 和 D 的多邊形表面“內部”,則當內部點沿著視線到表面時,多邊形必須是背面(我們位於該面的內部,無法從我們的觀察位置看到它的正面)。
我們可以透過考慮多邊形表面的法向量N來簡化此測試,該法向量具有笛卡爾分量 (A, B, C)。
一般來說,如果 V 是從眼睛(或“相機”)位置到觀察方向的向量,則如果該多邊形是背面
V.N > 0
此外,如果物件描述轉換為投影座標,並且您的觀察方向平行於觀察 z 軸,則 -
V = (0, 0, Vz) 以及 V.N = VZC
因此,我們只需要考慮法向量N的分量 C 的符號。
在觀察方向沿負 $Z_{V}$ 軸的右手觀察系統中,如果 C < 0,則多邊形是背面。此外,我們無法看到法向量 z 分量 C = 0 的任何面,因為您的觀察方向朝向該多邊形。因此,一般來說,如果其法向量的 z 分量值為 -,我們可以將任何多邊形標記為背面
C <= 0
類似的方法可用於採用左手觀察系統的包中。在這些包中,平面引數 A、B、C 和 D 可以根據以順時針方向指定的多邊形頂點座標計算(與右手系統中使用的逆時針方向不同)。
此外,背面具有指向遠離觀察位置的法向量,當觀察方向沿正 $Z_{v}$ 軸時,由 C >= 0 識別。透過檢查定義物件的不同平面的引數 C,我們可以立即識別所有背面。
A 快取方法
A 快取方法是深度快取方法的擴充套件。A 快取方法是 Lucasfilm Studios 為渲染系統 Renders Everything You Ever Saw (REYES) 開發的一種可見性檢測方法。
A 快取擴充套件了深度快取方法以允許透明度。A 快取中的關鍵資料結構是累積快取。
A 快取中的每個位置有兩個欄位 -
深度欄位 - 它儲存一個正數或負數實數
強度欄位 - 它儲存表面強度資訊或指標值
如果深度 >= 0,則儲存在該位置的數字是與相應畫素區域重疊的單個表面的深度。然後,強度欄位儲存該點表面顏色的 RGB 分量以及畫素覆蓋率的百分比。
如果深度 < 0,則表示多個表面對畫素強度的貢獻。然後,強度欄位儲存指向表面資料鏈接列表的指標。A 快取中的表面緩衝區包括 -
- RGB 強度分量
- 不透明度引數
- 深度
- 區域覆蓋率百分比
- 表面識別符號
該演算法的執行方式與深度快取演算法相同。深度和不透明度值用於確定畫素的最終顏色。
深度排序方法
深度排序方法同時使用影像空間和物體空間操作。深度排序方法執行兩個基本功能 -
首先,按深度遞減的順序對錶面進行排序。
其次,按順序掃描轉換表面,從深度最大的表面開始。
多邊形表面的掃描轉換在影像空間中執行。這種解決隱藏面問題的方法通常稱為畫家演算法。下圖顯示了深度排序的效果 -
該演算法首先按深度進行排序。例如,多邊形的初始“深度”估計可以取為多邊形任何頂點的最近 z 值。
讓我們取列表末尾的多邊形 P。考慮所有其 z 範圍與 P 重疊的多邊形 Q。在繪製 P 之前,我們進行以下測試。如果任何以下測試為正,則我們可以假設可以在 Q 之前繪製 P。
- x 範圍是否不重疊?
- y 範圍是否不重疊?
- P 是否完全位於 Q 平面的另一側,遠離視點?
- Q 是否完全位於 P 平面的同一側,靠近視點?
- 多邊形的投影是否不重疊?
如果所有測試都失敗,則使用另一個平面的平面分割 P 或 Q。將新的切割多邊形插入深度順序中,並繼續該過程。理論上,此分割槽可能會生成 O(n2) 個單獨的多邊形,但在實踐中,多邊形的數量要少得多。
二叉空間劃分 (BSP) 樹
二叉空間分割用於計算可見性。要構建BSP樹,應從多邊形開始並標記所有邊。一次處理一條邊,擴充套件每條邊使其將平面分成兩部分。將第一條邊作為樹的根節點放置。根據後續邊是在內部還是外部新增它們。跨越已在樹中的邊的擴充套件的邊被分成兩部分,並將這兩部分都新增到樹中。
從上圖中,首先取A作為根節點。
列出圖(a)中的所有節點。
將所有位於根節點A前面的節點放在節點A的左側,並將所有位於根節點A後面的節點放在右側,如圖(b)所示。
首先處理所有前面的節點,然後處理後面的節點。
如圖(c)所示,我們將首先處理節點B。由於節點B前面沒有任何節點,因此我們放置了NIL。但是,節點B後面有節點C,因此節點C將位於節點B的右側。
對節點D重複相同的過程。