2013-03-24 100 views
0

我有一个由8个顶点的立方体组成的模型,而且我对每个顶点定向照明都有问题。而不是一次点亮整个模型,每个立方体似乎分开点亮,如thisopengl中的每个顶点照明问题4

这是我的顶点着色器:

layout(location = 0)in vec3 vp; 
layout(location = 1)in vec3 color; 
layout(location = 2)in vec3 normal; 

out vec3 fColor; 

uniform mat4 model; 
uniform mat3 nm; 
uniform mat3 partNM; 
uniform mat4 modelPart; 
uniform mat4 view; 
uniform mat4 projection; 

void main() { 
    gl_Position = modelPart * vec4(vp, 1.0f); 
    gl_Position = model * gl_Position; 
    gl_Position = view * gl_Position; 
    gl_Position = projection * gl_Position; 

    mat3 normalMatrix = partNM*nm; 
    vec3 normalDirection = normalize(normalMatrix*normal); 
    vec3 lightDirection = normalize(vec3(-1.0, 1.0, -1.0)); 

    vec3 diffuseReflection = clamp(dot(normalDirection, lightDirection),0.0,1.0); 
    fColor = color+diffuseReflection; 
} 

和我的片段着色器:

in vec3 fColor; 
out vec4 frag_colour; 

void main() { 
    frag_colour = vec4(fColor.xyz,1.0); 
} 

这是我用来设置正常的矩阵功能:

void Shader::setNormalMatrix(string name,glm::mat4 matrix) { 
    glm::mat3 nm = glm::transpose(glm::inverse(glm::mat3(matrix))); 
    unsigned int location = glGetUniformLocation(program, name.c_str()); 
    glUniformMatrix3fv(location, 1, false, &nm[0][0]); 
} 

和函数为我的立方体生成顶点和法线:

std::vector<float> Cube::createCube(float size,float x,float y,float z,float r, float g, float b) { 
    VertexType points[8]; 

    points[0].x = (x*size)+0.0f; 
    points[0].y = (y*size)+0.0f; 
    points[0].z = (z*size)+size; 
    points[0].nx = 0.577350; 
    points[0].ny = 0.577350; 
    points[0].nz = -0.577350; 
    points[0].r = r; 
    points[0].g = g; 
    points[0].b = b; 

    points[1].x = (x*size)+size; 
    points[1].y = (y*size)+0.0f; 
    points[1].z = (z*size)+size; 
    points[1].nx = -0.577350; 
    points[1].ny = 0.577350; 
    points[1].nz = -0.577350; 
    points[1].r = r; 
    points[1].g = g; 
    points[1].b = b; 

    points[2].x = (x*size)+size; 
    points[2].y = (y*size)+size; 
    points[2].z = (z*size)+size; 
    points[2].nx = -0.577350; 
    points[2].ny = -0.577350; 
    points[2].nz = -0.577350; 
    points[2].r = r; 
    points[2].g = g; 
    points[2].b = b; 

    points[3].x = (x*size)+0.0f; 
    points[3].y = (y*size)+size; 
    points[3].z = (z*size)+size; 
    points[3].nx = 0.577350; 
    points[3].ny = -0.577350; 
    points[3].nz = -0.577350; 
    points[3].r = r; 
    points[3].g = g; 
    points[3].b = b; 

    points[4].x = (x*size)+0.0f; 
    points[4].y = (y*size)+0.0f; 
    points[4].z = (z*size)+0.0f; 
    points[4].nx = 0.577350; 
    points[4].ny = 0.577350; 
    points[4].nz = 0.577350; 
    points[4].r = r; 
    points[4].g = g; 
    points[4].b = b; 

    points[5].x = (x*size)+size; 
    points[5].y = (y*size)+0.0f; 
    points[5].z = (z*size)+0.0f; 
    points[5].nx = -0.577350; 
    points[5].ny = 0.577350; 
    points[5].nz = 0.577350; 
    points[5].r = r; 
    points[5].g = g; 
    points[5].b = b; 

    points[6].x = (x*size)+size; 
    points[6].y = (y*size)+size; 
    points[6].z = (z*size)+0.0f; 
    points[6].nx = -0.577350; 
    points[6].ny = -0.577350; 
    points[6].nz = 0.577350; 
    points[6].r = r; 
    points[6].g = g; 
    points[6].b = b; 

    points[7].x = (x*size)+0.0f; 
    points[7].y = (y*size)+size; 
    points[7].z = (z*size)+0.0f; 
    points[7].nx = 0.577350; 
    points[7].ny = -0.577350; 
    points[7].nz = 0.577350; 
    points[7].r = r; 
    points[7].g = g; 
    points[7].b = b; 
    std::vector<float> rPoint; 
    for(VertexType p:points) { 
     rPoint.push_back(p.x); 
     rPoint.push_back(p.y); 
     rPoint.push_back(p.z); 
     rPoint.push_back(p.r); 
     rPoint.push_back(p.g); 
     rPoint.push_back(p.b); 
     rPoint.push_back(p.nx); 
     rPoint.push_back(p.ny); 
     rPoint.push_back(p.nz); 
    } 
    return rPoint; 
} 

模型被分成几部分,这就是为什么我有两个正态和模型矩阵;一个用于整个模型,另一个用于模型的单个部分。我的代码有问题吗,还是需要使用per-fragment lighting来修复此错误?

+0

你的'#版本'指令在哪里? – genpfault 2013-03-24 23:51:52

+0

我已经解决了这个问题。我没有版本指令。我会假设我正在使用glsl的opengl 4版本。 – jbills 2013-03-25 01:33:13

回答

3

你的问题是你的网格的拓扑结构。在一个立方体的角落里,3个面相遇。每个面都有不同的法线。这会在法线的拓扑结构中产生不连续性。或者把它放在更简单的条件。每个角必须使用3个顶点,每个面使用一个顶点,并且面正常指向正确的方向。

虽然你在它,你可以删除这些立方体面无法看到。

+0

我已经删除索引级别的不可见面,我希望避免使用重复的顶点。 – jbills 2013-03-24 17:59:36

+1

@jbills:它们不是重复的顶点。这是一个常见的误解,即顶点等于位置。但是一个顶点是整个位置,法线,颜色,纹理坐标等。如果你改变了顶点属性中的一个,你就有了一个完全不同的顶点。所以对于不同的法线,你有不同的顶点,因此不会有重复。 – datenwolf 2013-03-24 19:22:42

+0

感谢您的澄清,我会记住这一点! – jbills 2013-03-24 19:48:41

0

原因是因为您将每个立方体渲染为单独的模型。因此着色器每个模型运行一次,在您的情况下运行一次,每个立方体运行一次。为了解决这个问题,你需要将整个模型(你的机器人)渲染为一个模型,并带有一组顶点,而不是一组立方体。

+0

即使机器人呈现为一束立方体,也不会改变结果。 – datenwolf 2013-03-24 17:56:04

+0

我将它渲染为一堆顶点。立方体创建函数输出顶点,然后将其与其他立方体的顶点连接起来。 – jbills 2013-03-24 17:58:26