OpenGL 网站中的 Phong 照明
Phong Illumination in OpenGL website
我正在阅读 opengl.org 中的以下 Phong 照明着色器:
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 之间的点积结果也不正确,因为它们的坐标不相同。我说得对吗?
So, we cannot simply subtract the light position from v to calculate
the L vector, because they are not in the same coordinates system.
Also, the result of dot product between L and N won't be correct
because their coordinates are not the same. Am I right about it?
没有
gl_LightSource[0].position.xyz
不是 您设置 GL_POSITION
的值。在 glLight()
调用时,GL 会自动将位置乘以当前 GL_MODELVIEW
矩阵。在固定功能 GL 中,光照计算完全在眼睛 space 中完成。所以V
和N
都需要转化为eyespace,而gl_LightSource[].position
已经转化为eye-space,所以代码是正确的实际上并没有混合不同的坐标 spaces.
您使用的代码依赖于已弃用的功能,使用了 GL 的许多旧的固定功能特性,包括那个特定问题。在现代 GL 中,那些内置的制服和属性不存在,你必须自己定义 - 你可以随意解释它们。
您当然也可以忽略该约定,仍然使用不同的坐标 space 进行内置光照计算,并通过在设置位置时简单地选择其他矩阵来不同地解释 gl_LightSource[].position
(通常,灯光的世界 space 位置已设置,而 GL_MODELVIEW
矩阵仅包含视图变换,因此出现了一些世界静止光源的 eye-space 灯光位置,但是你可以做任何你喜欢的事)。但是,所提供的代码旨在作为固定功能管道的某些 "drop-in" 替代品,因此它将以与固定功能管道相同的方式解释那些内置制服和属性。
我正在阅读 opengl.org 中的以下 Phong 照明着色器:
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 之间的点积结果也不正确,因为它们的坐标不相同。我说得对吗?
So, we cannot simply subtract the light position from v to calculate the L vector, because they are not in the same coordinates system. Also, the result of dot product between L and N won't be correct because their coordinates are not the same. Am I right about it?
没有
gl_LightSource[0].position.xyz
不是 您设置 GL_POSITION
的值。在 glLight()
调用时,GL 会自动将位置乘以当前 GL_MODELVIEW
矩阵。在固定功能 GL 中,光照计算完全在眼睛 space 中完成。所以V
和N
都需要转化为eyespace,而gl_LightSource[].position
已经转化为eye-space,所以代码是正确的实际上并没有混合不同的坐标 spaces.
您使用的代码依赖于已弃用的功能,使用了 GL 的许多旧的固定功能特性,包括那个特定问题。在现代 GL 中,那些内置的制服和属性不存在,你必须自己定义 - 你可以随意解释它们。
您当然也可以忽略该约定,仍然使用不同的坐标 space 进行内置光照计算,并通过在设置位置时简单地选择其他矩阵来不同地解释 gl_LightSource[].position
(通常,灯光的世界 space 位置已设置,而 GL_MODELVIEW
矩阵仅包含视图变换,因此出现了一些世界静止光源的 eye-space 灯光位置,但是你可以做任何你喜欢的事)。但是,所提供的代码旨在作为固定功能管道的某些 "drop-in" 替代品,因此它将以与固定功能管道相同的方式解释那些内置制服和属性。