上周,我看到了一个着色器脚本,它做了延迟着色。但是我对顶点着色器的一些变换感到困惑。如下所示:
VERT:
varying vec3 normals;
varying vec4 position;
uniform mat4 ModelMatrix;
uniform mat4 WorldMatrix;
void main( void )
{
// Move the normals back from the camera space to the world space
mat3 worldRotationInverse = transpose(mat3(WorldMatrix));
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
**normals = normalize(worldRotationInverse * gl_NormalMatrix * gl_Normal); <<<<<**
position = gl_ModelViewMatrix * gl_Vertex;
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
}
frag:
varying vec4 position;
varying vec3 normals;
varying mat4 TBN;
uniform sampler2D tDiffuse;
void main( void )
{
gl_FragData[0] = vec4(texture2D(tDiffuse,gl_TexCoord[0].st).rgb, 0);
gl_FragData[1] = vec4(position.xyz,0);
gl_FragData[2] = vec4(normals.xyz,0);
}
我真的不明白为什么要将法线转换为世界空间(模型空间)。因为我认为眼睛空间(相机空间)中的法线是至少可以消除不可见顶点甚至是ploygon的原因。我不知道我是否理解错误。
答案 0 :(得分:2)
只要所有物体和灯光都在同一个空间内,就可以在任何预投影空间(例如世界坐标或眼睛坐标)进行照明。
此着色器在眼睛坐标中进行照明 - 您可以通过使用遗留gl_NormalMatrix
隐式统一变量来判断。这种方法模仿了传统OpenGL管道中所做的工作,其中在眼睛坐标中完成了光照(在没有着色器时由OpenGL实现完成)。在眼睛坐标中进行照明没有任何问题,它不像其他空间那么直观。
更现代的方法在世界坐标中进行照明,并且不需要使用法向变换矩阵(这是当前模型 - 视图矩阵的上3x3的逆转置)。