0

以下に、法線マッピングのシェーダー コードを示します。それにもかかわらず、結果の画像が正しくないため、コードに何か問題があります。法線が外れているようです。他の機能は正常に動作しているように見えるので、問題はシェーダーにあると思います。何が間違っている可能性がありますか?

頂点シェーダー

#version 150

in vec3 position;
in vec2 texcoord;
in vec3 normal;
in vec3 tangent;
in vec3 bitangent;

out vec2 Texcoord;
out vec3 VertexPos_World;
out vec3 LightDir_Tan;

uniform vec3 lightPos0_World;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() 
{
    gl_Position = proj * view * model * vec4(position, 1.0);
    Texcoord = texcoord;    
    VertexPos_World = (model * vec4(position, 1.0)).xyz;

    vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
    vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
    vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

    mat3 TBN = transpose(mat3(tangent_Cam, bitangent_Cam, normal_Cam));

    vec3 lightDir_Cam = lightPos_Cam - vertexPos_Cam;
    LightDir_Tan = TBN * lightDir_Cam;
}

フラグメントシェーダー

#version 150

in vec2 Texcoord;
in vec3 VertexPos_World;
in vec3 LightDir_Tan;

out vec4 outColor;

uniform vec3 lightPos0_World;
uniform vec3 lightColor0;
uniform float lightPower0;

uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform sampler2D tex0;
uniform sampler2D tex0normal;

void main() 
{
    float lightDistance = length(lightPos0_World - VertexPos_World);

    vec3 materialDiffuseColor = texture(tex0, Texcoord).xyz * diffuseColor;
    vec3 materialAmbientColor = ambientColor * materialDiffuseColor;

    vec3 n = normalize(texture(tex0normal, Texcoord).rgb * 2.0 - 1.0);
    vec3 l = normalize(LightDir_Tan);
    float diff = clamp(dot(n,l), 0, 1);

    outColor.rgb = 
            materialAmbientColor +
            materialDiffuseColor * lightColor0 * lightPower0 * diff / (lightDistance * lightDistance);
}
4

2 に答える 2

3

これが唯一の問題ではないかもしれませんが、シェーダーには次のものがあります。

vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

これは次のようになります。

vec3 normal_Cam = (view * model * vec4(normal, 0.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 0.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 0.0)).xyz; 

これらは位置ではなく方向ベクトルであるため、0.0代わりに を使用するため、行列の平行移動を無視する必要があります。1.0

また、アプリケーションでこれらの行列を乗算し、シェーダーで統一された view_model を使用する必要があります (それ以外の場合は、モデルごとではなく頂点ごとにこの作業を行います)。

于 2013-07-17T11:11:56.223 に答える
1

あなたの法線はおそらく非常にずれています。8 つの頂点を持つ立方体を送信する代わりに、面ごとに正しい法線を送信できるように、面ごとに 4 つの頂点を持つ立方体を送信するようにしてください。それ以外の場合、補間器は単にインデックス付き隣接三角形の法線を使用するだけであり、それが問題の原因です。

于 2013-07-16T20:59:25.643 に答える