2015-07-14 3 views
0

Я пытаюсь написать программу, которая загружает файлы .obj. По какой-то причине моя модель только загорается с неправильно рассчитанными нормальными векторами. Я не смог найти что-либо в Интернете, объясняющее эту аномалию.OpenGL .obj Loader: модель только правильно горит с неправильными нормальными векторами?

Вот как я рассчитываю нормали, которые, как я считаю, являются правильным способом.

vector<float> Vertex::findNormal(Vertex v2, Vertex v3) 
{ 
    float va[3], vb[3], vr[3], val; 
    /* Calculate 1st Vector */ 
    va[0] = v2.getX() - x; 
    va[1] = v2.getY() - y; 
    va[2] = v2.getZ() - z; 
    /* Calculate 2nd Vector */ 
    vb[0] = v3.getX() - v2.getX(); 
    vb[1] = v3.getY() - v2.getY(); 
    vb[2] = v3.getZ() - v2.getZ(); 

    /* Cross Product */ 
    vr[0] = va[1] * vb[2] - vb[1] * va[2]; 
    vr[1] = vb[0] * va[2] - va[0] * vb[2]; 
    vr[2] = va[0] * vb[1] - vb[0] * va[1]; 

    /* Normalization Factor */ 
    val = sqrt(vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2]); 

    normal.push_back(vr[0]/val); 
    normal.push_back(vr[1]/val); 
    normal.push_back(vr[2]/val); 

    return normal; 
} 

Но это результат: Correct Normals

Angel набор данных любезно прописные буквы Berkeley Computer Animation and Modeling Group.

(не позволит мне добавлять изображения, потому что < 10 репутации)

Если переключить направление одного из векторов, как:

/* Calculate 1st Vector */ 
    va[0] = x - v2.getX(); 
    va[1] = y - v2.getY(); 
    va[2] = z - v2.getZ(); 

Затем он делает правильно:

Incorrect Normals

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

Я попытался переломить обмотку через,

glFrontFace(GL_CW); 

Я модульное тестирование коды для обеспечения вершина считывается в противофазе по часовой стрелке из файла, я сделал бесчисленные изменения в настройки освещения безрезультатно.

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

+0

Восстановить эти изображения на стек.imgur. – genpfault

ответ

2

Проблема в том, как вы вычисляете векторы a и b. Посмотрите на это изображение показывая правой руки правило:

enter image description here

векторы а и Ь и происходят из одной и той же точки и указывают в разных направлениях. Вектор b не начинается с кончика вектора a.

Однако в вашем коде это как будто основание среднего пальца (вектор b) начинается с кончика указательного пальца (вектор a), потому что вы идете вокруг треугольника, а не выбираете два вектора, исходящих из такая же вершина. Это эквивалентно использование кончика вектор а в качестве общей вершины, но с вектором указательного неправильным путем

Изображения треугольника накладывается на изображении с часовым номером вершиной:

enter image description here

(Вы мог бы подсчитать вершины тремя разными способами, но я выбрал нумерацию, соответствующую рабочей версии вашего кода.)

Чтобы получить вектор а, который идет от вершины 2 до вершины 1, вычесть вершину 2 из вершины 1:

/* Calculate 1st Vector */ 
va[0] = x - v2.getX(); 
va[1] = y - v2.getY(); 
va[2] = z - v2.getZ(); 

Для того, чтобы получить вектор Ь, который идет от вершины 2 к вершине 3, вычесть вершину 2 от вершины 3:

/* Calculate 2nd Vector */ 
vb[0] = v3.getX() - v2.getX(); 
vb[1] = v3.getY() - v2.getY(); 
vb[2] = v3.getZ() - v2.getZ(); 
+0

Получил, спасибо !!!!! – kadie16

Смежные вопросы