2

上周,我看到了一个着色器脚本,它执行延迟着色。但我对顶点着色器所做的一些变换感到困惑。例如:

垂直:

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);
}

碎片:

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);
}

我真的不明白为什么要将法线转换为世界空间(模型空间)。因为我认为眼睛空间(相机空间)中的法线至少可以消除不可见的顶点,甚至是多边形。我不知道我是否理解错了。

4

1 回答 1

2

光照可以在任何预投影空间(例如,世界坐标或眼睛坐标)中完成,只要所有对象和灯光都在同一个空间中。

此着色器在眼睛坐标中进行照明 - 您可以通过使用旧的gl_NormalMatrix隐式统一变量来判断。这种方法模仿了传统 OpenGL 管道中所做的事情,其中​​照明(在没有着色器时由 OpenGL 实现完成)是在眼睛坐标中完成的。在眼睛坐标中进行照明并没有错,只是它不像其他空间那样直观。

更现代的方法在世界坐标中进行照明,并且不需要使用法线变换矩阵(这是当前模型视图矩阵的上 3x3 的逆转置)。

于 2013-03-24T15:36:40.237 回答