2015-05-29 7 views
2

Я строю параметрический 3d-модельер с экспортом obj.Как избежать черных линий между треугольниками на современных графических процессорах?

Я действительно озадачен.

Я поменял свой GPU прошлой ночью, и теперь, между вершинами есть трещины, я вижу, что позади. Моя старая карта была Nvidia GTX275 и одна, NVIDIA GTX960. Я ничего не менял в коде, шейдере или другом. Я использую только плоские цвета (не текстуры).

На изображении ниже черные линии, которые разрезают пятиугольник в треугольник, не должны быть там.

enter image description here

Вроде бы чисто проблема 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] 
+0

Забавный факт: Blender также использует OpenGL. – Jerem

+1

Я не знаю, что может быть причиной этого, за исключением слегка разных вершинных позиций. Вы уверены, что нет дублированных вершин? У вас только 5 вершин в вашем буфере вершин? – Jerem

+0

@jerem: Я проверил в Blender, вершины выглядят нормально, что означает общий. Перемещая верхнюю вершину пирамиды, переместите все грани. Но ... путь к экспортному коду не выполняет триангуляцию, я проверю там. Thks. – LBarret

ответ

3

ОК, понял!

странный дисплей вызван glEnabled (GL_POLYGON_SMOOTH).

Я совершенно забыл об этом, так как моя старая карта ничего не делала с этой настройкой. По крайней мере, это было не видно. Но новый имеет правильное поведение: он пытается сгладить каждый треугольник независимо, а значит, и черные линии.

Большое спасибо @Jerem, который помог мне покрыть другие возможности.

+1

Ха Я даже забыл, что этот флаг существует ^^ Рад, что я мог бы помочь. – Jerem