2

先週、遅延シェーディングを行うシェーダースクリプトを1つ見ましたが、頂点シェーダーが行う変換によって混乱しました。たとえば、次のようになります。

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

フラグ:

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 に答える