Настройка преобразований проекции, модели и вида для вершинного шейдера в 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 ответа:
Вот пример функции 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), возможны только векторные переводы, генерирующие Матрицы, когда они необходимы.
Матрицы умножаются на стандартные алгебраические операция . Матрицы могут быть модельными матрицами или проекционными матрицами. Преобразования могут быть объединены путем умножения двух матриц преобразований.