Маленькая проблема при вычислении нормалей вершин (OpenGL ES) - PullRequest
4 голосов
/ 13 апреля 2011

У меня небольшая проблема с нормальной вершиной.

Результат кажется немного странным. Сначала посмотрите на изображения:

Оригинальная модель в программном обеспечении 3D.

http://img233.imageshack.us/img233/4421/screenshot20110412at707.png

Освещение по фрагментам с сеткой, импортированной непосредственно из файла OBJ (с использованием нормалей из файла).

http://img97.imageshack.us/img97/2960/screenshot20110412at708.png

Фрагментное освещение, вычисление нормалей по моей собственной рутине.

http://img508.imageshack.us/img508/2960/screenshot20110412at708.png

Вы заметили? С помощью нормалей из файла OBJ все ок. Но когда я использую свою собственную процедуру для вычисления нормалей на основе вершин, что-то кажется неправильным.

Нормы кажутся странными именно тогда, когда Z становится отрицательным (используя правую ориентацию). В других частях объекта все в порядке, но только одна воображаемая линия поперек сетки кажется странной. Эта проблема сохраняется на других сетках, всегда в одном и том же месте, Z = 0.

Моя процедура вычисления нормалей - та, которую все знают, предполагая треугольник с вершинами ABC:

vec3 normal = normalize(cross(C - A, B - A));

И затем добавление нормального результата в уже рассчитанный нормальный буфер.

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

Вы видели это раньше? Вы знаете, как это решить?

Вот код:


// Looping at each triangle
        vec3 distBA = vec3Subtract(vB, vA);
        vec3 distCA = vec3Subtract(vC, vA);

        vec3 normal = vec3Cross(distBA, distCA);

        // Each normalBuffer represents one vertex.
        normalBuffer[i1] = vec3Add(normal, normalBuffer[i1]);
        normalBuffer[i2] = vec3Add(normal, normalBuffer[i2]);
        normalBuffer[i3] = vec3Add(normal, normalBuffer[i3]);


// After pass through all faces/triangles.


// Looping at each Vertex structure.
        normal = vec3Normalize(normalBuffer[i]);

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 14 апреля 2011

В зависимости от того, как вы вычисляете освещение фрагмента (то есть, если вы зажимаете свой точечный продукт в диапазоне 0-1 или нет), то, что вы видите, может быть просто проблемой инвертированных нормалей. В зависимости от того, как вы выберите A, B, C, нормаль к вершине может указывать в любом направлении. Чтобы различить внешнюю и внутреннюю части треугольника, вам обычно требуется дополнительная информация, например, обмотка вершин. Вы принимаете это во внимание?

0 голосов
/ 13 апреля 2011

Вы нормализуете результат «И затем добавляете нормальный результат в уже рассчитанный нормальный буфер». Я не уверен, что нужно, но добавить его не помешает. И пока вы на это, проверьте на NaN и бесконечность.

Проверяете ли вы в своей функции нормализации, если длина входящего вектора больше 0?

У меня есть подозрение, что у вас есть неприятная ошибка где-то в вашей векторной библиотеке, тем более что проблема возникает только для оси Z.

...