Определение вверх в матрице просмотра Direct3D, когда камера постоянно движется
В моем приложении Direct3D камеру можно перемещать с помощью мыши или клавиш со стрелками. Но если я жестко закодировать (0,1,0) в качестве вектора направления вверх в LookAtLH
, рамка гаснет при некоторых ориентациях камеры.
Я только что усвоил сложный способ, что при взгляде вдоль оси Y (0,1,0) больше не работает как направление вверх (кажется очевидным?). Я думаю о переключении моего направления вверх на что-то другое для каждого из этих особых случаев. Есть ли более изящный способ справиться с этим?
2 ответа
Предполагая, что вы можете рассчитать вектор, указывающий вперед (то, на что вы смотрите - вашу позицию) и вектор, указывающий вправо (всегда на плоскости XZ, если вы не можете катиться). Нормализуйте оба этих вектора, затем вверх вперед x вправо (где x - перекрестное произведение).
В общем, вы можете подключить свое отклонение, наклон и поворот в матрицу вращения и вращать векторы осей, чтобы двигаться вправо, вверх и вперед, но я полагаю, что именно этого вы и используете LookAtLH, чтобы избежать.
Изящный способ справиться с этим - использовать кватернионы юнитов. Кватернион - это вектор из 4 значений, который кодирует ориентацию в трехмерном пространстве (а не вращение, как утверждают некоторые статьи), а единичный кватернион - это тот, где длина вектора sqrt(x^2+y^2+z^2+w^2) составляет 1,0. Существует ряд математических операций для работы с кватернионами, которые аналогичны использованию матриц для кодирования вращений, с дополнительным бонусом, заключающимся в том, что кватернионы никогда не могут представлять вырожденную ориентацию. Вы можете свободно конвертировать кватернионы в матрицу 3x3 или 4x4, когда вам нужно передать результат в графический процессор.
Ваша проблема в том, что пока вы перемещаете камеру, вы вносите небольшой поворот в направлении вверх камеры. Вынуждая камеру заново центрироваться на векторе (0,1,0) на каждой итерации, вы фактически вращаете камеру, а затем фиксируете ориентацию камеры, чтобы она оставалась на поверхности сферы, но когда ваша камера ударяется о На полюсе этой сферы нет хорошего направления, чтобы называть "вверх", и ваша матрица идет в единственном числе и дает вам многоугольники нулевого размера (отсюда и черный экран). Кватернионы имеют возможность интерполировать через эти полюса и выходить на другую сторону очень хорошо, оставляя вас с действительной матрицей всегда. все, что вам нужно сделать, это контролировать "поворот".
Чтобы измерить этот поворот, вы должны прочитать статью Кена Шумэйка "Сокращение изгиба волокна" в книге Graphics Gems 4. Он показывает хороший способ измерить этот накопленный поворот и как удалить его, когда он оскорбительный.