2012-05-07 122 views
2

我正在使用XNA 4.0並嘗試將Vector3變成Vector2,它代表其在屏幕上的座標。 我知道你可以使用Viewport.Project,這給了我完美的結果,但我需要爲此做出自己的方法。 我必須將每個頂點轉換爲2D幀,而不是GPU。 使用提供的Project方法比我想要的慢一點。 它也會返回一個「z」值,我甚至不會使用它。我只想以最簡單的方式返回(x,y)。將3D矢量投影到2D屏幕座標

這是我到目前爲止提出的,它給出了幾乎正確的結果。但還沒有應用

private Vector2 ScreenCoords(Vector3 v) 
    { 
     return new Vector2(
      viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41, 
      viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42); 
    } 

viewProj只是(viewMatrix * ProjectionMatrix)

在屏幕中心的一個頂點,似乎隨時回來爲(0,0),但我會略微搞砸結果作爲頂點改變屏幕座標(當我移動相機時) 隨着頂點向左移動,我的投影結果的X減小,並且隨着頂點向下移動,我的預測結果的Y增加。 所以至少我有這個權利,但他們改變的速度是不正確的或一致的。

編輯:這裏是它是如何做,可能做它的最快的方法(注意,這個返回的座標範圍爲[-1,1])

private Vector2 ScreenCoords(Vector3 v) 
    { 
     float 
      w = viewProj.M14 * v.X + viewProj.M24 * v.Y + viewProj.M34 * v.Z + viewProj.M44; 
     return new Vector2(
      (viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41)/w, 
      (viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42)/w);   
    } 

下面是使用視口的比較。項目獲得二維座標 -
的FPS項目 - 81
的FPS ScreenCoords - 143
FPS沒有任何一個 - 152
因此,我建議這樣的事情對於別人誰在做每幀投射的手。

回答

2

你應該認識到透視投影需要齊次座標,則應該由homegeneus因素劃分

部件W

這是數學:

Vector4 position = new Vector4(pos3, 1); 
Vector4.Transform(ref position, ref worldViewProjection, out position); 
position /= position.W; 

您也可以找到更多信息在這裏:http://en.wikipedia.org/wiki/Transformation_matrix#Perspective_projection

+0

這讓我感謝我! 我試圖避免使用變換和項目等東西,並用我自己的數學得到答案,但這讓我在那裏。 在任何人想要的時候發佈新的方法。 – Frobot

+0

很好地知道背後的數學是什麼,但我認爲這種變換在着色器內部更有效率。 – Blau

+0

是的,變換也獲得了Z緩衝區中該像素的值,這是我剪掉的部分,因爲我不需要它。 希望我可以在着色器中實現我的整個算法,然後我甚至不需要在CPU上找到2D屏幕座標,它會快得多 – Frobot