2013-03-24 6 views
0

저는 꼭지점이 8 개인 큐브로 만들어진 모델을 가지고 있으며, 정점 방향 별 조명과 관련된 문제가 있습니다. 한 번에 전체 모델이 켜지는 대신 각 큐브는 this처럼 별도로 켜져있는 것처럼 보입니다.OpenGL에서 정점 별 조명 문제가 발생했습니다.

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; 
} 

내 프래그먼트 쉐이더 : 이것은 I가 정규 행렬 설정하기 위해 사용하는 함수

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; 
} 

모델이 여러 부분으로 나뉘어져 있습니다. 따라서 두 개의 일반 모델과 모델 행렬이 있습니다. 하나는 모델 전체, 하나는 모델 개별 조각을 나타냅니다. 코드에 문제가 있습니까? 아니면이 버그를 해결하기 위해 조각 별 조명을 사용해야합니까?

+0

'# version' 지시어는 어디에 있습니까? – genpfault

+0

문제가 해결되었습니다. 나는 버전 지시어가 없다. 내가 glsl의 OpenGL 4 버전을 사용하고 있다고 가정합니다. – jbills

답변

3

문제는 메시의 토폴로지입니다. 입방체의 모서리에서 3 개의 얼굴이 만난다. 이면들의 각각은 다른 법선을 가지고 있습니다. 이것은 정상의 토폴로지에서 불연속성을 만듭니다. 또는 더 간단한 용어로 넣으십시오. 모서리 당 3 개의 꼭지점을 사용해야합니다. 각 꼭지점은 올바른 방향을 향한 법선이됩니다.

그리고 그 동안, 어쨌든 보이지 않는 큐브면을 제거 할 수 있습니다.

+0

인덱스 수준에서 보이지 않는 얼굴을 이미 제거 했으므로 중복 된 정점 사용을 피하기를 희망했습니다. – jbills

+1

@jbills : 중복 된 정점이 아닙니다. 정점이 위치와 같다고하는 것은 일반적인 오해입니다. 하지만 정점은 위치, 법선, 색상, 텍스처 좌표 등의 전체 집합입니다. 하나의 정점 속성을 변경하면 완전히 다른 정점을 갖게됩니다. 따라서 다른 법선을 사용하면 정점이 다르기 때문에 중복이 없습니다. – datenwolf

+0

설명 주셔서 감사합니다, 나는 이것을 기억합니다! – jbills

0

이유는 각 큐브를 별도의 모델로 렌더링하기 때문입니다. 따라서 쉐이더는 한 모델 당 한 번 (경우에 따라 큐브 당 한 번) 실행됩니다. 이를 해결하려면 전체 모델 (로봇)을 큐브 집합이 아닌 하나의 정점 세트로 하나의 모델로 렌더링해야합니다.

+0

로봇을 단일 큐브로 렌더링하더라도 결과가 변경되지는 않습니다. – datenwolf

+0

하나의 정점으로 렌더링하고 있습니다. 큐브 생성 기능은 정점을 출력 한 다음 다른 정육면체의 정점과 연결합니다. – jbills