首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

OpenGL 矩陣存儲順序與坐標系變換的數學本質

     編輯:關於C語言

OpenGL 矩陣佈局:列主序

OpenGL 使用列主序存儲 4×4 矩陣:


m[0]  m[4]  m[8]  m[12]   ← 第 0 列
m[1]  m[5]  m[9]  m[13]   ← 第 1 列
m[2]  m[6]  m[10] m[14]   ← 第 2 列
m[3]  m[7]  m[11] m[15]   ← 第 3 列

對應數學矩陣(行主序寫法):


| m0  m4  m8  m12 |
| m1  m5  m9  m13 |
| m2  m6  m10 m14 |
| m3  m7  m11 m15 |

OpenGL 官方文檔的坐標系解讀

glGetFloatv(GL_MODELVIEW_MATRIX, m) 獲取的矩陣:

  • X 軸向量:(m[0], m[1], m[2]) —— **第 0 列前三個分量**
  • Y 軸向量:(m[4], m[5], m[6]) —— **第 1 列前三個分量**
  • Z 軸向量:(m[8], m[9], m[10]) —— **第 2 列前三個分量**
  • 原點(平移):(m[12], m[13], m[14]) —— **第 3 列前三個分量**

這與列主序一致:基向量存儲在列中。

數學推導:矩陣向量乘法

列主序矩陣 M 作用於列向量 v = (x,y,z,w)ᵀ:


v' = M * v
x' = m0*x + m4*y + m8*z + m12*w
y' = m1*x + m5*y + m9*z + m13*w
z' = m2*x + m6*y + m10*z + m14*w
w' = m3*x + m7*y + m11*z + m15*w

**注意係數索引**:m0,m4,m8,m12 是第一行(數學意義),但內存中是第 0 列。

平移分量的幾何含義

設物體局部坐標系原點在世界坐標系為 (Ox, Oy, Oz)。
局部點 (x,y,z,1) 變換到世界:


x' = X軸·x + Y軸·y + Z軸·z + 原點

對比矩陣乘法,得:


m[12] = Ox
m[13] = Oy
m[14] = Oz

**直接等於原點坐標**,而非負的點積。之前推導出現負號是因為混淆了「物體→世界」與「世界→物體」(視圖矩陣)的方向。

視圖矩陣 vs 模型矩陣

常見誤區澄清

  1. 「OpenGL 是行主序」:錯。OpenGL 規範、GLSL、glUniformMatrix4fv 默認均為**列主序**。
  2. 「m[12],m[13],m[14] 是平移」:僅對模型矩陣。視圖矩陣平移分量為 -dot(軸, 相機位置)。
  3. 「基向量在行中」:列主序下基向量在**列**中。行主序(如 DirectX、glm 默認構造)基向量在行中。

代碼驗證:提取模型矩陣平移與旋轉


// 假設 m 為列主序 float[16]
vec3 translation = vec3(m[12], m[13], m[14]);
mat3 rotation = mat3(
    m[0], m[1], m[2],
    m[4], m[5], m[6],
    m[8], m[9], m[10]
);
// rotation 為正交矩陣(無縮放時),列向量為局部 XYZ 軸在世界方向

總結

OpenGL 矩陣**列主序存儲、列向量為基向量、第 3 列為平移(模型矩陣)**。理解「存儲順序 ≠ 數學寫法順序」、「模型 vs 視圖矩陣平移語義不同」是圖形編程避坑關鍵。建議統一使用成熟數學庫(glm、Eigen)處理矩陣運算,專注幾何邏輯而非索引計算。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
模型矩陣視圖矩陣
意義局部 → 世界世界 → 相機
平移分量物體世界坐標相機世界坐標的負點積
基向量物體局部軸在世界方向世界軸在相機方向