【问题标题】:How to avoid black lines between triangles on modern GPUs?如何避免现代 GPU 上三角形之间的黑线?
【发布时间】:2015-08-11 22:11:36
【问题描述】:

我正在使用 obj 导出构建参数化 3d 建模器。

我真的很困惑。

我昨晚换了GPU,现在,顶点之间有裂缝,我可以看到后面是什么。我的旧卡是英伟达 GTX275,另一张是英伟达 GTX960。 我没有更改代码、着色器或其他方面的任何内容。我只使用纯色(而不是纹理)。

在下图中,将五边形切成三角形的黑线不应该存在。

这似乎纯粹是一个 OpenGL 问题,因为当我导出模型并在 Blender 中查看时,面是连续的并且没有重复的顶点。

着色器代码非常简单:

_VERTEX2 = """
#version 330
#extension GL_ARB_explicit_uniform_location : enable
layout(location = 0 ) in vec3 position;
layout(location = 1 ) in vec4 color;
layout(location = 2 ) in vec3 normal;

varying vec4 baseColor;
// uniform mat4 proj;
layout(location = 0) uniform mat4 view;
layout(location = 4) uniform mat4 proj;

varying vec3 fragVertexEc;

void main(void) {
    gl_Position = proj * view * vec4(position, 1.0);
    fragVertexEc = (view * vec4(position, 1.0)).xyz;
    baseColor = color;
}
"""


_FRAGMENT2 = """
#version 330
#extension GL_OES_standard_derivatives : enable

varying vec3 fragVertexEc;
varying vec4 baseColor;

const vec3 lightPosEc = vec3(0,0,10);
const vec3 lightColor = vec3(1.0,1.0,1.0);

void main()
{
    vec3 X = dFdx(fragVertexEc);
    vec3 Y = dFdy(fragVertexEc);
    vec3 normal=normalize(cross(X,Y));

    vec3 lightDirection = normalize(lightPosEc - fragVertexEc);

    float light = max(0.0, dot(lightDirection, normal));


    gl_FragColor = vec4(normal, 1.0);
    gl_FragColor = vec4(baseColor.xyz * light, baseColor.w);
}
"""

渲染代码也很简单:

def draw(self, view_transform, proj, transform):
    self.shader.use()
    gl_wrap.glBindVertexArray(self.vao)
    try:
        self.vbo.bind()

        view_transform = view_transform * transform
        GL.glUniformMatrix4fv(0, 1, False, (ctypes.c_float*16)(*view_transform.toList()))
        GL.glUniformMatrix4fv(4, 1, False, (ctypes.c_float*16)(*proj.toList()))

        GL.glEnableVertexAttribArray(self.shader.attrib['position'])
        GL.glEnableVertexAttribArray(self.shader.attrib['color'])
        GL.glEnableVertexAttribArray(self.shader.attrib['normal'])

        STRIDE = 40
        GL.glVertexAttribPointer(
            self.shader.attrib['position'], len(Vector._fields), GL.GL_FLOAT,
            False, STRIDE, self.vbo)

        GL.glVertexAttribPointer(
            self.shader.attrib['color'], len(Color._fields), GL.GL_FLOAT,
            False, STRIDE, self.vbo+12)

        GL.glVertexAttribPointer(
            self.shader.attrib['normal'], len(Vector._fields), GL.GL_FLOAT,
            False, STRIDE, self.vbo+28)

        GL.glDrawElements(
            GL.GL_TRIANGLES,
            len(self.glindices),
            self.index_type,
            self.glindices)

    finally:
        self.vbo.unbind()
        gl_wrap.glBindVertexArray(0)
        self.shader.unuse()

一个简单的四边形将以下数据发送到 OpenGL:

vertices ( flat array of pos+rgba+normal) :
[5.0, -3.061616997868383e-16, 5.0, 0.898, 0.0, 0.0, 1.0, 0.0, 1.0, 6.123233995736766e-17, 
-5.0, 3.061616997868383e-16, -5.0, 0.898, 0.0, 0.0, 1.0, 0.0, 1.0, 6.123233995736766e-17, 
-5.0, -3.061616997868383e-16, 5.0, 0.898, 0.0, 0.0, 1.0, 0.0, 1.0, 6.123233995736766e-17, 
5.0, 3.061616997868383e-16, -5.0, 0.898, 0.0, 0.0, 1.0, 0.0, 1.0, 6.123233995736766e-17]

indices  :: [0, 1, 2, 0, 3, 1]

【问题讨论】:

  • 有趣的事实:Blender 也使用 OpenGL。
  • 我不知道是什么原因造成的,除了顶点位置略有不同。你确定没有重复的顶点?您的顶点缓冲区中只有 5 个顶点?
  • @jerem :我已经检查了 Blender,顶点似乎没问题,意味着共享。移动金字塔的顶部顶点,移动所有的面。但是......导出代码路径不进行三角测量,我会在那里检查。谢谢。
  • 您能否打印顶点缓冲区和索引缓冲区(用于渲染的缓冲区)的内容并将其添加到您的帖子中?也许我们会在那里看到一些东西。
  • 哦,但首先尝试更改片段着色器以输出硬编码颜色,看看问题是否仍然存在。只是为了确保这不是照明代码问题。

标签: opengl gpu opengl-3 pyopengl opengl-4


【解决方案1】:

好的,知道了!

奇怪的显示是由于 glEnabled(GL_POLYGON_SMOOTH)。

我完全忘记了它,因为我的旧卡在此设置下没有做任何事情。至少是看不见的。 但是新的具有正确的行为:它尝试独立地对每个三角形进行抗锯齿处理,因此是黑线。

非常感谢@Jerem,他帮助我了解了其他可能性。

【讨论】:

  • 哈,我什至忘记了这个标志的存在^^很高兴我能帮上忙。
猜你喜欢
  • 1970-01-01
  • 2012-10-14
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 2017-08-31
  • 2012-06-02
相关资源
最近更新 更多