Jump to content
  • Advertisement
Sign in to follow this  
polyfrag

Why does this matrix multiplication order matter?

This topic is 1552 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is how I used to do matrix multiplication in my vertex shaders:


	gl_Position = projection * (view * (model * position));

But since I've ported to linux, in at least two of my shaders, only this works:


	gl_Position = projection * view * model * position;

Why?

Share this post


Link to post
Share on other sites
Advertisement

when you set your uniform matricies in linux, the glsl perhaps assumes opposite majoring order. So in case of column you use row, or vice versa (since you just ported, thus the layout in memory is the same). If you transpose the matricies, it will work with the previous formula (I am not saying you should do that of course, a waste of instructions).

Share this post


Link to post
Share on other sites

No, this works with all my other shaders.

 

Also, seems to be a bug:


	float minlight = shadow * diffuse;

	//outfrag = vec4(color.xyz * stexel.xyz * shadow * diffuse + vspecular, alph);	//buggy on linux for some reason
	outfrag = vec4(color.xyz * stexel.xyz * minlight + vspecular, alph);

It produces a reddish colour with blue fragments.

 

GL_VERSION: 3.0 Mesa 10.3.0-devel (git-96a95f4 saucy-oibaf-ppa)
Renderer1: Mesa DRI Intel(R) Ivybridge Mobile

 

Maybe it's because I tried to get the latest (experimental?) drivers for my integrated Intel videocard?

Edited by polyfrag

Share this post


Link to post
Share on other sites

GLSL code is platform agnostic for the most part, them difference usually boils down to the shader compiler included with the OpenGL driver. So this may be a driver bug.

Share this post


Link to post
Share on other sites

No, this works with all my other shaders.

 

What no? Do you mean shaders on linux that use the first formula work, and only this shader demands second formula on the linux?

 

Again, GLSL does not make distinction betweeen column or row vectors in its very code, but order of operations is explicit of course (order is actualy equivalent of majoring). you would better use glUniformMatrix4fv with transpose parameter specified, this will interpet matrix in GLSL code as expected, if driver is not totaly mad.

 

 

color.xyz * stexel.xyz

this is a cross product, depends on majoring as well.

 

I myself am not constructing matricies in GLSL code by implicit constructors, but I use explicit more atomic operations to actualy transform vectors by them, safely. (since I do not use glUniformMatrix4fv call to set matricies, but a batched vec4 array where I put everything I need for the shader in one call).

All operations that result in a vector not scalar I perform myself explicitly atomic for they are sensitive for majoring, to make myself sure.(this includes transformation of vector, multiplying matricies, crossing vectors...).

Share this post


Link to post
Share on other sites

 

 

 

color.xyz * stexel.xyz

this is a cross product, depends on majoring as well.

 

 

No, that's a pairwise multiply, not a cross product. The cross product is done with cross() and it does not depend on the row/column majorness of matrices.

 

polyfrag's code doesn't have matrix memory layout problems. His problem is that associative property of matrix multiplication doesn't hold on his Linux machine. And I don't know the reason for that.

Share this post


Link to post
Share on other sites

 

Again, GLSL does not make distinction betweeen column or row vectors in its very code, but order of operations is explicit of course (order is actualy equivalent of majoring).

 

The difference in the order is whether to multiply the vector first, and have all the other matrixes multiply a vector (reducing the number of operations since a vector is only 4x1), or multiply all the matrixes in order and only multiply the vector at the end.

Edited by polyfrag

Share this post


Link to post
Share on other sites

 


No, that's a pairwise multiply, not a cross product. The cross product is done with cross() and it does not depend on the row/column majorness of matrices.

 

polyfrag's code doesn't have matrix memory layout problems. His problem is that associative property of matrix multiplication doesn't hold on his Linux machine. And I don't know the reason for that.

 

Ah, yes you are right,

 

But memory layout is not what I am apointing. Majoring of operations has nothing to do with layout in memory. To explain, if you transform a matrix and reverse the majoring (component wisdom), it is then the same matrix and the same oprations- you just have to perform reverse majoring all the time, and, if you return to preveious majoring and keep the new matrix , it is  then a different (transposed matrix). Majoring is equivalent of operations comutativity with vectors and matricies.

 

If memory layout transposes,  you simply have only two options to have the same matrix, reverse the majoring (order of not comutaive operations with vectors), or, have matrix components to not tranpose thanks to layout missinterpratation.

Share this post


Link to post
Share on other sites
The difference in the order is whether to multiply the vector first, and have all the other matrixes multiply a vector (reducing the number of operations since a vector is only 4x1), or multiply all the matrixes in order and only multiply the vector at the end.

 

yes, first formula is more effective since you transform vector 3 times by a matrix, while second formula performs 2 matrix multiplications and than transforms a vector. I stress again that second formula performs reverse order of transformations, and it results in the same thing since matricies are (diagnosticly) transposed.

Share this post


Link to post
Share on other sites

 

 

Again, GLSL does not make distinction betweeen column or row vectors in its very code, but order of operations is explicit of course (order is actualy equivalent of majoring).

 

The difference in the order is whether to multiply the vector first, and have all the other matrixes multiply a vector (reducing the number of operations since a vector is only 4x1), or multiply all the matrixes in order and only multiply the vector at the end.

 

 

That only saves operations if you are doing only one or two transformations.  If you are processing lots of vectors, then the matrix concatenation is clearly more efficient.

 

Regarding your original question, are you having issues with only one or two shaders, but all of the others are working as you expected (using the same matrix multiplication order)?

Share this post


Link to post
Share on other sites

This topic is 1552 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!