Изначально я написал развёрнутый ответ на форуме gamedev.ru об устройстве glFrustrum. Здесь опишу свои рассуждения по поводу ортогонального и перспективного проектирования в некотором смысле болле подробно.
Начнём. Различают два основных вида проектирования - перспективное и ортогональное.
Суть ортогонального проектирования - лучи, отражённые от объекта, падают параллельно на проекционную плоскость. Часто при упоминании этого вида проектирования рассматривается случай проектирования вдоль направления,
параллельному одному из направлений орт.
Суть перспективное проектирования - наблюдатель, видит лучи, отражённые от объекта, которые идут к нему в глаз. Лучи не идут вообще говоря параллельно.
Примем то что собирает эти лучи за точку. Между точкой и остальным миром вставим картинную плоскость. Рассмотрим только лучи, которые после пересечения картинной плоскости сойдутся в рассмотренной точке. Допуская некоторую вольность речи, это и есть модель перспективного проектирования. Изображение получаемое на картинной плоскости не является инвертированным.
забегая немного вперёд отличие описанной модели от той, что применяется в OpenGL для перпективного проецирования в том, что в OpenGL не теряют глубину а её натягивают особым образом на отрезок [-1, 1]
В OpenGl используется модель перспектиной геометрии. В этой модели 3-ёх мерные вектора расширяются до 4-ёх мерных. Последнии называются "однородными" (homogenous)
Причём отношением эквивалентности для точек пространства задаётся так: (x1, y1, z1, w1) ~(x2, y2, z2, w2) <=>(x1/w1, y1/w1, z1/w1, 1) = (x2/w2, y2/w2, z2/w2, 1)
В общем преобразования координат вершин в OpenGL можно охарактеризовать так:
Мы рассмотрим шаг 2.
Матрица проектирования влияет на вектор следующим образом:
Стоит отметить, что для шага 2 "Eye coordinates" определяются в провосторонней системе координат, однако "Clip coordinates" уже являются координатами в левосторонней системе координат. Стандартные OpenGL проекционные матрицы переворачивают ось oz. Это изменяет систему координат из правосторонней в левую. Эти системы координат отличаются направлением оси Z
Поймём откуда вообще говоря взялись матрицы, определённые в OpenGL, как матрицы которые загружаются посредством glOrtho и glFrustum.
Мне не знакома ни одна книга, ни одни лекции которые объянили бы эту краегольную тему во всей realtime компьютерной гпафике
Будем считать, что картинная плоскость задаётся так
Перспективное проектирование
1) Для перспективного проектирования задаётся центр проектирования. Пусть это будет точка
Требуется вычислить проекцию точки
на плоскость T.
Будем считать, что точка
и лежат по разные стороны плоскости T => проекция точки будет принадлежать отрезку (),
или другими словами
(*)
Подставляя (*) в уравнение плоскости получим:
=>
Согласно выведенным уравнениям (**) и (*) мы можем получить перспективную проекцию точки
К примеру если положить c=(0,0,-1); n=(0,0,1); d=-1
t=(-1 -1)/(-1 - z)=2/(1+z)
r' = (1-2/(1+z)) (0,0,-1) + 2/(1+z)*r
2) В описании glFrustum из msdn сказано: "assuming that the eye is located at (0, 0, 0). ", т.е. центр проектирования находится в начале координат. Также перенося текст из msdn на выведенные формулы получим: n=(0,0,1) и d=-(zNear) =>
t=-zNear/(-nr)=zNear/z
r'(x) = r(x) * Znear/z
r'(y) = r(y) * Znear/z
r'(z) = r(z) * Znear/z=Znear
3) Вернёмся к описанию glFrustrum
Умножим матрицу на вектор [X, Y, Z, 1] ^ T справа и получим покомпонентное выражение:
Разделим все компоненты на (-Z), т.к. проективная геометрия позволяет так делать =>
Таким образом c x' и y' происходит:
1) перспетивное преобразование согласно (2)
2) смещение центра получаемой координаты на (right+left)/2 и (top+bottom)/2
3) нормализация координат в [0,1]. Умножение полученного результата на 2 для того, чтобы всё привести в отрезок [-1, +1].
достаточно хитро это делается.
С z' происходит:
1) смещение проектируемой точки на (far+near)/2
2) гиперболическое преобразование координаты Z (2*far*near/Z)
3) нормализация координат
Особенность формулы заключается, что область допустимых значений для Z есть интервал [-far, -near] в правой системе координат. При подстановке значения z' (-near) = -1 и z'(-far)=+1
Таким образом на можно сделать вывод о том, что Clip Coordinates получаются в левой системе координат
Ортогональное проектирование
1) Для ортоганального проектирования задаётся направление проектирования. Пусть это будет направление
Определим проекцию точки
на плоскость T.
(*)
Подставляя (*) в уравнение плоскости получим:
=>
Согласно выведенным уравнениям (**) и (*) мы можем получить перспективную проекцию точки
2) В описании glOrtho сказано: "assuming that the eye is located at (0, 0, 0). ", т.е. центр проектирования находится в начале координат. Также перенося текст из msdn на выведенные формулы получим: n=(0,0,1) и d=-(zNear) и e=(0,0,-1) =>
t=-(z-zNear)
r'(x) = r(x) + (z-Znear)*(0,0,1)
r'(y) = r(x) + (z-Znear)*(0,0,1)
r'(z) = r(x) + (z-Znear)*(0,0,1)