法线似乎是错误的方式

时间:2014-02-01 15:41:14

标签: opengl 3d shader fragment-shader lighting

我觉得我的法线是错误的,但我怎么能确认这是问题,我该如何解决?

我在视觉上体验的是,我在y = -10处有一个大地平面(y是向上/向下轴),并且有一些从(0, y, 0)(4, y, 4)的小地形大致0 <= y <= 5

然后我有一盏灯发出来自(0.0, 7.5, 0.0)的环境光和漫射光 当我从地形上方看到地形时,我只能看到环境 当我从地形下方看到地形时,我开始看到漫射光。

负责任的着色器是:

terrain.vs.glsl

#version 440 core

layout(location = 0) in vec4 position;

layout(location = 0) uniform mat4 model_matrix;
layout(location = 1) uniform mat4 view_matrix;

void main(void) {
    gl_Position = view_matrix * model_matrix * position;
}

terrain.tcs.glsl

#version 440 core

layout(vertices = 16) out;

void main(void) {
    uint id = gl_InvocationID;

    if (id == 0) {
        gl_TessLevelInner[0] = 32.0;
        gl_TessLevelInner[1] = 32.0;

        gl_TessLevelOuter[0] = 32.0;
        gl_TessLevelOuter[1] = 32.0;
        gl_TessLevelOuter[2] = 32.0;
        gl_TessLevelOuter[3] = 32.0;
    }

    gl_out[gl_InvocationID].gl_Position = gl_in[id].gl_Position;
}

terrain.tes.glsl

#version 440 core

layout(quads, equal_spacing, cw) in;

layout(location = 0) uniform mat4 model_matrix;
layout(location = 1) uniform mat4 view_matrix;
layout(location = 2) uniform mat4 proj_matrix;

out TES_OUT {
    vec3 N;
    vec3 L;
    vec3 V;
} tes_out;

uniform vec3 light_pos = vec3(0.0, 7.5, 0.0);

vec4 quadratic_bezier(vec4 A, vec4 B, vec4 C, float t) {
    vec4 D = mix(A, B, t);
    vec4 E = mix(B, C, t);

    return mix(D, E, t);
}

vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t) {
    vec4 E = mix(A, B, t);
    vec4 F = mix(B, C, t);
    vec4 G = mix(C, D, t);

    return quadratic_bezier(E, F, G, t);
}

vec4 evaluate_patch(vec2 at) {
    vec4 P[4];
    int i;

    for (i = 0; i < 4; i++) {
        P[i] = cubic_bezier(gl_in[i].gl_Position, gl_in[i + 4].gl_Position, gl_in[i + 8].gl_Position, gl_in[i + 12].gl_Position, at.y);
    }

    return cubic_bezier(P[0], P[1], P[2], P[3], at.x);
}

const float epsilon = 0.001;

void main(void) {
    vec4 p1 = evaluate_patch(gl_TessCoord.xy);
    vec4 p2 = evaluate_patch(gl_TessCoord.xy + vec2(0.0, epsilon));
    vec4 p3 = evaluate_patch(gl_TessCoord.xy + vec2(epsilon, 0.0));

    vec3 v1 = normalize(p2.xyz - p1.xyz);
    vec3 v2 = normalize(p3.xyz - p1.xyz);

    //normal
    tes_out.N = cross(v1, v2);

    //light vector
    tes_out.L = light_pos - p1.xyz;

    //view vector
    tes_out.V = -p1.xyz;

    gl_Position = proj_matrix * p1;
}

terrain.fs.glsl

#version 440 core

out vec4 color;

in TES_OUT {
    vec3 N;
    vec3 L;
    vec3 V;
} fs_in;

uniform vec3 ambient = vec3(0.3, 0.3, 0.3);
uniform vec3 diffuse_albedo = vec3(1.0, 0.0, 0.0);

void main(void) {
    //normalize
    vec3 N = normalize(fs_in.N);
    vec3 L = normalize(fs_in.L);
    vec3 V = normalize(fs_in.V);

    //calculate R
    vec3 R = reflect(-L, N);

    //calculate diffuse
    vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo;

    //write color
    color = vec4(ambient + diffuse, 1.0);
}

有人能给我一些提示吗?

更新:我注意到的另一件奇怪的事情是我在普通坐标中定义light_pos。我不应该对它们应用view_matrix吗?

0 个答案:

没有答案