2

GLSL で基本的な頂点シェーダーを作成しました。ソースコードは次のとおりです。

varying float intensity;
uniform vec4 lightPos;

void main() {
    intensity = 0.1;
    vec3 tfVert = (gl_ModelViewMatrix*gl_Vertex).xyz;
    vec3 tfNorm = normalize(gl_NormalMatrix*gl_Normal).xyz;
    vec3 tfLightPos = (gl_ModelViewMatrix*lightPos).xyz;

    vec3 lightDir = normalize(tfLightPos-tfVert).xyz;
    intensity += dot(lightDir, tfNorm);

    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
}

その後、フラグメント シェーダーは、変化する強度フロートの明るさでフラグメントを照らします。ここで問題が発生します。いくつかの立方体を描画し、OBJ モデルをワールドにロードするか、そのようなことを行います。次に、glRotatef() と glTranslatef() を使用して、同じものを再度描画します。ライトは、2 つの異なる場所で (一種の) 2 回表示されます。平行移動した位置で 1 回、元の位置で 1 回。移動されたモデルは、移動された位置のライトのみの影響を受け、元のモデルは元の位置のライトのみの影響を受けます。また、この問題を解決するために gl_LightSource0[] を使用しないことが重要です。私が間違っていることはありますか?これを修正する方法はありますか?それが重要な場合は、カメラの位置と回転に glTranslatef() と glRotatef() を使用しています。

4

2 に答える 2

1

Don't transform lightPos by gl_ModelViewMatrix

Just use lightPos.xyz in place of tfLightPos -- in fact you dodn't need tfLightPos at all

于 2013-03-07T01:45:49.053 に答える
0

残念ながら、頂点シェーダーにより多くの情報を渡さない限り、これを修正することは不可能です。glTranslatef と glRotatef はモデルの動きだけでなくカメラの動きにも使用されるため、vec3s で変換と回転を GLSL に渡さない限り、シェーダーが 2 つを区別する方法はありません。

于 2013-03-13T15:54:17.980 に答える