-
Notifications
You must be signed in to change notification settings - Fork 220
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
m3.multiply returns the premultiplied rather than postmultiplied result #96
Comments
The code in the article is the same as glmatrix https://github.com/toji/gl-matrix/blob/21b745f3a8b095c4a5304978fa8ab131b76a5f9e/src/mat3.js#L294 which is the same as glm which is the same as opengl https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glMultMatrix.xml It's not a bug. It's what pretty much every graphics library calls "multiply" In glm (C++) your example of M = TRS is written as
The math applied is the same as in this article. The order of storage is the same as well, translation is in offsets 12,13,14 in the matrix (well, offsets 7,8 for a 3x3 matrix) Also, the confusing part is WebGL consider rows to be columns as mentioned in the this article. No transposing is going on. Only how the data is interpreted |
Yeah, I realize now that in For the next person that gets tripped up here, I was thrown off because the naming of the variables is different than what you'd expect when using standard math notation, e.g. this series of variables:
Which I assumed referenced a matrix layout like this (row-major), because usually the first subscript denotes the row and the second subscript denotes the column in math. For instance, naively you might expect a02 to select the first row and the third column:
But actually the variables in the code reference a matrix layout like this (column-major):
I was also thrown off because the diagrams in the articles have the rows where columns would normally be and vice versa, as you wrote about here: https://webgl2fundamentals.org/webgl/lessons/webgl-matrix-vs-math.html Anyway closing this and thanks for the response. Hopefully the comment helps the next person who gets confused. |
Thanks. If/when I write WebGPU articles I'll try to use more "math"y diagrams and explanations and point out the "rows are columns" In another github issue I pointed out if you want to see the rows as columns you can write it like this
or maybe clearer
which if you squint can look like columns 😅 |
Describe the bug
Here is the definition of
m3.multiply
in https://webgl2fundamentals.org/webgl/lessons/webgl-2d-matrices.html:From the code and variable names:
BA
(A premultiplied by B) rather thanAB
(A postmultiplied by B) as you would naively expect. Maybe this is what you intended, but it isn't documented anywhere in the code or called out in the prose.Example:
vs.
The tricky thing is that the examples all work as written, because everything else in the code is written to handle this correctly. For instance, given this snippet from that webpage:
Let's simplify that snippet for notation purposes:
From reading this naively, you would expect
M = TRS
. But given the waym3.multiply
is implemented, you actually haveM = SRT
, which is actually the desired result, so the code works.I say that
M = SRT
is the desired result because once you feed M into the fragment shader, WebGL transposes the matrix (since it treats the matrix as column major). So the frag shader is actually doing this:and if
M = SRT
, thenM_transpose = T_transpose * R_transpose * S_transpose
, so:which is actually correct: first the point is scaled, then it's rotated, and then it's translated; translation should be the last step since generally you want the rotate the model point around the model origin rather than the world origin.
I think this is part of what is contributing to the confusion in #33 and #84.
The text was updated successfully, but these errors were encountered: