2010-01-20 81 views
1

我的視圖中有一個256x256的紋理,我需要移動到z位置,紋理在屏幕上以實際大小複製。OpenGL:計算1:1像素比率的z值

我至今是:

const float zForTrueScale = -((itemSize/2)/tanf(DEGREES_TO_RADIANS(fieldOfView/2))) * 2;  

其中itemSize是我在世界空間(2.0單位)紋理的大小。這是計算itemSize/2(相反)爲1.0時Z(相鄰)的值。我認爲這會起作用。

無論我使用何種FOV,該公式顯示的紋理一直過小約10%。

感謝

編輯:我走動的圖像在三維空間中,需要正確的z距離的無縫過渡。我不能使用正交投影,它必須處於視錐體中。

回答

6

由於您需要的信息直接保存在投影矩陣中,因此您可以比視角更容易地做到這一點。

因此給你的投影矩陣看起來就像這樣:

xScale  0    0      0 
0  yScale   0      0 
0   0  -(zf + zn)/(zf - zn) -(2 * zf)/(zf-zn) 
0   0    -1      0 

其中Z-遠(ZF)和z近(ZN),xScale等和yScale是已知的。

要選擇正確的Z-Depth,我們首先確保w結束爲1.這樣,當我們通過w進行除法時,它不會改變任何東西。

幸運的是,w很容易找到。它只是輸入z的負數。因此,將-1輸入到z將返回1的w。

我們假定您使用的分辨率爲1024x768,並且您想要的正確比例的紋理爲256x256。

我們還會進一步假設您的矩形在左上角位置-1,1和右下角位置1,1處設置。

因此,讓我們插入這些東西並計算出z。

如果我們使用以下命令:

-1, 1, -1, 1 
1, -1, -1, 1 

我們會得到了一些東西,如下所示。

1/xScale, -1/yScale, someZThatIsn'tImportant, 1 
-1/xScale, 1/yScale, someZThatIsn'tImportant, 1 

視口變換變換的那些值,使得-1,1爲0,0和1,-1是1024,768

因此,我們可以看到,通過執行工作((X + 1)/2)* 1024和((1-y)/ 2)* 768

所以,如果我們假設xScale爲3/4,yScale爲1,我們可以看到通過插入它我們會得到以下:

左上:

x = -3/4 
=> ((-3/4 + 1)/2) * 1024 
=> 128 
y = 1 
=> ((1 - 1)/2) * 768 
=> 0 

對於右下:

​​

因此你可以看到,我們在屏幕中心的768x768像素的圖片。很顯然,獲得256x256我們需要得到的w爲3,所以後w分割我們有這些座標的三分之一的大小((xScale * 1024)/ 256應該等於(yScale * 768)/ 256得到一個正方形。投影

所以,如果我們最後的座標如下:

-1, 1, -3, 1 
and 
1, -1, -3, 1 

,我們會得到下面的輸出(W-分後):

-0.25, 0.333, unimportantZ, 1 
and 
0.25, -0.333, unimportantZ, 1 

運行那些通過屏幕以上等式和我們得到

對於左上:

x = -0.25 
=> ((-0.25 + 1)/2) * 1024 
=> 384 
y = 0.3333 
=> ((1 - 0.3333)/2) * 768 
=> 256 

對於右下:

x = 0.25 
=> ((0.25 + 1)/2) * 1024 
=> 640 
y = -0.333 
=> ((1 + 0.33333)/2) * 768 
=> 512 

640 - 384 = 256 
512 - 256 = 256 

因此我們現在在正確的像素大小的矩形最後...

+0

哇,很好的答案,謝謝 – Sam 2010-01-21 10:19:19

2

不知道你的情況太多了,將正交投影推到投影矩陣堆棧上,繪製紋理然後再次彈出它幾乎肯定更容易。

+0

不,我四處移動圖像3D空間,並需要無縫過渡到正確的z距離。我不能使用正交投影,它必須是3D。 – Sam 2010-01-20 11:43:01

+1

好的。對不起 - 誤解了。在這種情況下:我的觸發器非常生鏽,但最終需要乘法運算嗎? – Pike65 2010-01-20 12:11:47

0

雖然速度會很慢,但您可以使用glDrawPixels()並完成它。

...不,如果它是性能的關鍵,但!

0

你的framebuffer是否正方形?

如果沒有,那麼你有一個水平的視野和一個垂直的視野。你使用的是正確的嗎?另外,你怎麼知道你想要它在世界座標中是2.0單位?如果您的最終目標是將其映射到像素,那麼您需要考慮視口,並從中恢復。

我也同意派克65,我沒有得到* 2來自哪裏。

+0

* 2是因爲trig使用相反的長度(半個項目寬度),然後在最後我將它乘以返回以獲得全長。我可能剛開始時沒有將項目寬度減半,但當時對我來說讀起來更好。 無論如何,我的問題是,「我如何考慮視口並從中恢復視口」。我的framebuffer是方形的。 – Sam 2010-01-20 16:47:09

+0

我發現通過將13.5/FOV添加到最終結果中,可以爲任何FOV提供足夠精確的結果..但我不明白13.5來自哪裏,這只是我目前代碼中的一個可怕的幻數。 – Sam 2010-01-20 16:50:32

+0

對於trig:/ 2有意義得到項目寬度的一半。但是tan()是半項/ z。那裏沒有* 2參與。 什麼是您的視圖/ proj矩陣看起來像在繪製時?你通過什麼樣的方法來繪製紋理? – Bahbar 2010-01-20 17:47:34