GLSL передает обозначенные нормали шейдеру

Я сгенерировал модель (Suzie) в blender и экспортировал ее в файл .obj с нормалями. Во время режима загрузки в мое приложение я заметил, что число вершин и нормалей различно (2012 и 1967).

Детали модели

Я пытаюсь реализовать простое затенение клеток. Проблема в передаче нормалей в шейдеры. Для хранения данных вершин я использую векторы из glm.

std::vector<unsigned int> face_indices;
std::vector<unsigned int> normal_indices;
std::vector<glm::vec3> geometry;
std::vector<glm::vec3> normals;

Результат у меня так далеко

Неверные нормы

Расположение буферов

    glBindVertexArray(VAO);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, geometry.size() * sizeof(glm::vec3), &geometry[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, NormalVBOID);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VIndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.size() * sizeof(unsigned int), &face_indices[0], GL_DYNAMIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

Фрагмент рендеринга

    glBindVertexArray(VAO);

glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
glDrawElements(GL_QUADS, face_indices.size(), GL_UNSIGNED_INT, (void*)0);

glBindVertexArray(0);

0

Решение

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

geometry.clear();
normals.clear();

geometry.resize(vv.size());
normals.resize(vv.size());

for (unsigned int i = 0; i < face_indices.size(); i++)
{
int vi = face_indices[i];
int ni = normal_indices[i];
glm::vec3 v = vv [vi];
glm::vec3 n = vn [ni];
geometry[vi] = v ;
normals[vi]  = n ;
indices.push_back(vi);
}
1

Другие решения

Вам также следует помнить, что использование модификатора сглаживания в Blender перед экспортом в некоторых случаях поможет гарантировать, что у вас есть 1 нормаль на вершину (вам может потребоваться или не нужно также устанавливать нормальный вид для каждого вертикала вместо нормального вида для лица. .. не могу, так что вам придется проверить). Это потому, что по умолчанию Blender использует индивидуальные нормали. Гладкий модификатор (меню горячих клавиш «w»)
переключит его на нормы для каждой вершины. Затем, когда вы экспортируете, вы экспортируете верты и нормы как обычно, и число должно совпадать. Это не всегда, но это работало на меня в прошлом.
Это может означать меньше ненужных манипуляций с вашими данными во время импорта.

0

По вопросам рекламы [email protected]