2014-01-19 34 views
2

我開始使用DirectX(和SharpDX,因此只能在C#/ hlsl中編程),並且正在嘗試構建自己的相機類。它應該是可旋轉的,允許向前和向後移動以及「橫向」移動(經典的第一人稱運動通常映射到A和D,在我的情況下加上和減小)。爲了更容易修正模型和世界空間在我的情況下是一樣的,透視投影還沒有實現,旋轉相機,我的相機應該看Z軸(進入屏幕)。我的錯誤修復模型是一個簡單的四邊形,它具有1.f寬度和高度,z = 0並且居中在屏幕上。

爲了便於使用,我發現了DirectX的Matrix.LookAtLH(),我正在使用它來構建我的矩陣,以便從世界座標轉換到視圖座標,基於我的相機在世界座標中的位置,向上矢量(現在 - 不旋轉 - 總是正Y軸)和世界座標中的目標點。
我(頂點)着色器使用一個簡單的乘法與此矩陣:
output.position = mul(position, worldToView);
的注視矩陣計算如下:造成這幅畫
Matrix.LookAtLH(vec3(0, 0, -1), vec3(0, 0, 0.5f), vec3(0, 1, 0))

Camera at (0, 0, -1) looking at (0, 0, 0.5f
現在我想將我的相機向右,在這種情況下,通過將1.f添加到它的X座標。 我的預期結果與之前相同,四處移動一點。
我建立一個新的LootAt矩陣,動眼座標和目標座標由同一矢量:
Matrix.LookAtLH(vec3(1, 0, -1), vec3(1, 0, 0.5f), vec3(0, 1, 0))
在由此產生:
Camera at (1, 0, -1) lookint at (1, 0, 0.5fDirectX:查看矩陣的世界 - 我的誤解在哪裏?

這GET更極端的我移動攝像機的多,但中心的屏幕仍然保持四邊形的中心。這是否與我對Matrix.LookAtLH的潛在誤解有關?

回答

5

當您使用D3DX函數時,必須在將矩陣發送給着色器之前對其進行轉置。

here在深入的解釋更:

在線性代數,向量和矩陣使用標準矩陣乘法算法相乘。因此,關於操作順序和所涉矩陣的「形狀」有一些規則。數學家通常治療載體爲包含元件的單個列的矩陣,具有翻譯乘法看起來像這樣:

[ 0, 0, 0, tx] [ x] 
[ 0, 0, 0, ty] *[ y] 
[ 0, 0, 0, tz] [ z] 
[ 0, 0, 0, 1] [ 1] 

首先注意到矩陣乘法產生根據這個簡單的規則一個特定的行/列配置的結果:

AxB * BxC = AxC。

換句話說,大小爲A行和B列的矩陣乘以B行和C列的矩陣將產生A行和C列的矩陣。另外,爲了適當地倍增,B必須相等。在這種情況下,我們有4x4 * 4x1,它產生一個4x1或另一個列向量。如果我們改變乘法的順序,它將是4x1 * 4x4,這將是非法的。

然而,計算機科學家經常把矢量當作一行矩陣處理。這有幾個原因,但通常是因爲單個行表示單個線性內存塊或單維數組,因爲數組通常以array [row] [column]的形式尋址。爲了避免在代碼中使用2維數組,人們簡單地使用「行向量」代替。因此,爲了使用矩陣乘法,以實現期望的結果,我們交換爲了1×4 * 4×4 = 1×4,或向量*矩陣:

[ x, y, z, 1] * [ 0, 0, 0, 0] 
       [ 0, 0, 0, 0]    
      [ 0, 0, 0, 0] 
      [ x, y, z, 1] 

通知如何在x,y,Z,翻譯的元件矩陣不得不移動以保持乘法的正確結果(在這種情況下,它被移位)。

當使用列向量,操作的典型變換順序是P * V * W * V,因爲列向量必須放在最後,以產生正確的結果。請記住,矩陣乘法關聯,不可交換的,所以爲了實現矢量由世界轉化,轉化成視覺空間,轉化成均勻的屏幕空間的適當的結果,我們必須按照這個順序繁殖。這給了我們(使用關聯性)P *(V *(W * V)),從而從內部工作到外部工作,首先進行世界變換,接下來觀察,然後進行投影。如果我們使用行向量,則乘法如下:v * W * V * P使用關聯性,我們認識到它簡單地是相同的操作順序:((v * W)* V)* P或者世界第一,然後查看,然後投影。

乘法這兩種形式都同樣有效,並且DX庫選擇,因爲它匹配的內存佈局模式使用後者,它可以讓你讀你的轉變順序從左到右。

HLSL支持操作的兩個訂單。 「*」運算符按元素縮放執行簡單元素,但不執行矩陣乘法。這是使用「mul()」內部操作執行的。如果將一個4元素向量作爲mul()內部函數的第一個參數傳遞,它假定您希望將其作爲「行向量」處理。因此,您必須提供按正確順序相乘的矩陣,並使用適當的行/列格式提供矩陣。這是使用DX效果參數從DX庫傳遞矩陣時的默認行爲。如果您將4元素向量作爲第二個參數提供給mul()內在函數,它會將其視爲列向量,並且您必須爲列向量提供適當形成和相乘的矩陣。

+0

我有完全相同的問題,因爲OP。我已經嘗試在將視圖矩陣傳遞給頂點着色器之前調換視圖矩陣,但是這隻會使所有內容都消失。像在我的着色器中將矩陣聲明爲row_major一樣。以及扭轉多功能中的論點。這些事情的任何組合或者導致一個空白的屏幕,或OP的確切圖像。有什麼建議麼? – Camander

+0

我想通了出錯的地方。我沒有乘以投影矩陣,所以它超出了視口的最大深度 – Camander