2015-08-08 1 views
0

Если я выбираю пятно на мониторе на экране X/Y, как я могу получить точку в трехмерном пространстве, основываясь на матрицах проекции и просмотра?Как определить координаты XYZ точки на заднем буфере

Например, я хочу поместить объект на глубину и разместить его в 10,10 в экранных координатах. Поэтому, когда я обновляю свою матрицу мира, она будет отображаться на экране на 10,10.

Я предполагаю, что это довольно прямолинейно, поскольку у меня есть матрицы моей камеры, но я не уверен, как «отменить» нормальный процесс.

DirectXTk XMMath было бы лучше, но я, без сомнения, разбираюсь в любой системе линейной алгебры (OpenGL, D3DX и т. Д.).

+0

Ваша проблема-постановка недостаточно определена. Существует целая _ линия_ точек, которые будут отображаться на определенную (x, y) пространственную точку экрана. Классический «unprojecting» использует значение глубины из буфера z, чтобы полностью инвертировать процесс. Разумеется, вы можете предположить, что некоторые значения z, если вам все равно. – derhass

+0

Да, я рад предположить, что Z равно заднему буйферу. Это то, что я имел в виду под «объектом на глубине», хотя это не очень ясно. – Dave

+0

@Dave читает буфер глубины в этой точке, он будет находиться в диапазоне ** [0.0, 1.0] **, и вам придется отменить диапазон глубины и разделение перспективы. Это, наверное, единственное, что не совсем прямолинейно. Но я думаю, что любое обсуждение «непрозрачности», вероятно, охватит это. Вам нужно все в NDC-пространстве, прежде чем вы сможете сделать unproject, так что это связано с вашим диапазоном просмотра/глубины в дополнение к матрицам. –

ответ

0

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

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

  1. ModelView (GL) или View (общий D3D /) матрица
  2. матрица проекции
  3. Viewport
  4. Глубина Range (допустим, по умолчанию, [0, 1])

То, что вы пытаетесь сделать, - это найти в мировом пространстве точку, лежащую на далекой плоскости отсечения при определенной координате x, y в окне-пространстве. Точка, которую вы ищете, - <x,y,1>(z = 1 соответствует дальнему плану в пространстве окна).

Учитывая этот момент, вы должны преобразовать обратно в NDC-пространстве

  • Специфика фактически API-зависимым, поскольку определение D3D в НДЦ отличается от OpenGL в - они не согласны на интервале Z (D3D = [0, 1], GL = [-1, 1]).

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

  • Это однородные координаты и деление на W необходимо.

Из пространства вида примените обратную матрицу View, чтобы достичь точки в мировом пространстве, которая удовлетворяет вашим критериям.


Большинство математических библиотек имеют функцию, называемую UnProject (...), которая будет делать все это для вас.Я бы предложил использовать это, потому что вы отметили этот вопрос D3D и OpenGL, а особенности некоторых из этих преобразований различны в зависимости от API.

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

Смежные вопросы