Решена проблема с затенением;линии сетки сохраняются.См. Обновление 5
Я работаю над загрузчиком файлов .obj для OpenGL, используя Objective-C.
Я пытаюсь загрузить объекты и отобразить их с затенением.Я не использую никаких текстур, материалов и т. Д. Для модификации модели, кроме одного источника света.При рендеринге любой модели затенение распределяется неправильно (как показано на рисунках ниже).Я верю, что это как-то связано с нормой, но я не уверен.
Вот мои результаты:
И вот тип эффекта, который я пытаюсь достичь:
Я думал, что проблема в том, что нормальные значения, которые я проанализировал из файла, были неправильными, но после их вычисления и получения тех же результатов я обнаружил, что это не так.Я также думал, что проблема не в том, чтобы включить GL_SMOOTH
, но я тоже ошибался.
Так что я понятия не имею, что я делаю здесь неправильно, извините, если вопрос кажется расплывчатым.Если потребуется дополнительная информация, я добавлю ее.
Обновление: ссылка на увеличенное изображение сломанной головы обезьяны: http://oi52.tinypic.com/2re5y69.jpg
Обновление 2: Если в процессе вычисления нормалей произошла ошибка, это то, что я делаю:
- Создайте треугольник для каждой группы индексов.
- Рассчитайте нормали для треугольника и сохраните его в векторе.
- Убедитесь, что вектор нормализован с помощью следующей функции
:
static inline void normalizeVector(Vector3f *vector) {
GLfloat vecMag = VectorMagnitude(*vector);
if (vecMag == 0.0) {
vector->x /= 1.0;
vector->y /= 0.0;
vector->z /= 0.0;
}
vector->x /= vecMag;
vector->y /= vecMag;
vector->z /= vecMag;
}
Обновление 3: вот код, который я использую для создания нормали:
- (void)calculateNormals {
for (int i = 0; i < numOfIndices; i += 3) {
Triangle triangle;
triangle.v1.x = modelData.vertices[modelData.indices[i]*3];
triangle.v1.y = modelData.vertices[modelData.indices[i]*3+1];
triangle.v1.z = modelData.vertices[modelData.indices[i]*3+2];
triangle.v2.x = modelData.vertices[modelData.indices[i+1]*3];
triangle.v2.y = modelData.vertices[modelData.indices[i+1]*3+1];
triangle.v2.z = modelData.vertices[modelData.indices[i+1]*3+2];
triangle.v3.x = modelData.vertices[modelData.indices[i+2]*3];
triangle.v3.y = modelData.vertices[modelData.indices[i+2]*3+1];
triangle.v3.z = modelData.vertices[modelData.indices[i+2]*3+2];
Vector3f normals = calculateNormal(triangle);
normalizeVector(&normals);
modelData.normals[modelData.surfaceNormals[i]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i]*3+2] = normals.z;
modelData.normals[modelData.surfaceNormals[i+1]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i+1]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i+1]*3+2] = normals.z;
modelData.normals[modelData.surfaceNormals[i+2]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i+2]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i+2]*3+2] = normals.z;
}
Обновление 4: если посмотреть дальше, кажется, что нормали файла .obj являются поверхностными нормалями, а мне нужны вершинные нормали.(Может быть)
Если бы нормали вершин - это то, что мне нужно, если кто-нибудь сможет объяснить теорию их расчета, это было бы здорово.Я пытался найти его, но я нашел только примеры, а не теорию.(например, «получить перекрестное произведение каждого лица и нормализовать его»).Если я знаю, что мне нужно делать, я могу посмотреть на отдельный процесс, если застряну и не буду постоянно обновлять это.
Обновление 5: я переписал весь свой загрузчик и каким-то образом заставил его работать.Несмотря на то, что он затеняет должным образом, у меня все еще есть те линии сетки, которые вы можете видеть на моих исходных результатах.