我正在阅读以下opengl.org中的Phong照明着色器:
顶点着色器和片段着色器如下:
顶点着色器:
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之间的点积结果也不正确,因为它们的坐标不同。我对吗?
因此,我们不能简单地从v减去光的位置来计算L向量,因为它们不在同一坐标系中。此外,L和N之间的点积结果也不正确,因为它们的坐标不同。我对吗?
不。
该gl_LightSource[0].position.xyz
是不是你设置的值GL_POSITION
来。调用GL_MODELVIEW
时,GL将自动将位置乘以当前矩阵glLight()
。固定功能GL中的眼睛空间完全可以进行照明计算。因此,无论V
并且N
必须转换到眼空间,gl_LightSource[].position
将已转化为眼睛的空间,所以代码是正确的,实际上没有混合不同的坐标空间。
您正在使用的代码依赖于不推荐使用的功能,并使用了GL的许多旧的固定功能,包括该特定问题。在现代GL中,这些内置的制服和属性不存在,因此您必须定义自己的制服和属性,并且可以根据需要对其进行解释。
您当然也可以忽略该约定,仍然使用内置函数来使用不同的坐标空间进行照明计算,并gl_LightSource[].position
通过在设置位置时简单地选择其他矩阵来进行不同的解释(通常,在GL_MODELVIEW
矩阵包含仅视图转换,以便出现某些世界平稳光源的眼空间光位置,但您可以执行任何喜欢的操作。但是,本文提供的代码旨在作为固定功能管道的“替代”替代品,因此它将以与固定功能管道相同的方式解释那些内置的制服和属性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句