Skip to content
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

Proposal: optimized functions to multiply 3 matrices at once without using _mulN #124

Open
recp opened this issue Mar 6, 2020 · 6 comments

Comments

@recp
Copy link
Owner

recp commented Mar 6, 2020

It is common to multiply Model, View and Project matrices together, there may be additional matrices to multiply...

We have two option to multiply 3 matrices:

  1. Using glm_mat4_mulN() which is nice helper but it uses loop.
  2. Using two glm_mat4_mul() call which is general.

Proposal:

New functions to multiply 3 or 4 matrices.

  • glm_mat4_mul3x(m1, m2, m3, dest), glm_mat4_mul4x(m1, m2, m3, m4, dest) - general matrix multiplication to multiply 3 or 4 matrices
  • glm_mvp(m, v, p) or glm_pvm(p, v, m) or glm_mul_mvp(m, v, p) or glm_mul_pvm(p, v, m) for Model * View * Proj. Model matrix' rotation vectors' last component must be zero. (mvp vs pvm?)
  • glm_trs - Translate * Rotate * Scale

same for mat2 and mat3. Better names and ideas are always welcome. These functions will be optimized especially with SIMD, loop will not be used.

This will also make engines, renderers, games... faster and with less cglm call[s] and more readable, more neat... 🤗

@recp recp self-assigned this Mar 6, 2020
@recp recp pinned this issue Mar 6, 2020
@recp recp added this to the v0.8.0 milestone Mar 6, 2020
@Lambdara
Copy link
Contributor

mvp vs pvm?

I would suggest pvm, for Proj * View * Model; as you would usually translate a vertex by going Proj * View * Model * vertex, if I'm not mistaken. I guess the full name would best be glm_mat4_pvm or glm_pvm; I don't think mul really adds anything (is there any other kind of functionality involving these three that you would expect there to be?)

@acoto87
Copy link
Contributor

acoto87 commented Apr 11, 2020

I like the glm_mat4_mul3x and glm_mat4_mul4x variants, as you could use these functions for other stuff other than multiplying Model * View * Proj.

@recp
Copy link
Owner Author

recp commented Apr 13, 2020

@Uwila , @acoto87 thanks for reviewing this proposal!

if I'm not mistaken. I guess the full name would best be glm_mat4_pvm or glm_pvm;

glm_pvm(projection, view, model, dest) or glm_mvp(model, view, projection, dest) are the name candidates, not glm_mat4_pvm...

the multiplication order will same: ### Projection * View * Model for both glm_pvm() and glm_mvp().

single call will make things more readable and faster because, I want to optimize triple matrix multiplication in one function to get maximum performance and less instructions and less binary size.

I don't think mul really adds anything (is there any other kind of functionality involving these three that you would expect there to be?)

I guess you are talking about glm_mat4_mul3x() and glm_mat4_mul4x() ... these will be general matrix multiplication. _pvm() version is optimized for affine transforms.

For instance there are a few functions to multiply mat4 in cglm:

  1. glm_mat4_mul() - optimized, general purpose matrix multiplication.
  2. glm_mul() - optimized for affine transforms; the last element of rotation part must be zero like:
/* affine-mat.h */

R  R  R  X
R  R  R  Y
R  R  R  Z
0  0  0  W
  1. glm_mul_rot() - optimized for rotation transforms:
/* affine-mat.h */

R  R  R  0
R  R  R  0
R  R  R  0
0  0  0  1

@Lambdara
Copy link
Contributor

I guess you are talking about glm_mat4_mul3x() and glm_mat4_mul4x() ... these will be general matrix multiplication. _pvm() version is optimized for affine transforms.

I meant in the context of _pvm; you listed glm_mvp(m, v, p), glm_pvm(p, v, m), glm_mul_mvp(m, v, p) and glm_mul_pvm(p, v, m) as candidates; not that it matters much but I meant to say that mul doesn't really add anything in this case.

@acoto87
Copy link
Contributor

acoto87 commented Apr 13, 2020

I kind of agree with @Uwila but with the names glm_mvp or glm_pvm it's lost in the name of the function what does the function do. It's general knowledge that what you do with those matrices are multiplying to together to get the final transformation matrix. If that is the case, those names are fine, if it could be cause of confusion I would prefer the explicit glm_mul_mvp and glm_mul_pvm.

About the order of the parameters, it's a matter of semantics when you talk about it;_pvm indicates exactly the order in which the matrices will be multiplied: Proj * View * Model so there is no ambiguity there, and the _mvp indicates generally the operation that you are doing (without explicitly telling the order of the multiplication and I think it's the most common way people refers to this operation), in like: "I'm just calculating the final transformation with matrices Model, View, Proj.

That last version could also create confusion, because you can treat that operation as:

  • vT * Model * View * Proj (vT is the transpose of the vector)
  • Proj * View * Model * v

depending on how you store matrices, but since this library store matrices column-wise, the latter is what will be used, and the explicit _pvm makes more sense.

@kzhsw
Copy link

kzhsw commented Dec 17, 2024

For glm_trs, it's good to have one that takes vectors as input, like glm_trs(vec3 translation, versor rotation, vec3 scale, mat4 dest), example impl (in js):

https://github.com/toji/gl-matrix/blob/fdab302a5a3ae9b7a975fcba7aa5d3112a681f94/src/mat4.js#L1320

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants