-
-
Notifications
You must be signed in to change notification settings - Fork 235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-square matrix * column vector multiplication implemented as row vector * matrix multiplication #385
Comments
Seems like the main issue here is perspective of what the matrix looks like under the hood. @recp We should probably document this. What do you think? You say Line 151 in 45134b1
Per my understanding of linear algebra You can't multiply
But you can multiply
I decided when creating arrays to use
versus
So,
(column top, row left) Gives you.
From a programming perspective, if you typed as is
If the row was on top then using a vec4 (4x1) would be valid. However, that changes the matrix to (column left, row top) Gives you
From a programming perspective, if you typed as is
For Reference Sake https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf |
From the openGL 4.60 spec page 126: This clearly states the product of a vector V and a matrix M is the vector of the dot product of V with the columns of M, while the product of M with V is a vector of the dot products of the rows of M with V. Currently, the 4x4, 3x3, and 2x2 matrix-vector multiply functions are all implemented as returning the vector of the rows dotted with the input vector. The non-square types return the vector of the columns dotted with the input vector. This is inconsistent, and one has to be wrong. My 4x3 matrix example is trivially verifiable with a simple glsl shader:
If you multiply a 4x3 matrix with a vector, it must be a vec4 and the result will be a vec3. |
@recp Per what I see from @Error-mdl We need more multiplication Current we support, plus more 2x2 X 2x1 = 2x1 (vec2) 3x2 X 2x1 = 3x1 (vec3) 4x2 X 2x1 = 4x1 (vec4) But we should add functions that do operations as described about 1x4 X 4x3 = 1x3 (vec3) We honestly might as well add function for each #x# that does more types |
Hi @Error-mdl, @EasyIP2023, Wow, thanks for the catch, yes I think Since we have only COLUMN vectors now we cant have both 1x4 ( which is vec4 ) and 4x1 ( ? ). 4x1 simply can be vec4 too as type but in functions it must have different representation to differ COL from ROW. For instance
in 1st matrix come first then vector in func name also in operation. In the second one vector come first then matrix as func name and operation. I like this if there are no better ideas, we can implement ROW * MAT as this style? Thanks EDIT: Actually we used the term "row" as vec4 in ROW * MAT * COL = SCALAR |
I'm probably entirely wrong about this it just makes more since to me. Sorry, in advance if i'm being annoying, but my mind just isn't fully understanding. Would be nice If in the docs there were a table of some sort showing how each Were my confusion lies is how is this laid out on paper. My mind is convinced that because GLSL spec swaps Laid out on paper mat4x3 with original matrix form
Laid out on paper mat4x3 with swapped matrix form (DUE to GLSL)
|
Sorry for poor documentation, we should clarify how cglm keep matrices on memory and how to access items. cglm keeps matrices as COLUMN-MAJOR order in memory. It's all about how we define vectors and how to keep in memory. A single vector is considered as a column, for instance vec4:
When we talk about a vector in general it is a COLUMN as above. But someone may store 4x1 which can be considered as row vector in vec4 for convenience. On the other hand matrices are consist from vectors. For instance an affine matrix looks like:
which consists from 4 column vectors: Rx, Ry, Rz and P column vectors. We keep them in memory as: VEC1 | VEC2 | VEC3 | VEC4 Matrix[m] will give you m vector or m column. Why COLUMN vectors? For instance; consider if you want to access position and make changes, it is easy to do this in this way ( store matrix as columns in memory ). Matrix[3] will give a vector that contains positions. This is also cache friendly and efficient. In ROW_MAJOR similar effect can be achieved by transposing the matrix:
it is all about convention. 4x2:
2x4:
Matrix(m, n) --> m columns, n rows not m rows n columns. |
If the intent is to also support Would there be any issue with naming the |
@gottfriedleibniz
|
@Error-mdl Good, catch. You're correct! This is making more since now @recp
Of course not actual rules, but it helps me. Also maybe adding new types rvec2, rvec3, rvec4 instead of only using vec2,vec3,vec4 Linear algebra: matrix * matrix
GLSL linear algebra: matrix * matrix
Linear algebra: matrix * matrix
GLSL linear algebra: matrix * matrix
GLSL linear algebra: matrix * row vector (rvec)
GLSL linear algebra: matrix * column vector (vec)
|
@EasyIP2023 I'm not sure about adding typedef struct transform_or_other_type {
rvec4 row1;
mat4x1 row2;
vec4 col1;
mat1x4 col2;
} and something like maybe: typedef vec4 mat1x4;
typedef vec4 mat4x1;
typedef mat4x1 rvec4; which gives relation between mat4x1 and rvec4, user may prefer one which they like or meaningful in the context is used. Any feedbacks? |
I would love that. Would also like to use |
@recp Have cycles Wanted to wait until more feedback. Do you want me to start converting? Or continue to wait for more feedback?
|
Hi @EasyIP2023,
Actually no need to converting IIRC,
Yes let's wait a little more please |
The matrix-vector multiplication functions for non-square types (mat4x3, mat3x4, mat2x4, etc) incorrectly take the dot product of each column of the matrix with the vector instead of the row, which is vector * matrix not matrix * vector. This also means the functions take and output the wrong dimension of vector. For example, the mat4x3 multiplication:
cglm/include/cglm/mat4x3.h
Line 151 in 45134b1
A mat4x3 is a matrix of 4 columns and three rows:
A valid matrix-vector multiply on this matrix would take a vec4 and output a vec3 where the first component of the vec3 is the dot product of the first row of the matrix with the vector:
instead, the
glm_mat4x3_mulv
takes a vec3 and outputs a vec4, where the first component of the output vec4 iscglm/include/cglm/mat4x3.h
Line 154 in 45134b1
The square matrix types correctly dot the rows of the matrix with the vector to get each component of the output:
cglm/include/cglm/mat4.h
Line 407 in 45134b1
The text was updated successfully, but these errors were encountered: