讓我們從基礎開始。
通常情況下,你想通過下面的步驟來改變你的本地三角形頂點:
local-space coords-> world-space coords -> view-space coords -> clip-space coords
在標準GL,第2個變換通過GL_MODELVIEW_MATRIX
完成,第三個是通過GL_PROJECTION_MATRIX
完成
這些模型視圖轉換對於我們通常要應用的許多有趣變換(例如,平移,縮放和旋轉等)來說,在我們用表示頂點時碰巧可以表示爲矢量矩陣乘法。典型地,頂點V = (x, y, z)
在該系統中被表示爲(x, y, z, 1)
。
好的。假設我們想通過翻譯轉換頂點V_local,然後是旋轉,然後是翻譯。每個變換可以表示爲矩陣*,我們稱它們爲T1,R1,T2。 我們希望將變換應用於每個頂點:V_view = V_local * T1 * R1 * T2
。矩陣乘法是關聯的,我們可以一勞永逸計算M = T1 * R1 * T2
。
這樣,我們只需要將M傳遞給頂點程序,並計算V_view = V_local * M
。最後,典型的頂點着色器將頂點位置乘以單個矩陣。計算一個矩陣的所有工作都是如何將對象從本地空間移動到剪輯空間。
好的...我瞥了一些重要的細節。
首先,我到目前爲止所描述的只是真正涵蓋了我們通常希望做的視圖空間轉換,而不是剪輯空間。但是,硬件期望頂點着色器的輸出位置在該特殊的剪輯空間中表示。在沒有重要數學的情況下,很難解釋片段空間座標,所以我會將其忽略,但重要的一點是,將頂點引入該片段空間的變換通常可以表示爲相同類型的矩陣乘法。這是舊的gluPerspective,glFrustum和glOrtho計算的結果。
其次,這是你應用於頂點的位置。改變法線的數學有些不同。這是因爲你希望法線在變換之後保持垂直於表面(作爲參考,它在一般情況下需要乘以模型視圖的逆轉置,但在很多情況下可以簡化)
第三,你永遠不會向頂點着色器發送四維座標。一般來說,你會通過3D。 OpenGL會將這些三維座標(或二維,btw)轉換爲四維座標,以便頂點着色器不必添加額外的座標。它展開每個頂點以添加1作爲w
座標。
所以......把所有的東西放在一起,對於每個對象,你需要根據你想要應用到對象的所有變換來計算這些魔術M矩陣。在着色器中,您必須將每個頂點位置乘以該矩陣,並將其傳遞給頂點着色器位置輸出。典型的代碼是多還是少(這是用舊的命名):
mat4 MVP;
gl_Position=MVP * gl_Vertex;
*實際矩陣可以在網絡上找到,特別是在手冊頁每個這樣的功能:rotate,translate,scale,perspective ,ortho
謝謝你的回答!我錯過的一個細節是你可以在調用glDrawElements之間改變MVP矩陣(例如聲明它是統一的)...... 奇怪的從khronos移動到離開這些非常常見的矩陣的規格給程序員。希望他們能很快找到他們的方式,或者類似的方式...... – Wonko 2009-10-28 22:37:01
這就是中間件的用途。 GL3.2對於快速編碼的表現力較弱。但是以前的版本對於實際應用來說是錯誤的抽象層次。它需要一個國家管理框架。 另外,假設你想保持矩陣。這意味着驅動程序必須保留所有的矩陣堆棧,如何將它們僅傳遞給需要它的_all_着色器(不僅僅是頂點),找出你需要哪種味道--M,MV,MVP,IT(MV),IT(M )。最糟糕的部分?該應用程序是唯一一個可以通過一次運行多個矩陣操作來提高數學效率的應用程序。 GL無法做到這一點。 – Bahbar 2009-10-29 10:03:55