Мы формулируем матрицу вида и явно применяем преобразование в шейдере (передавая матрицу вида или матрицу lookAt) как униформу, поэтому разве камера не создана нами?
Да, точно. И так было еще до шейдеров. Есть только преобразования координат, если мы интерпретируем, что «камера» полностью зависит от нас.
Это не значит, что OpenGL предоставляет нам объект камеры по умолчанию для работы с нами, так как эта камера по умолчанию вообще откуда?
Этот учебник здесь довольно неточен. Однако в устаревшем OpenGL существовали некоторые соглашения по умолчанию, но это были только соглашения, и их строго не нужно использовать. Однако некоторые из устаревших функций OpenGL были разработаны с учетом этих соглашений. Общая идея заключалась в том, что пользователь использует правое пространство для глаз, где x указывает вправо, y вверх и z вне экрана в направлении зрителя, и поэтому -z
является направлением взгляда. Старая функция gluLookat()
следует этим соглашениям.
А также старые функции для создания проекционных матриц придерживаются этого: glFrustum()
, glOrtho()
, gluPerspecitve()
все принимают near
и far
как положительные расстояния в направлении просмотра, но используют z_eye = -near
для ближней плоскости и z_eye = -far
для дальней плоскости соответственно. Они также установили нижний ряд равным 0,0,-1,0
, поэтому мы в конечном итоге делаем деление на перспективу на -z_eye
и получаем левостороннюю систему координат ND C по ней (где z_ndc
указывает на экран сейчас) .
Обратите внимание, что матричные функции в glm
смоделированы так, чтобы следовать этим соглашениям, но вы также найдете функции с суффиксами с именами LH
и RH
, так что вы можете выбрать соглашение, которое вам нравится.
Мы могли бы предположить, что оси нашего координатного пространства указывают в любом направлении, верно?
Да. Однако пространство клипа (в котором находится вывод вершинного шейдера gl_Position
) определяется GL: растеризатор всегда будет использовать x
, полученный из x_cip/w_clip
и y
, полученный из y_clip/w_clip
, с x
горизонтальным и y
вертикальным размером. Размер z
используется только для проверки глубины, и если он указывает на экран, наш выбор в конечном итоге снова является вашим выбором (вы можете переключить направление сравнения проверки глубины, или glDepthRange
, или оба). Графический процессор не будет заботиться о том, что вы используете между ними вообще, поэтому для объектного пространства , мирового пространства и _eye_space_ вы можете использовать любые соглашения, которые вам нравятся, или вы можете создавать совершенно разные пространства если это подходит вам лучше, чем традиционная модель.