我是通過以下的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之間的點積的結果將不正確,因爲它們的座標不一樣。我對嗎?
哦,我明白了。因此,'gl_NormalMatrix'包含舊的固定功能流水線中的model_view矩陣,並且'gl_LightSource'也被轉換爲視圖座標。然後,代碼正在工作。 實際上,我正在檢查superbible opengl phong照明着色器,它也在視圖座標中進行phong照明計算。 – mmostajab
@mmostajab:好的,'gl_NormalMatrix'是從modelview矩陣派生出來的,它不是一回事。原因在於法線在某些情況下必須進行不同的變換。考慮一個「歪斜」操作。如果將它直接應用於法線方向,則所得的法線不再垂直於表面。 (假設他們之前)。對此,我們給出了更多的解釋[在這個lighthouse3d教程中](http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/)。 – derhass