7

私はカスタム ライト シェーダを作成しようとしており、時間をかけてさまざまなことを試していました。私が見つけた解決策の中には、うまくいくものもあれば、うまくいかないものもあります。この質問については、これまでで最も効果的なソリューションを使用しています。

私の問題は、「カメラ」を動かすと、ライトの位置も動くように見えることです。このソリューションには非常にわずかですが顕著な動きがあり、ライトの位置が本来あるべき場所よりも上にあるようです。

デフォルトの OpenGL ライティング (シェーダーなし) は正常に動作します (安定したライト位置) が、マルチテクスチャリングにはシェーダーが必要であり、シェーダーが機能したらライティング効果にその一部を使用する予定です。

頂点ソース:

varying vec3 vlp, vn;

void main(void)
{
    gl_Position = ftransform();

    vn = normalize(gl_NormalMatrix * -gl_Normal);
    vlp = normalize(vec3(gl_LightSource[0].position.xyz) - vec3(gl_ModelViewMatrix * -gl_Vertex));

    gl_TexCoord[0] = gl_MultiTexCoord0;
} 

フラグメント ソース:

uniform sampler2D baseTexture;
uniform sampler2D teamTexture;
uniform vec4 teamColor;

varying vec3 vlp, vn;

void main(void)
{
    vec4 newColor = texture2D(teamTexture, vec2(gl_TexCoord[0]));
    newColor = newColor * teamColor;
    float teamBlend = newColor.a;

    // mixing the textures and colorizing them. this works, I tested it w/o lighting!
    vec4 outColor = mix(texture2D(baseTexture, vec2(gl_TexCoord[0])), newColor, teamBlend);

    // apply lighting
    outColor *= max(dot(vn, vlp), 0.0);
    outColor.a = texture2D(baseTexture, vec2(gl_TexCoord[0])).a;

    gl_FragColor = outColor;
}

私は何を間違っていますか?

4

1 に答える 1

5

これらのいずれかが問題であるとは断言できませんが、問題を引き起こす可能性があります。

まず、頂点ごとに正規化する必要がありますvn(vlpところで、よりわかりやすい変数名を使用してみてください。viewLightPositionよりもはるかに理解しやすいですvlp)。頂点シェーダーでそれらを正規化したことは知っていますが、フラグメント シェーダー補間によって非正規化されます。

第二に、これは冗長というほど特に間違っているわけではありません。vec3(gl_LightSource[0].position.xyz). スウィズル マスク (「.xyz」) には 3 つのコンポーネントしかないため、「position.xyz」は既に vec3 です。もう一度 vec3 にキャストする必要はありません。

于 2011-06-17T22:20:04.040 に答える