2012-11-22 83 views
2

我目前正在研究一個帶有OpenGL的小玩具程序,它在剪輯空間視圖中顯示了一個場景,即它繪製了一個立方體以可視化規範視圖體積並在立方體內部進行投影變換模型繪製。顯示模型圖的代碼片段:OpenGL - 投影后的正確曲面法線

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glScalef(1.0f, 1.0f, -1.0f); 
glMultMatrixd(projectionMat); 
glMultMatrixd(modelviewMat); 
glEnable(GL_LIGHTING); 
draw_model(); 
glDisable(GL_LIGHTING); 

因此,自然,繪製的模型是「扭曲的」(這是期望的行爲)。然而,光照是錯誤的,因爲表面法線也被投影矩陣變換,並且因此在變換之後不與它們的表面正交。我試圖完成的是在扭曲模型的表面具有正確的法線的意義上,「正確」的照明。

問題是 - 我該怎麼做?我正在使用法線通常的轉置 - 逆矩陣法則,但據我所知,這就是OGL默認的法線。我想我將不得不重新計算表面法線後,模型視圖矩陣轉換表面,但如何做到這一點?還是有另一種方式?

+0

你想要做[這樣的事情](http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2017.html#d0e15797)?我的教程解釋瞭如何去做,但它是基於着色器的邏輯。這一切仍然只是矩陣數學,它甚至使用矩陣堆棧,所以你應該能夠翻譯它。 –

+0

其實,「雙重投影」正是我想要做的,是的:)正如你在你的教程中所描述的,重點是在標準化的設備座標中看到「奇怪」的對象形狀。但是,我並沒有真正發現/理解你在曲面法線上做了什麼來在NDC空間中獲得「正確」的照明。在我的例子中,從反轉換模型視圖矩陣中「移除」投影部分是否足以使法線僅由「真實」模型視圖矩陣轉換?我非常喜歡OGL newb,所以請耐心等待:D – user1845810

+0

你讀過我的回答了嗎?另外,本教程不會在NDC空間中進行照明。渲染位置的空間不一定是你照亮的空間。 –

回答

1
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glScalef(1.0f, 1.0f, -1.0f); 
glMultMatrixd(projectionMat); 

投影矩陣進入glMatrixMode(GL_PROJECTION);。轉換法線發生在模型視圖的逆轉置處。如果模型視圖中有一個投影組件,它會擾亂你的正常轉換。

正確的代碼將

glMatrixMode(GL_PROJECTION); 
glLoadMatrixd(projectionMat); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glScalef(1.0f, 1.0f, -1.0f); 
glMultMatrixd(modelviewMat); 
glEnable(GL_LIGHTING); 
draw_model(); 
glDisable(GL_LIGHTING); 
+1

謝謝,但你誤解了我正在嘗試做的事情。我非常清楚投影矩陣的存儲位置(實際上,存在一個存儲在GL_PROJECTION模式中的正確透視投影矩陣)。但是,我的整個代碼的目的是通過繪製由透視投影變換的模型來將透視投影引入的「變形」可視化。我向你保證我的代碼是正確的 - 幾何 - 實現我想要的。我唯一的問題是照明。 – user1845810

+0

@ user1845810:哦,當然,這與固定功能流水線不太一樣。那麼爲什麼不簡單地使用頂點着色器呢?其中,您可以根據需要進行所有計算,也可以將正常計算與某個「模型視圖」矩陣分離;而是傳遞一個單獨的標準變換矩陣,它是從尚未投影的模型視圖中導出的。 – datenwolf

+0

不幸的是,我對OGL相當陌生,不知道如何使用頂點着色器。這通常不會成爲問題,但是由於我的代碼可能僅用於固定功能的大學任務中,所以我認爲最好不要使用頂點着色器。 – user1845810

0

如果您使用固定功能,你必須把所有這一切都在你的投影矩陣。 包括規模,平移和旋轉投影后出現這種情況:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glScalef(1.0f, 1.0f, -1.0f); 
glMultMatrixd(projectionMat); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glMultMatrixd(modelviewMat); 
glEnable(GL_LIGHTING); 
draw_model(); 
glDisable(GL_LIGHTING); 

這工作,因爲位置(即:你看到了什麼)都通過投影和模型視圖矩陣變換兩者,但定點功能照明僅在視圖空間中完成(即:在modelview之後,但之前投影)。

事實上,這正是固定功能GL在兩個矩陣之間有區別的原因。