2015-01-17 29 views
1

我是通過以下的Phong光照渲染其在opengl.org閱讀:海防照明在OpenGL網站

Phong Illumination in Opengl.org

頂點和片段着色器如下:

頂點着色器:

varying vec3 N; 
varying vec3 v; 
void main(void) 
{  
    v = vec3(gl_ModelViewMatrix * gl_Vertex);  
    N = normalize(gl_NormalMatrix * gl_Normal); 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

片段着色器:

varying vec3 N; 
varying vec3 v;  
void main (void) 
{ 
    vec3 L = normalize(gl_LightSource[0].position.xyz - v); 
    vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0) 
    vec3 R = normalize(-reflect(L,N)); 

    //calculate Ambient Term: 
    vec4 Iamb = gl_FrontLightProduct[0].ambient;  

    //calculate Diffuse Term: 
    vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0); 
    Idiff = clamp(Idiff, 0.0, 1.0);  

    // calculate Specular Term: 
    vec4 Ispec = gl_FrontLightProduct[0].specular 
       * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); 
    Ispec = clamp(Ispec, 0.0, 1.0); 
    // write Total Color: 
    gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;  
} 

我想知道他計算查看器矢量或v的方式。因爲通過將頂點位置乘以gl_ModelViewMatrix,結果將在視圖矩陣中(並且與世界座標相比,視圖座標大部分時間被旋轉)。

因此,我們不能簡單地從v中減去燈光位置來計算L矢量,因爲它們不在同一座標系統中。而且,L和N之間的點積的結果將不正確,因爲它們的座標不一樣。我對嗎?

回答

4

因此,我們不能簡單地從v中減去燈位置來計算 的L向量,因爲它們不在同一個座標系中。 此外,L與N之間的點積的結果將不正確 ,因爲它們的座標不相同。我對嗎?

gl_LightSource[0].position.xyz值設置GL_POSITION來。 GL將在glLight()呼叫時自動將位置乘以當前的GL_MODELVIEW矩陣。照明計算完全在固定功能GL的眼睛空間中完成。因此,VN必須轉換爲眼圖空間,並且gl_LightSource[].position已經被轉換爲眼睛空間,所以代碼是正確的,實際上不是混合不同的座標空間。

您使用的代碼依賴於不推薦的功能,使用許多GL的舊固定功能特性,包括特定問題。在現代GL中,那些內置的制服和屬性並不存在,你必須定義你自己的 - 並且你可以隨意解釋它們。

您當然也可以忽略該慣例,並且仍然使用不同的座標空間來進行光照計算,並且在設置位置時通過簡單地選擇其他矩陣來解釋gl_LightSource[].position(通常,光的世界空間位置是而GL_MODELVIEW矩陣僅包含視角變換,因此某個世界靜止光源的眼外光位置會出現,但您可以隨心所欲地做任何事情)。然而,所提供的代碼旨在用作固定功能流水線的一些「插入式」替代品,因此它將以固定功能流水線的相同方式解釋這些內置的制服和屬性。

+0

哦,我明白了。因此,'gl_NormalMatrix'包含舊的固定功能流水線中的model_view矩陣,並且'gl_LightSource'也被轉換爲視圖座標。然後,代碼正在工作。 實際上,我正在檢查superbible opengl phong照明着色器,它也在視圖座標中進行phong照明計算。 – mmostajab

+0

@mmostajab:好的,'gl_NormalMatrix'是從modelview矩陣派生出來的,它不是一回事。原因在於法線在某些情況下必須進行不同的變換。考慮一個「歪斜」操作。如果將它直接應用於法線方向,則所得的法線不再垂直於表面。 (假設他們之前)。對此,我們給出了更多的解釋[在這個lighthouse3d教程中](http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/)。 – derhass