Directx 3d почему переворачивается матрица просмотра экрана

от admin

Почему DirectX использует перевернутую ось Y?

Я сохраняю свои управляемые координаты X / Y, а затем использую функцию, которая преобразует координаты в метры и добавляю 1280 к каждой точке (чтобы она хорошо вписывалась в изображение 2560×2560), а затем рисую многоугольник между « точками » , в результате получилась своего рода гоночная линия. Но как только я сгенерировал многоугольник и сохранил его как изображение, он каким-то образом переворачивается по вертикали. Если повернуть изображение по вертикали, оно будет идеально соответствовать растровым изображениям дорожек. Мне сказали, что это связано с тем, что DirectX внутренне перевернул ось Y. Почему DirectX использует перевернутую ось Y?

1 ответ

Вопрос в том, есть ли в DirectX перевернутая ось Y или изображение?

DirectX использует систему координат 3D / 4D, в которой ось X указывает вправо, а ось Y указывает вверх, когда преобразование не применяется. Это связано с тем, что экран (где ось Y направлена ​​вниз) является последним экземпляром, который должен обработать изображение. Каждый предыдущий шаг использует систему координат с направленной вверх осью Y. Поскольку Direct3D разработан для трехмерных миров, система координат, которая выровнена, как мир, и как большинство систем координат в математике, намного удобнее для программиста и дизайнера. Представьте, вы создали бы 3D-модель. Разве это не было бы странно, если бы вы спроектировали его так, чтобы ось Y была направлена ​​вниз?

Когда у вас вообще нет трансформации, которая позволяла бы перспективу и т. Д., У вас одна и та же система координат. Игнорируя ось Z, верхний левый угол равен (-1 | 1), нижний правый угол равен (1, -1). Это равно системным координатам, используемым, например, в математика. В конце концов, эта система координат трансформируется с окном просмотра, в результате верхний левый угол будет (0 | 0), а нижний правый угол будет (ResolutionX | ResolutionY).

В общем, причина, по которой ось Y направлена ​​вверх, заключается в том, что основная цель Direct3D — описывать миры удобным способом независимо от физических атрибутов экрана.

Неожиданный результат при отмене проецирования координат экрана в DirectX

Чтобы определить, щелкнул ли пользователь какой-либо из моих 3D-объектов, я пытаюсь превратить координаты экрана щелчка в вектор, который затем я использую, чтобы проверить, попал ли какой-либо из моих треугольников. Для этого я использую метод XMVector3Unproject, предоставляемый DirectX и Im, реализующий все в С++/CX.

Проблема, с которой сталкивается Im, заключается в том, что вектор, являющийся результатом непроектирования экранных координат, вовсе не таков, как я ожидаю. На следующем рисунке показано следующее:

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

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

Изображение 38049Таким образом, как видно из приведенного выше изображения, все векторы, по-видимому, происходят из одного и того же местоположения. Если я изменяю представление и повторяю процесс, то появляется тот же шаблон, но с другим источником векторов.

Изображение 38050

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

Метод «SelectObject» выглядит следующим образом:

В конечном итоге вычисляемый вектор используется методом Intersects пространства имен DirectX:: TriangleTests, чтобы определить, попал ли треугольник. Ive опустил код в приведенном выше фрагменте, потому что он не имеет отношения к этой проблеме.

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

Матрица представления вычисляется следующим образом (на основе примера в программе программирования 3D Фрэнк Лунас):

На него влияют два метода, которые поворачивают камеру вокруг оси x и y камеры:

Матрица мира/модели и матрица проекции вычисляются следующим образом:

Честно говоря, я еще не понимаю проблему, с которой сталкивается Im. Id быть благодарным, если кто-либо с более глубоким пониманием может дать мне некоторые подсказки относительно того, где мне нужно применить изменения, чтобы вектор, вычисленный из непроектирования, начинался с позиции курсора и перемещался в экран.

Изменить 1:

Я предполагаю, что это связано с тем, что моя камера находится в (0, 0, 0) в мировых координатах. Камера вращается вокруг своей локальной оси x и y. Из того, что я понимаю, матрица вида, созданная камерой, строит плоскость, на которой проецируется изображение. Если это так, то это объясняет, почему луч находится в каком-то «неожиданном» месте.

