2013-03-24 26 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