Странное поведение умножения собственных матриц при использовании матриц-строк

Следующее работает просто отлично для меня:

using Mat4 = Eigen::Matrix4f;
using Vec3 = Eigen::Vector3f;

class Camera {
public:
Vec3 pos = { 0.0f, 0.0f, 0.0f };
Vec3 forward = { 0.0f, 0.0f, 1.0f };
Vec3 up = { 0.0f, 1.0f, 0.0f };
float vfov = degrees(45.0f);
float near_plane = 0.1f;
float far_plane = 100.0f;

Mat4 cameraToScreen(float aspect_ratio) const {
Mat4 result;

float tanHalfFovy = tan(vfov *0.5f);
float x_scale = 1.0f / (aspect_ratio * tanHalfFovy);
float y_scale = 1.0f / (tanHalfFovy);

result <<
x_scale, 0, 0, 0,
0, y_scale, 0, 0,
0, 0, -(far_plane + near_plane) / (far_plane - near_plane), -1.0f,
0, 0, -2.0f * near_plane * far_plane / (far_plane - near_plane), 0;
return result;
}

Mat4 worldToCamera() const {
Mat4 result;

Vec3 p = pos;
Vec3 f = forward.normalized();
Vec3 r = f.cross(up).normalized();
Vec3 u = r.cross(f).normalized();

result <<
r.x(), u.x(), -f.x(), 0.0f,
r.y(), u.y(), -f.y(), 0.0f,
r.z(), u.z(), -f.z(), 0.0f,
-r.dot(p), -u.dot(p), f.dot(p), 1.0f;

return result;
}

Mat4 worldToScreen(float aspect_ratio) const {
return cameraToScreen(aspect_ratio) * worldToCamera();
}
};

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

using Mat4 = Eigen::Matrix<float, 4, 4, Eigen::RowMajor>;

К сожалению, все сломалось. Интересно, что инвертирование окончательного умножения матриц (что неверно) решает проблему:

Mat4 worldToScreen(float aspect_ratio) const {
return worldToCamera() * cameraToScreen(aspect_ratio);
}

Это почти как если бы eigen выполнил умножение матриц с предположением, что хранилище было главным по столбцу, независимо от моего тега шаблона, но это не может быть правильным.

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

Что я не понимаю, как Эйген обрабатывает матрицы строк?

редактировать:

Вот как эффективно я отправляю данные в OpenGL. В моем коде много дополнительных шаблонов, но все сводится к следующему:

struct CameraData {
Mat4 world_to_screen ;
};

void draw(Camera const& cam) {
CameraData cam_data;

// I remove the transposed() call when using Eigen::RowMajor
cam_data.world_to_screen = cam.worldToScreen(16.0f/9.0f).transposed();

// Camera data has a permanent ubo binding point shared by all programs.
glBindBuffer(GL_UNIFORM_BUFFER, cam_data_ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(cam_data), &cam_data);

//.. perform drawing
}

и glsl:

#version 420

in vec3 vertex;

layout (std140) uniform CameraData {
mat4 world_to_screen;
};

void main() {
gl_Position = world_to_screen * vec4(vertex, 1.0);
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]