Мое предположение заключается в том, что мне нужно переместить камеру из центра так, чтобы она находилась вне объекта. Однако, если просто изменить переменную-член m_cameraPosition камеры, моя модель полностью искажается.

Читать:
Как повернуть треугольник на 150 градусов

Проекционная трансформация

Трехмерные объекты в пространстве фотографии проецируются на двухмерной пленке, которая является экраном в Direct3d. Этот трехмерный процесс преобразования двухмерных преобразования -это преобразование преобразования, то есть преобразование от пространства представления в пространство представления в Фотография. Пусть координатами трехмерных объектов в пространстве наблюдения являются Pview, а проекционная матрица -MPROJ, координаты вершины в проекционном пространстве: pProj = pView * mProj

Два основных проекционных преобразования представлены ниже: ортогональная проекция и прогрессивная проекция, а также их реализация в Direct3D.

1. Православная проекция

В ортогональной проекции проекционный вектор и плоскость наблюдения являются вертикально вертикальными. Координаты объектов проецируются на плоскости оси z, параллельной для наблюдения за системой координат. Расстояние между точками наблюдения и расстоянием между плоскостью не повлияет на проекцию. размер объекта.

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

Давайте посмотрим на генерацию ортодоксальной проекционной матрицы. Для ортогональной проекции его поле зрения — кубоид, и будет нарисовано только пейзаж в этом кубоиде.

Direct3D Extended Utility Library предоставляет функцию d3dxmatrixortholh () для создания ортогональной проекционной матрицы. Заявление функции d3dxmatrixortholh () выглядит следующим образом:

Создайте левую ортогональную проекционную матрицу.

Все параметры функции d3dxmatrxtoolh — это расстояние в пространстве камеры. Параметр Описание размера объема просмотра.

Эта функция использует следующую формулу для расчета матрицы возврата.

2. Перспективная проекция

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

Функция перспективной проекционной матрицы состоит в том, чтобы проецировать сцену на сцене на двухмерную пленку камеры. Вы можете использовать D3DXMatrixpersperspectivlh (), предоставленную библиотекой расширения функции Direct3D для создания матрицы проекции перспективы:

Builds a left-handed perspective projection matrix based on a field of view.

Конкретный метод расчета:

Роль перспективной проекционной матрицы состоит в том, чтобы преобразовать просмотр резака в куб. Поскольку проксимальный конец резака меньше удаленного конца, объект, близкий к камере, будет усилен, и чем дальше объект от камеры, тем меньше визуализация. Это принцип перспективы сцены. Перспективное преобразование преобразует резак кадрирования в новое пространство координат. Обратите внимание, что резак становится кубом. В то же время исходная точка перемещается от верхнего правого угла сцены к центру куба. В перспективном преобразовании пределы направлений оси x и оси Z составляют -1 и 1, предел направления оси z к передней плоскости составляет 0, а предел задней плоскости составляет 1.

Как исправить неполадки Direct 3D в полноэкранном режиме в Windows 10 v1903

Мы уже знаем, что каждое обновление Windows 10 приносит новую серию ошибок, которые расстраивают пользователей. То же самое относится и к майскому обновлению 2019 года.

Microsoft недавно подтвердила, что некоторые приложения и игры Direct3D (D3D) могут не переходить в полноэкранный режим на дисплеях, где ориентация дисплея была изменена по умолчанию (например, альбомная ориентация в портретном режиме) ,

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

Действия по устранению проблем с полноэкранным режимом D3D в Windows 10

1. Запустите приложения/игры в оконном режиме

Первое решение довольно удобно, и оно может быстро решить проблему для вас. Вы можете попробовать запустить свои приложения в оконном режиме.

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

Вы должны использовать дополнительный дисплей для запуска таких игр. Имейте в виду, что этот экран не должен поворачиваться перед запуском игры.

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

2. Отключите полноэкранные оптимизации

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

Откройте корневую папку приложения или игры и найдите основной исполняемый файл. Теперь щелкните правой кнопкой мыши файл .exe и перейдите на вкладку Свойства >> вкладка Совместимость >> Настройки >> Отключить полноэкранную оптимизацию >> Применить.

Вам не нужно перезагружать компьютер сейчас, потому что настройки будут применены немедленно.

3. Перезагрузите вашу систему

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

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

Похожие статьи