Настройка преобразований проекции, модели и вида для вершинного шейдера в eigen


Я осмотрелся и никогда не видел, что именно делает каждая матрица и какие операции формируют их (так что фактические вызовы функций eigen). Это то, что я ищу. Или хотя бы описание процесса и пару примеров с собственными функциями, чтобы увидеть в целом, как это сделать! В любом случае, вот некоторые детали, если они полезны:

Я настраиваю игру перспективы сверху вниз (так что камера фиксируется вниз, но может вращаться и двигаться вдоль плоскости XY), но поскольку у меня будут некоторые 3D-элементы (наряду с некоторыми вещами, которые строго 2D), я думаю, что перспективная проекция будет хорошо работать. Но мне интересно, какие команды были бы необходимы для формирования ортогональной проекции...

Я вроде как понимаю вид, который будет сделан путем перевода координат камеры в исходное положение, поворота поворотом камеры, перевода их обратно туда, где они были, а затем масштабирования для увеличения? Но какие именно функции и объекты будут задействованы, я не знаю. конечно.

И для хранения вращения любого данного объекта кватернион, по-видимому, является лучшим выбором. Так будет ли это определять проекцию модели? Если мне удастся упростить мое вращение до двумерного случая одного угла, будут ли кватернионы тогда расточительными?

И нужно ли все эти матрицы регенерировать из идентичности каждого кадра? Или их можно как-то изменить, чтобы они соответствовали новым данным?

Я бы действительно предпочел использовать для этого eigen вместо того, чтобы держать за руку библиотека, но мне нужно с чем-то работать, чтобы точно понять, что происходит... У меня есть все настройки GLSL и однородные матрицы, которые подаются в рендеринг с моим VAOs, мне просто нужно понять и сделать их.

Правка:
Мой вершинный шейдер использует эту стандартную настройку с 3 равномерными mat4, умноженными на позицию vec3:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);

Можно ли использовать mat3s и vec2 для позиционирования, чтобы добиться лучшей производительности в чисто 2D-случаях?

2 9

2 ответа:

Вот пример функции lookAt и setPerspective, создающей матрицы вида и проекции из простых входных данных:

void Camera::lookAt(const Eigen::Vector3f& position, const Eigen::Vector3f& target, const Eigen::Vector3f& up)
{
  Matrix3f R;
  R.col(2) = (position-target).normalized();
  R.col(0) = up.cross(R.col(2)).normalized();
  R.col(1) = R.col(2).cross(R.col(0));
  mViewMatrix.topLeftCorner<3,3>() = R.transpose();
  mViewMatrix.topRightCorner<3,1>() = -R.transpose() * position;
  mViewMatrix(3,3) = 1.0f;
}

void Camera::setPerspective(float fovY, float aspect, float near, float far)
{
  float theta = fovY*0.5;
  float range = far - near;
  float invtan = 1./tan(theta);

  mProjectionMatrix(0,0) = invtan / aspect;
  mProjectionMatrix(1,1) = invtan;
  mProjectionMatrix(2,2) = -(near + far) / range;
  mProjectionMatrix(3,2) = -1;
  mProjectionMatrix(2,3) = -2 * near * far / range;
  mProjectionMatrix(3,3) = 0;
}

Затем можно задать матрицы для GL:

glUniformMatrix4fv(glGetUniformLocation(mProgram.id(),"mat_view"), 1, GL_FALSE, mCamera.viewMatrix().data());
glUniformMatrix4fv(glGetUniformLocation(mProgram.id(),"mat_proj"), 1, GL_FALSE, mCamera.projectionMatrix().data());

Для преобразования модели (лучше разделять вид и модель) можно использовать модуль Geometry с классами Scaling, Translation и Quaternion для сборки объекта Affine3f.

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

В приведенном примере лучше вычислить только mat4 * vec4 вместо mat4 * mat4 * mat4 * vec4, Действительно:

Gl_Position = modelviewprojectionMatrix * vec4 (in_Position, 1.0);

Где modelviewprojectionMatrix - результат projectionMatrix * viewMatrix * modelMatrix. Матрица арифметика реализована на стороне процессора, для каждого набора вершин, которые вам нужно отрисовать.

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

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