Matrix and vector multiplication returns wrong result using GLM

Viewed 952

I have this equation with constant c and vec4 x=(x_1, x_2, x_3, x_4):

x_1*c + x_2*c + x_3*c + x_4*c

where sum(x_i) = 1

That means, the result should be c:

=(x_1 + x_2 + x_3 + x_4) * c

= 1 * c = c

So I have a vec4 and a matrix4*3 multiplication like this:

(x_1, x_2, x_3, x_4) * ((? c ?), (? c ?), (? c ?) (? c ?) )

However, the y coord in result (vec3) is not equal to c at all.

How is that and how to fix it?

float constant = 10.0f;
glm::vec3 v1 = glm::vec3(48.0f, constant, 18.0f);
glm::vec3 v2 = glm::vec3(56.0f, constant, 18.0f);
glm::vec3 v3 = glm::vec3(56.0f, constant, 12.0f);
glm::vec3 v4 = glm::vec3(52.0f, constant, 8.0f);
glm::mat4x3 M = glm::mat4x3(v1, v2, v3, v4);
glm::vec4 sumTo1 = glm::vec4(0.2f, 0.4f, 0.1f, 0.3f);
glm::vec3 result = sumTo1 * M;
cout << "sumTo1=" << glm::to_string(sumTo1) << endl;
cout << "M=" << glm::to_string(M) << endl;
cout << "result=" << glm::to_string(result) << endl;

Output:

sumTo1=vec4(0.200000, 0.400000, 0.100000, 0.300000)
M=mat4x3((48.000000, 10.000000, 18.000000), (56.000000, 10.000000, 18.000000), (56.000000, 10.000000, 12.000000), (52.000000, 10.000000, 8.000000))
result=vec3(15.400001, 17.000000, 16.400000)

To my knowledge the vector is considered as a row vector already.

1 Answers

OpenGL matrices and GLM matrices are stored in column major order. The vector has to be multiplied to the matrix from the right:

glm::vec3 result = sumTo1 * M;

glm::vec3 result = M * sumTo1;

See GLSL Programming/Vector and Matrix Operations
and OpenGL Shading Language 4.60 Specification - 5.10. Vector and Matrix Operations

The exceptions are matrix multiplied by vector, vector multiplied by matrix, and matrix multiplied by matrix. These do not operate component-wise, but rather perform the correct linear algebraic multiply.

vec3 v, u;
mat3 m;
u = v * m;

is equivalent to

u.x = dot(v, m[0]); // m[0] is the left column of m
u.y = dot(v, m[1]); // dot(a,b) is the inner (dot) product of a and b
u.z = dot(v, m[2]);

And

u = m * v;

is equivalent to

u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;
Related