2011-09-29 156 views
5

我正在嘗試創建一個簡單的3D圖形引擎,並找到並使用了我在此處找到的公式:http://en.wikipedia.org/wiki/3D_projection#cite_note-0。 (我計算了Dx,Dy,Dz和Bx,By)用於3D透視投影的剪貼矩陣

我工作,但是當我旋轉攝像頭時,線條開始在整個地方飛行,最終你看到屏幕開始返回的多邊形開始返回在屏幕的另一側(你可以去這裏:http://mobile.sheridanc.on.ca/~claassen/3d.html並使用W,A,S和D鍵旋轉相機以查看我在說什麼)

我讀過這個討論:How to convert a 3D point into 2D perspective projection?他在哪裏他談到了使用剪輯矩陣,但我仍然有點困惑,至於如何使用一個。另外我不確定我是否按照討論中所述使用「齊次座標」。

回答

18

乘以透視投影矩陣(也稱爲剪輯矩陣)後,最終得到同質4矢量[x,y,z,w]。這稱爲npc(歸一化投影座標),也稱爲剪輯座標。爲了讓屏幕上的二維座標您通常使用類似

xscreen = (x/w) * screen_width 
yscreen = (y/w) * screen_width 

爲了在鏡頭前點,這給你想要的東西。但是,相機後面的點將具有對應於有效屏幕座標的值,即使該點位於相機後面。爲了避免這種情況,你需要剪輯。需要修剪任何具有w < 0的頂點。

一個快速的嘗試就是如果任何一個頂點都沒有繪製任何線條0這應該修復出現在場景中的奇怪多邊形。但它也會刪除一些應該可見的行。

要完全解決您需要剪切的問題,需要在攝像機前面有一個頂點,在攝像機後面有一個頂點。剪切意味着將線切割成兩半,然後扔掉攝像機後面的一半。該線被穿過相機並平行於顯示屏的平面「裁剪」。問題是找到與該平面相對應的線上的點(即線與平面相交的點)。這將發生在w == 0的那一行。你可以找到這個點,但是當你試圖找到屏幕座標時,你最終除以0(w == 0)。這是「近裁剪機」的原因。近裁剪平面也與顯示屏平行,但位於相機前面(相機與場景之間)。相機與近剪裁平面之間的距離是投影矩陣的「近」參數:

[ near/width ][  0  ][   0    ][  0  ] 
[  0  ][ near/height ][   0    ][  0  ] 
[  0  ][  0  ][(far+near)/(far-near) ][  1  ] 
[  0  ][  0  ][-(2*near*far)/(far-near)][  0  ] 

夾到你必須要找到對相交的近裁剪平面線的點近平面。這是w ==附近的地方。所以,如果你有一個頂點線V1,V2其中

v1 = [x1, y1, z1, w1] 
v2 = [x2, y2, z2, w2] 

你需要檢查每個頂點是否在近剪輯平面之前或之後。如果w1> =近,V1在前面,如果w1近似爲<。如果v1和v2都在前面,則繪製線條。如果v1和v2都落後,那麼不要畫線。如果V1是在前面v2是落後,那麼你需要找到VC,其中線與近剪裁平面:

n = (w1 - near)/(w1 - w2) 
xc = (n * x1) + ((1-n) * x2) 
yc = (n * y1) + ((1-n) * y2) 
zc = (n * z1) + ((1-n) * z2) 
vc = [xc, yc, zc, wc] 

現在畫V1和VC之間的界線。

+0

對於寫得好的答案,我無法感謝你。這對我來說幫助非常大......也不足以支持投票。 – shbi

+0

這是一個很好的答案,但有幾件事我不清楚。首先,你是否錯過了'wc =(n * w1)+((1-n)* w2)'這一行?此外,您的投影矩陣P在右邊相乘,即v_e * P? 更重要的是,我用過的渲染器不需要我在繪製時指定近平面 - 當近值不知道時,如何執行此剪切? – Qualia

+0

我可能暫時找到答案。顯然,剪切z,你約束w,因爲它們是線性依賴的。我遇到的問題是,如果您正在插入w,則會插入您測試z的剪輯值。事實上,這些方程並不像我想象的那麼難。對於與線平面相交的v_1和v_2給出的頂點v_3,'w_3 = w_1 + r *(w_2-w_1)'和'a_3 = a_1 + r *(a_2-a_3)',其中'a_n = dot平面,v_n)'。但a_3等於剪輯值w_3,所以'a_1 + r *(a_2-a_1)= w_1 + r *(w_2-w_1)'。爲r解決,你就完成了。 (我希望)。 – Qualia

4

這可能是對術語的誤解。剪輯矩陣更適合稱爲投影矩陣。至少在OpenGL中,投影矩陣將視圖座標空間(VCS)至剪切座標空間(CCS)中的4D齊次座標變換爲。從CCS到的歸一化設備協調空間(NDCS)的投影需要透視劃分,即將每個分量除以W分量。在此步驟之前剪切已正確完成。因此,「裁剪矩陣」並不排除在投影之前剪切幾何圖形的需要。我希望我已經理解了你,這聽起來並不居高臨下。

這就是說,我認爲你顯然已經得到了投影矩陣的權利 - 它的工作原理。我懷疑穿過眼睛後面的頂點具有負W,這意味着它們應該被剪裁;但我也懷疑他們的Z值是負的,所以這個分數產生了一個正的Z值。如果你真的想要裁剪幾何圖形,而不是丟棄整個三角形,可以搜索「同質裁剪」。如果你不是真的在4D同質空間工作,你可以先看看'Sutherland-Hodgman'3D裁剪。