2016-04-22 89 views
0

我試圖在三維中顯示三個笛卡兒平面時遇到問題,當它們旋轉平面時,會在一個方向上拉伸(z軸,藍色)並在另一個方向上(x軸紅色)等這些圖像示出了圍繞y軸旋轉:Webgl:旋轉對象變得沿着軸線變形

45度:

95度:
enter image description here

135度: enter image description here

我計算投影矩陣,與來自GL-矩陣庫mat4.perspective:

mat4.perspective(this.pMatrix_, this.vFieldOfView_, this.aspect_, this.near_, this.far_); 

用的值:

private near_ = 0.1; 
private far_ = 1000.0; 
private vFieldOfView_ = 60.0 * Math.PI/180; 

頂點着色器:

void main(void) { 
    gl_Position = uProjection * uView * uTransform * vec4(aVertexPosition, 1.0); 
} 

視圖矩陣將對象2.0單位轉換爲遠離相機。

let t = new Mat4(); 
t.array[12] = v.x; 
t.array[13] = v.y; 
t.array[14] = v.z; 

我旋轉使用此代碼生成矩陣繞y軸的平面:

// identity matrix already set 
let rad = angle * Math.PI/180; 
r.array[0] = Math.cos(rad); 
r.array[2] = Math.sin(rad); 
r.array[8] = -1.0 * Math.sin(rad); 
r.array[10] = Math.cos(rad); 

我乘三個變換對象的矩陣順序如下: 旋轉*翻譯*規模。正在使用四元數來處理旋轉,但它們同樣被扭曲,因此回到使用旋轉矩陣並保持旋轉簡單,在一個軸上。看起來我正在按照錯誤的順序進行一些乘法步驟,或者沒有正確使用透視矩陣,或者得到錯誤的符號。

更新:

只是爲了澄清上的一些在頂點着色器矩陣的值:從mat.perspective(...)獲得

uProjection = pMatrix_ =值。可以使用uView = [1,0,0,0,0,1,0,0,0,0,1,0.0,0,0,0,1](即,在z軸上相隔2個單位)的矩陣,其中, 。

uTransform在本例中應該是單位矩陣。

UPDATE2:

uView竟是[1,0,0,0,0,1,0,0,0,0,1,0,0,0,-2.0,1]

+0

如果你正在使用gl-matrix庫,爲什麼'new Mat4()'而不是'mat4.create()'? –

+1

由於您將矩陣分開,因此向我們展示每個矩陣的值可能會有所幫助。它看起來像一個標誌可能翻轉了某處,這就是爲什麼我通常堅持現有的數學庫,如gl矩陣,而不是直接數組訪問。 –

+0

使用typescript並使用Mat4類來簡化類型檢查,這基本上只是一個包含評估者的Float32Array(16)。使用gl-matrix做像透視矩陣這樣的計算。 – dppower

回答

1

您已轉換您的視圖矩陣。你有

1 0 0 0 
0 1 0 0 
0 0 1 0 
0 0 -2 1 

你想:

1 0 0 0 
0 1 0 0 
0 0 1 -2 
0 0 0 1 

這個錯誤永遠不會,如果你只是堅持用GL-矩陣和使用mat4.translate()發生。這就是爲什麼我不使用直接數組訪問來創建矩陣的原因,這太容易搞砸了。

請記住,OpenGL矩陣像列向量數組一樣存儲。所以索引是這樣的:

0 4 8 12 
1 5 9 13 
2 6 10 14 
3 7 11 15 
+0

我在更新中犯了一個錯誤,我把視圖矩陣按錯誤的順序排列,我今天特意檢查矩陣的值。我去使用gl-matrix的函數mat4.rotateY,而且看起來確實有效,所以我已經正確地實現了翻譯和透視,但得到了旋轉矩陣錯誤。需要再去研究一下。 – dppower

0

我發現我的錯誤在哪裏,我的實現是矩陣乘法。正確的代碼是這樣的:

static multiply(a: Mat4, b: Mat4, out: Mat4) { 

    let a11 = a.array[0], a12 = a.array[1], a13 = a.array[2], a14 = a.array[3], 
     a21 = a.array[4], a22 = a.array[5], a23 = a.array[6], a24 = a.array[7], 
     a31 = a.array[8], a32 = a.array[9], a33 = a.array[10], a34 = a.array[11], 
     a41 = a.array[12], a42 = a.array[13], a43 = a.array[14], a44 = a.array[15]; 

    for (let i = 0; i < 16; i += 4) { 
     let b1 = b.array[i], b2 = b.array[i + 1], b3 = b.array[i + 2], b4 = b.array[i + 3]; 
     out.array[i] = b1 * a11 + b2 * a21 + b3 * a31 + b4 * a41; 
     out.array[i + 1] = b1 * a12 + b2 * a22 + b3 * a32 + b4 * a42; 
     out.array[i + 2] = b1 * a13 + b2 * a23 + b3 * a33 + b4 * a43; 
     out.array[i + 3] = b1 * a14 + b2 * a24 + b3 * a34 + b4 * a44; 
    } 
}; 
+0

OpenGL/WebGL不使用矩陣轉置,除非您通過將'GL_TRUE'傳遞給'glUniformMatrix'的轉置參數來請求它。 OpenGL使用常規矩陣,就像其他人一樣。 –