OpenGL简单着色,伪影



我一直在尝试实现一个简单的灯光/阴影系统,一个没有镜面光的简单Phong照明系统。它基本上有效,除了它有一些(在我看来(令人讨厌的工件。

我的第一个想法是,也许这是纹理 mipmap 的问题,但禁用它们不起作用。我的下一个最佳猜测是着色器问题,但我似乎找不到错误。

有没有人遇到过类似的问题或关于如何解决这个问题的想法?

工件的图像

顶点着色器:

#version 330 core
// Vertex shader
layout(location = 0) in vec3 vpos;
layout(location = 1) in vec2 vuv;
layout(location = 2) in vec3 vnormal;
out vec2 uv;        // UV coordinates
out vec3 normal;    // Normal in camera space
out vec3 pos;       // Position in camera space
out vec3 light[3];  // Vertex -> light vector in camera space
uniform mat4 mv;    // View * model matrix
uniform mat4 mvp;   // Proj * View * Model matrix
uniform mat3 nm;    // Normal matrix for transforming normals into c-space
void main() {
    // Pass uv coordinates
    uv = vuv;
    // Adjust normals
    normal = nm * vnormal;
    // Calculation of vertex in camera space
    pos = (mv * vec4(vpos, 1.0)).xyz;
    // Vector vertex -> light in camera space
    light[0] = (mv * vec4(0.0,0.3,0.0,1.0)).xyz - pos;
    light[1] = (mv * vec4(-6.0,0.3,0.0,1.0)).xyz - pos;
    light[2] = (mv * vec4(0.0,0.3,4.8,1.0)).xyz - pos;
    // Pass position after projection transformation
    gl_Position = mvp * vec4(vpos, 1.0);
}

片段着色器:

#version 330 core
// Fragment shader
layout(location = 0) out vec3 color;
in vec2 uv;     // UV coordinates
in vec3 normal;     // Normal in camera space
in vec3 pos;        // Position in camera space
in vec3 light[3];   // Vertex -> light vector in camera space
uniform sampler2D tex;
uniform float flicker;
void main() {
    vec3 n = normalize(normal);
    // Ambient
    color = 0.05 * texture(tex, uv).rgb;
    // Diffuse lights
    for (int i = 0; i < 3; i++) {
        l = normalize(light[i]);
        cos = clamp(dot(n,l), 0.0, 1.0);
        length = length(light[i]);
        color += 0.6 * texture(tex, uv).rgb * cos / pow(length, 2);
    }
}

正如第一条评论所说,看起来您的颜色计算使用的精度不足。尝试使用中浮点数或高浮点数。

此外,length = length(light[i]); pow(length,2)表达式效率非常低,也可能是观察到的条带的来源;您应该改用dot(light[i],light[i])

因此,我找到了有关我的问题的信息,该信息被描述为"梯度带",也在这里进行了讨论。问题似乎出在我的纹理的性质上,因为只有"白色"纹理和真实纹理大多是灰色/白色,并且当每个颜色通道使用 256 位时,实际上有 8 个灰色级别。

解决方案是实现后处理抖动或使用更好的纹理。

最新更新