Как исправить обратные нормы облака точек? - PullRequest
0 голосов
/ 17 января 2019

У меня есть облако точек и я хочу сгенерировать нормали для каждой точки. На данный момент я попробовал несколько методов. Нормы, которые я сгенерировал, выглядят правильно, но имеют два возможных направления, внутрь или снаружи моделей, и не существует правила консистенции для его контроля. Так есть ли метод, который может генерировать надежные нормали? Спасибо!

Вот эскиз моей проблемы. enter image description here

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Поскольку вопрос помечен тегом point-cloud-library, я представляю решение с использованием PCL .

Перевернуть в направлении точки обзора

PCL имеет функцию flipNormalTowardsViewpoint, в которой вы указываете точку, соответствующую нормаль и точку обзора, к которой нужно перейти.

Точкой обзора обычно является положение камеры в глобальных координатах, но если у вас есть только снимок сцены, тогда точка обзора становится (0,0,0) .

0 голосов
/ 17 января 2019

Учитывая треугольник, определенный его тремя вершинами ABC, вектор, перпендикулярный («нормальный») этому треугольнику, легко получить с помощью перекрестного произведения двух векторов, например, ABxAC. Но также ABxBC.

Дело в том, что перекрестное произведение НЕ коммутативно. Итак, ABxAC - это не то же самое, что ACxAB. Точно это ABxAC = - ACxAB, это тот же вектор, но в противоположном направлении .

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

Вы должны знать, как GL делает порядок намотки в зависимости от типа треугольного примитива

Пример
Допустим, вы используете glDrawArrays (GL_TRIANGLES, ...) и ваш буфер вершин выглядит как v1, v2, v3, v1, v3, v4, v1, v4, v5 и т. Д. (Vi = vix, viy, viz) где все порядки намотки против часовой стрелки. Тогда:

Vector AB = v2 - v1
Vector AC = v3 - v1
Vector perp = cross(AB, AC)
Vector norm = normalize(perp) //divide each component by lenght of perp


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

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

...