2016-11-30 71 views
0

據我所知的屏幕空間,在OpenGL多邊形通常被限幅在裁剪空間和僅那些三角形(或三角形的部分,如果限幅處理拆分它們)存活與+的比較 - 瓦特然後這需要實施諸如Sutherland-Hodgman的多邊形裁剪算法。裁剪三角形每像素

我實現我自己的CPU光柵化現在想避免這樣做。我有可用頂點的NDC座標(不是真的歸一化了,因爲我沒有剪取任何東西,所以位置可能不在範圍[-1,1]中)。我想爲所有像素插值這些值,並且只繪製NDC座標在x,y和z維度中落入[-1,1]範圍內的像素。然後我會另外進行深度測試。

會這樣嗎?如果是,插值看起來像什麼?我可以如here所述使用OpenGl spec(p。429 14.9)屬性插值公式嗎?或者,我應該使用公式14.10,它用於所有3個座標的深度(z)插值(我不明白爲什麼在那裏使用不同的座標)?

更新: 我試圖通過兩種方法插每個像素的NDC值:

w0, w1, w2是頂點的重心權重。

1)float x_ndc = w0 * v0_NDC.x + w1 * v1_NDC.x + w2 * v2_NDC.x; float y_ndc = w0 * v0_NDC.y + w1 * v1_NDC.y + w2 * v2_NDC.y; float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;

2) float x_ndc = (w0*v0_NDC.x/v0_NDC.w + w1*v1_NDC.x/v1_NDC.w + w2*v2_NDC.x/v2_NDC.w)/ (w0/v0_NDC.w + w1/v1_NDC.w + w2/v2_NDC.w); float y_ndc = (w0*v0_NDC.y/v0_NDC.w + w1*v1_NDC.y/v1_NDC.w + w2*v2_NDC.y/v2_NDC.w)/ (w0/v0_NDC.w + w1/w1_NDC.w + w2/v2_NDC.w); float z_ndc = w0 * v0_NDC.z + w1 * v1_NDC.z + w2 * v2_NDC.z;

的修剪+深度測試總是看起來像這樣:

if (-1.0f < z_ndc && z_ndc < 1.0f && z_ndc < currentDepth && 1.0f < y_ndc && y_ndc < 1.0f && -1.0f < x_ndc && x_ndc < 1.0f)

情況1)對應於利用方程14.10爲其內插。情況2)對應於使用等式14.9進行插值。

結果documented in gifs on imgur. 1)奇怪的事情發生在第二個立方體在相機後面或者當我進入立方體時。 2)奇怪的工件不可見,但隨着相機接近頂點,它們開始消失。並且由於這是perspective correct interpolation of attributes頂點(靠近攝像機?)具有更大的權重,所以一旦頂點被剪切,該信息就會以強大的權重插入到三角形像素中。

是這一切的預期或有我做錯了什麼?

+1

我不知道你在這裏執行什麼。正如Nicol Bolas已經指出的那樣,如果任何基元與'z_eye = 0'平面相交,剪切就非常重要。並且對這些基元的插值將變得完全沒有意義(對於某些頂點,在'z_eye = 0'時,甚至最終會以零除除)。在NDC中檢查'-1 <= x,y,z <= 1'不等於剪輯空間中的-w <= x,y,z <= w',因爲符合'w <= x, y,z,<= -w'(在相機後面)也可以實現。我不知道'NDC.w'是什麼意思,因爲在NDC中,沒有w(或者它是1)。 – derhass

+1

總結:在我看來,剪切屏幕空間並沒有絲毫的意義(你可以在同質座標系下進行光柵化)(http://www.cs.unc.edu/~olano/papers/2dh-tri /)),它會慢很多。所以我不知道你在這裏獲得了什麼。 – derhass

+0

感謝澄清derhass。我沒有正確理解尼科爾的回答(我認爲他的意思是即使在裁剪z_eye = 0的情況下,數學也可以工作)。在我的代碼中,我使用NDC.w作爲頂點的相機空間z。無可否認,這在透視分裂後沒有意義。 – pseudomarvin

回答

2

除非三角形在攝像機空間Z中達到或超過0,否則不要緊靠近平面進行剪切。一旦出現這種情況,齊次座標數學就會變得很奇怪。

如果在剪輯空間外延伸的屏幕寬度超過屏幕寬度,或者如果它們穿過零相機Z,大多數硬件只會困擾剪裁三角形。這種剪輯稱爲「保護帶剪輯」,因爲剪輯不便宜,所以可以節省大量性能。

所以,數學可以正常工作。在設置掃描線時,你需要做的主要事情是弄清楚它們每個在屏幕上的開始/結束位置。插值數學是相同的任何方式。

+0

我使用邊緣函數來測試一個像素是否在三角形內,所以在我的情況下,「設置掃描線」可能等同於在屏幕空間中夾緊到範圍[0,寬度 - 1],[0,height - 1],對嗎? – pseudomarvin

2

我看不出有任何理由,這是行不通的。但它會比傳統裁剪慢。請注意,您可能會遇到靠近投影中心的三角形,因爲它們會很小,並且可能會在重心座標計算中導致問題。方程14.9和14.10之間的區別在於,該深度基本上是z/w(並重新映射爲[0,1])。由於角度差已經發生,所以在插值期間必須將其留下。