Simple GLSL Shader (Light) 导致闪烁

Simple GLSL Shader (Light) causes flickering

我正在尝试按照 here and here 上的教程实现一些基本的光照和阴影。

一切都或多或少地工作,但由于阴影,我在物体表面出现某种奇怪的闪烁。

我附上了两张图片来向大家展示这个问题的样子。

我认为问题与我将顶点坐标从顶点着色器传递到片段着色器以计算上述链接教程中所述的一些光照变量有关。

这是一些源代码(删除了不相关的代码)。

顶点着色器:

#version 150 core

in vec4 pos;
in vec4 in_col;
in vec2 in_uv;
in vec4 in_norm;

uniform mat4 model_view_projection;


out vec4 out_col;
out vec2 passed_uv;
out vec4 out_vert;
out vec4 out_norm;


void main(void) {
    gl_Position = model_view_projection * pos;

    out_col = in_col;
    out_vert = pos;
    out_norm = in_norm;
    passed_uv = in_uv;
}

和片段着色器:

#version 150 core

uniform sampler2D tex;

uniform mat4 model_mat;

in vec4 in_col;
in vec2 passed_uv;
in vec4 vert_pos;
in vec4 in_norm;

out vec4 col;

void main(void) {

    mat3 norm_mat = mat3(transpose(inverse(model_mat)));
    vec3 norm = normalize(norm_mat * vec3(in_norm));

    vec3 light_pos = vec3(0.0, 6.0, 0.0);
    vec4 light_col = vec4(1.0, 0.8, 0.8, 1.0);

    vec3 col_pos = vec3(model_mat * vert_pos);

    vec3 s_to_f = light_pos - col_pos;

    float brightness = dot(norm, normalize(s_to_f));
    brightness = clamp(brightness, 0, 1);

    gl_FragColor = out_col;

    gl_FragColor = vec4(brightness * light_col.rgb * gl_FragColor.rgb, 1.0);
}

正如我之前所说,我猜问题与顶点位置传递给片段着色器的方式有关。如果我将位置值更改为静态值,则不会再出现闪烁。 我也将所有其他值更改为静态值。这是相同的结果 - 如果我没有使用从顶点着色器传递的顶点位置数据,则不会闪烁。

所以,如果有人有一些 GL 智慧 .. ;) 任何帮助,将不胜感激。 旁注:运行 Intel HD 4000 上的所有这些东西,如果可以提供更多信息的话。

提前致谢! 伊万

顶点着色器中的 out 变量的名称和片段着色器中的 in 变量的名称需要匹配。你在顶点着色器中有这个:

out vec4 out_col;
out vec2 passed_uv;
out vec4 out_vert;
out vec4 out_norm;

片段着色器中的这个:

in vec4 in_col;
in vec2 passed_uv;
in vec4 vert_pos;
in vec4 in_norm;

这些变量是按名称关联的,而不是按顺序关联的。除了passed_uv,这里的名称不匹配。例如,您可以在顶点着色器中使用这些声明:

out vec4 passed_col;
out vec2 passed_uv;
out vec4 passed_vert;
out vec4 passed_norm;

片段着色器中的这些:

in vec4 passed_col;
in vec2 passed_uv;
in vec4 passed_vert;
in vec4 passed_norm;

根据我阅读规范的方式,您的着色器程序实际上应该无法 link。至少在 GLSL 4.50 规范中,在第 43 页的 table 中,针对这种情况列出了 "Link-Time Error"。不过,这些规则在早期规范中似乎有些模棱两可。