[英]QMatrix4x4 Model View Projection OpenGL Can't Get Scene to Render
鑒於此頂點着色器:
attribute vec3 vertex;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(vertex, 1.0);
}
這個片段着色器:
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
當mvp
矩陣為單位或模型矩陣為縮放,旋轉或平移變換時,可以渲染以下數據:
GLfloat values[] = {
-1.0, -1.0, +0.0,
+1.0, -1.0, +0.0,
+0.0, +1.0, +0.0,
};
為什么Qt的QMatrix4x4::lookAt
和QMatrix4x4::perspective
的以下用法導致場景呈現為好像沒有對象存在?
QMatrix4x4 model;
QMatrix4x4 view;
view.lookAt(
QVector3D(0.0, 0.0, 10.0), // Eye
QVector3D(0.0, 0.0, 0.0), // Focal Point
QVector3D(0.0, 1.0, 0.0)); // Up vector
QMatrix4x4 proj;
// Window size is fixed at 800.0 by 600.0
proj.perspective(45.0, 800.0 / 600.0, 1.0, 100.0);
QMatrix4x4 mvp = (model * view * proj);
我尋找的不僅是如何修復代碼,而且還希望通過這種方式將來可以調試這些東西。
只是預感,我將mvp更改為p * v * m並解決了該問題。 如果必須以相反的順序進行乘法運算,為什么它是mvp? 我知道矩陣乘法不是可傳遞的。 也就是說,如果A和B是矩陣,則A * B!= B * A如果A和B不是I。
之所以稱為MVP,是因為……有人這樣稱呼它。 ;)
不過,這是有道理的。 它基本上按轉換順序列出了它們的應用順序。 首先,將模型矩陣應用於頂點,然后將視圖矩陣應用於頂點,然后將投影矩陣應用於兩者。
或者在數學上,對於輸入頂點vObj
,您可以編寫:
vWorld = M * vObj
vEye = V * vWorld
vClip = P * vEye
如果替換方程式,則會得到:
vClip = P * vEye = P * (V * vWorld) = P * (V * (M * vObj))
矩陣乘法是關聯的,因此可以重寫為:
P * (V * (M * vObj)) = (P * V * M) * vObj
因此,組合矩陣計算為P * V * M
Reto Koradi是正確的。 這不是因為內存布局或其他原因,而是因為OpenGL使用列向量-具有四行和一列的矩陣或4x1矩陣。 轉換為Matrix4x4 *向量,以滿足矩陣乘法的標准(結果再次為列向量)。
另一種方法是將向量定義為行(1x4矩陣),然后所有轉換為vWorld = vObj * M
等,以滿足矩陣乘法的標准,從而得出行向量。 突然,最后一行被重寫為vClip = vObj * M * V * P
矩陣乘法始終是相同的,您不必關心矩陣在內存中的存儲方式(好吧,除非它是線性數組,並且您需要在行/列中尋址元素),但是根據向量的定義,變換矩陣是不同的。
在OpenGL中,總是從右到左組成變換。 請記住,最左邊的矩陣最后應用。
出於某種原因(歷史?),通常將向量視為列向量,並從右向左應用變換矩陣,但是正如下面的注釋所指出的,可以在GL Shading Language(GLSL)中使用這兩種方法。
這與矩陣的維數和數學符號有關。 矩陣的尺寸定義為行x列。 因此1x3矩陣為M = [abc]。 然后是一個4x4矩陣,如預期的那樣。
僅當B = C(排入列並將結果求和)時,才能將維AxB和CxD的兩個矩陣相乘。
可以將具有XYZW坐標的N個頂點的列表定義為大小為Nx4或4xN的矩陣,但是如果頂點的塊位於矩陣之后,則只有4xN可以與乘法運算符一起使用:
V'(4xN)= M(4x4)x V(4xN)
因此,頂點被視為使此符號起作用的列向量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.