2016-03-25 1 views
1

Я пытаюсь реализовать диффузное освещение с помощью OpenGL. Я отлаживал шейдер фрагмента для куба и обнаружил, что нормальный вектор всегда (0,0,0), хотя я указываю нормали в своих данных вершин и включаю атрибут вершины.Почему атрибут вершины для нормального вектора не работает?

Соответствующий код OpenGL:

GLfloat vertices[] = { 
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 

-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 

-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 

0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 

-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 

-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f 
}; 

GLuint VBO, boxVAO; 
glGenVertexArrays(1, &boxVAO); 
glGenBuffers(1, &VBO); 

glBindVertexArray(boxVAO); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); 
glEnableVertexAttribArray(1); 
glBindVertexArray(0); 

Vertex Shader:

#version 330 core 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 normal; 
out vec3 FragPos; 
out vec3 outNormal; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 proj; 

void main() 
{ 
    gl_Position = proj * view * model * vec4(position, 1.0); 
    FragPos = vec3(model * vec4(position, 1.0f)); 
    outNormal = vec3(normal); 
} 

Фрагмент Shader:

#version 330 core 
in vec3 FragPos; 
in vec3 outNormal; 
out vec4 color; 

uniform vec3 objectColor; 
uniform vec3 lightColor; 
uniform vec3 lightPos; 

void main() 
{ 
    float ambientIntensity = 0.5f; 
    vec3 ambientColor = ambientIntensity * lightColor; 

    vec3 norm = normalize(outNormal); 
    vec3 lightDir = normalize(lightPos - FragPos); 
    float diffuse = max(dot(norm, lightDir), 0.0); 
    vec3 diffuseColor = diffuse * lightColor; 

    vec3 resultColor = (ambientColor + diffuseColor) * objectColor; 
    color = vec4(resultColor, 1.0f); 
} 

Выход: (показывает только окружающее освещение, не диффузный)

enter image description here

Кроме того, не уверен, если это помогает на всех, но делать что-то странное, как установку нормальным, как положение фрагментов дает этот результат: enter image description here

Так что, похоже, как нормали следует производить рассеянный свет, но каким-то образом не загружаются в шейдер правильно. Есть идеи?

Это код, который я использовал для отладки шейдеров:

// debug testing 
vec3 test = vec3(outNormal.xyz); 
bvec3 ln = lessThan(test, vec3(0,0,0)); 
if (ln[2]){ 
    color = vec4(1.0, 0.0, 0.0, 1.0); 
}else{ 
    color = vec4(0.0, 1.0, 0.0, 1.0); 
} 
+0

Каково положение света на этом изображении? Весь ваш код * как есть * выглядит правильно, что заставляет меня поверить, что есть проблема с тем, как вы позиционировали свет или кубы, что также объясняет, почему кормить странные ценности, поскольку ваши нормали вызывают нечетные результаты. – Xirema

+0

Свет находится на (1.2, 1.0, 2.0), а основной куб - на (0,0,0). Таким образом, на изображении выше свет ближе к камере, чем куб, поэтому рассеянный свет должен быть виден на снимке экрана. –

+0

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

ответ

0

Oops! Оказывается, когда я создал свет VAO, я использовал те же вершины, но использовал только первые три значения каждой вершины для позиции (что правильно для света). Но я случайно использовал это VAO для рисования куба вместо VAO, показанного в приведенном выше коде. Не могу поверить, что я этого не понимал. Во всяком случае, код здесь правильный.

Мир.