Я пытаюсь реализовать диффузное освещение с помощью 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);
}
Выход: (показывает только окружающее освещение, не диффузный)
Кроме того, не уверен, если это помогает на всех, но делать что-то странное, как установку нормальным, как положение фрагментов дает этот результат:
Так что, похоже, как нормали следует производить рассеянный свет, но каким-то образом не загружаются в шейдер правильно. Есть идеи?
Это код, который я использовал для отладки шейдеров:
// 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);
}
Каково положение света на этом изображении? Весь ваш код * как есть * выглядит правильно, что заставляет меня поверить, что есть проблема с тем, как вы позиционировали свет или кубы, что также объясняет, почему кормить странные ценности, поскольку ваши нормали вызывают нечетные результаты. – Xirema
Свет находится на (1.2, 1.0, 2.0), а основной куб - на (0,0,0). Таким образом, на изображении выше свет ближе к камере, чем куб, поэтому рассеянный свет должен быть виден на снимке экрана. –
Просто, чтобы уточнить, маленький куб света представляет свет и использует разные шейдеры, которые не должны иметь отношение к этой проблеме. Он просто используется для отображения положения источника света. –