Нахождение нормального OpenGL - PullRequest
3 голосов
/ 06 января 2011

Я хотел бы знать, можем ли мы получить нормаль на поверхности объекта из координат окна. Функция gluUnProject () преобразует координаты окна в координаты объекта в трехмерном пространстве. Кроме того, мне нужна функция, которая дает нормаль поверхности, на которой лежит мой указатель мыши. Я был бы более чем счастлив, если бы у нас была функция opengl, которая может это дать. Я не хотел бы делать это с пересечением луча и объектов (поверхностных треугольников).

Ответы [ 4 ]

2 голосов
/ 06 января 2011

Я не думаю, что это возможно.Зачем opengl хранить все нормали для всех пикселей?Это не нужно, так что вряд ли вы сможете получить его.Боюсь, это будет непросто.

Вы можете написать шейдер, который рисует нормали, закодированные как rgb, вместо цвета лица.Если вы перерисовываете сцену с включенным шейдером, она прорисует все нормали.Затем вы можете просто найти цвета, где вы хотите, и получить нормальный.

1 голос
/ 06 января 2011

Первое пояснение: gluUnProject выполняет обратную проекцию конвейера с фиксированными функциями OpenGL.Если задействованы шейдеры, все усложняется.Однако в качестве отправной точки для gluUnProject обычно получают значение буфера глубины в нужной позиции (используя glReadPixels).Это тривиально, прочитать весь блок (скажем, массив 3х3) значений глубины и отменить их проецирование, оставляя вас с 9 точками, одна из которых находится в центре.Использование точек влево и вверх уже даст вам действительный нормальный (поэтому теоретически будет достаточно массива 2x2), но давайте отфильтруем его, учитывая всю окрестность.

Давайте их нумероватьтаким образом, в соответствии с массивом, из которого они получены:

1 8 7
2 0 6
3 4 5

Все, что вам нужно сделать, это вычислить нормали плоскости, определяющей треугольники (0,1,2), (0,2,3),… (0,7,8), (0,8,1) берут (возможно, взвешенная величина, обратная расстоянию выборки) сумму нормалей и нормализуем результирующий вектор.Вуаля, вы определили нормальное мировое пространство для выбранной точки.Чтобы вернуться в пространство объектов, умножьте на транспонированную инверсию матрицы объекта (почему транспонированная обратная, нормаль скважины преобразуется путем обратной транспонирования матрицы вида модели, см. Приложение к руководству по программированию OpenGL для объяснения причин и обратное).это ... ну, я думаю, ты это понял).

0 голосов
/ 29 сентября 2012

Есть пара способов, которыми я мог бы подумать сделать это.

Возможность 1

Пользователь щелкает в окне окна, поэтому теперь у вас есть координаты окна щелчка мыши (x, y). Теперь добавьте один пиксель в направлении X (x + 1 / width, y) и один пиксель в направлении y (x, y + 1 / height), где width и height - это размеры в пикселях дисплея. используйте gluUnProject для всех трех этих векторов, тогда у вас есть три точки в пространстве объектов {A, B, C}. Если у вас есть три точки в пространстве объектов, обычный расчет относительно прост:

A = ObjectCoordinates(x+1/width, y)
B = ObjectCoordinates(x, y)
C = ObjectCoordinates(x, y+1/height)
BA = (A-B)/|A-B|
BC = (C-B)/|C-B|
N = BA cross BC

где | X | это величина вектора X и нормаль N

Это может быть не быстро, и у него будут проблемы, когда A, B и C не все приземляются в одном и том же треугольнике (это может произойти, если вы нажимаете на объект, который действительно далеко). Но он должен получить хороший приблизительный результат.

Возможность 2

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

При первом проходе ваш вершинный шейдер пройдет вершину, нормальную к вашему фрагментному шейдеру. Затем вы назначаете цвет фрагмента (r, g, b) нормальным координатам, переданным из вашего вершинного шейдера (x, y, z). Затем ваш первый проход будет визуализироваться с использованием этих шейдеров. Ваш второй проход будет визуализироваться в буфер кадров. Когда пользователь щелкает, вы получаете набор координат пространства окна, которые вы конвертируете в (u, v) координаты текстуры для выборки из текстуры, созданной при первом проходе рендеринга.

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

Здесь - немного устаревшая, но бесплатная книга по GLSL - языку шейдеров OpenGL, в котором описывается, как вы собираетесь собрать вместе некоторые из этих шейдеров.

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

Здесь - псевдокод для вычисления нормали.

Ура, Ned

0 голосов
/ 06 января 2011

Математика не сложная, если у вас есть три балла. Я бы посоветовал взглянуть на примеры кода OpenGL Super Bible 4 * Macintosh Windows . Math3d. * В общем каталоге дает вам код для этого, найдите m3dFindNormal.

Что касается хранения нормалей, это будет зависеть от вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...