2017-08-07 38 views
-2

我試圖渲染使用攪拌機的exported.obj文件的立方體但照明看起來是錯誤的。故障使用OpenGL的obj法線時

我想這是因爲我的頂點數組包含8個值,但法線數組只有6

我無法理解的OpenGL是如何使用這個指數的數組。這對我來說有點魔力。

任何人都可以幫助我嗎?

這是文件:

v -1.000000 -1.000000 1.000000 
v -1.000000 -1.000000 -1.000000 
v 1.000000 -1.000000 -1.000000 
v 1.000000 -1.000000 1.000000 
v -1.000000 1.000000 0.999999 
v -0.999999 1.000000 -1.000001 
v 1.000000 1.000000 -1.000000 
v 1.000000 1.000000 1.000000 

vn 0.0000 -1.0000 0.0000 
vn 0.0000 1.0000 -0.0000 
vn -1.0000 -0.0000 0.0000 
vn 0.0000 -0.0000 -1.0000 
vn 1.0000 -0.0000 0.0000 
vn -0.0000 0.0000 1.0000 

f 2//1 4//1 1//1 
f 8//2 6//2 5//2 
f 5//3 2//3 1//3 
f 6//4 3//4 2//4 
f 3//5 8//5 4//5 
f 1//6 8//6 5//6 
f 2//1 3//1 4//1 
f 8//2 7//2 6//2 
f 5//3 6//3 2//3 
f 6//4 7//4 3//4 
f 3//5 7//5 8//5 
f 1//6 4//6 8//6 

這是我的代碼:

GLuint cubeVAO, cubeVerticesVBO, cubeColorsVBO, cubeNormalsVBO, cubeIndicesVBO; 
glGenVertexArrays(1, &cubeVAO); 
glBindVertexArray(cubeVAO); 


glGenBuffers(1, &cubeVerticesVBO); 
glBindBuffer(GL_ARRAY_BUFFER, cubeVerticesVBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(0); 

glGenBuffers(1, &cubeColorsVBO); 
glBindBuffer(GL_ARRAY_BUFFER, cubeColorsVBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(1); 

glGenBuffers(1, &cubeNormalsVBO); 
glBindBuffer(GL_ARRAY_BUFFER, cubeNormalsVBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normals), cube_normals, GL_STATIC_DRAW); 
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(2); 

glGenBuffers(1, &cubeIndicesVBO); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIndicesVBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_indices), cube_indices, GL_STATIC_DRAW); 
glBindVertexArray(cubeVAO); 

cubeShader.use(); 
glm::mat4 model; 
cubeShader.setMat4("model", model); 
cubeShader.setMat4("view", view); 
cubeShader.setMat4("projection", projection); 
cubeShader.setVec3("lampColor", lampColor); 
cubeShader.setVec3("lampPos", lampPos); 
cubeShader.setVec3("viewPos", viewPos); 
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); 

的Vertex Shader

#version 330 core 

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

out vec3 Color; 
out vec3 Normal; 
out vec3 FragPos; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    vec4 posv4 = vec4(position, 1.0f); 
    Color = color; 
    FragPos = vec3(model * posv4); 
    Normal = normal; 
    gl_Position = projection*view*model*posv4; 
} 

片段着色器:

#version 330 core 

in vec3 Color; 
in vec3 Normal; 
in vec3 FragPos; 

out vec4 FragColor; 

uniform vec3 lampColor; 
uniform vec3 lampPos; 
uniform vec3 viewPos; 

void main() 
{ 
    // ambient 
    float ambientStrength = 0.1; 
    vec3 ambient = ambientStrength * lampColor; 

    // diffuse 
    vec3 norm = normalize(Normal); 
    vec3 lightDir = normalize(lampPos - FragPos); 
    float diff = max(dot(norm, lightDir), 0.0); 
    vec3 diffuse = diff * lampColor; 

    // specular 
    float specularStrength = 0.5; 
    vec3 viewDir = normalize(viewPos - FragPos); 
    vec3 reflectDir = reflect(-lightDir, norm); 
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 
    vec3 specular = specularStrength * spec * lampColor; 

    vec3 result = (ambient + diffuse + specular) * Color; 
    FragColor = vec4(result, 1.0); 
} 

怎麼了? , - ,

示範視頻: https://vid.me/vy17h

回答

1

你必須擴大在OBJ文件中的數據。 OpenGL的預計爲每個頂點中指定一個正常的,個別地。在OBJ文件中,頂點和法線分開處理。你需要做的是找到獨特的頂點+正常組合,將它和索引存儲到新的頂點+正常數組中,而不是使用單獨的索引。

使用現代OpenGL,通過使用頂點着色器紋理獲取,將頂點數據存儲在紋理中,可以對每個頂點屬性使用不同的索引。但是這帶來了性能問題。

1

法線陣列僅具有6個值,因爲立方體具有6個面和已創建,其中每個面具有在相同的方向上指向的角部4點的法線(一個模型即相同) - 這解釋了照明不是你期待的。

OBJ文件使用索引以便它可以分配這些6個獨特的價值觀之一,每個8個頂點