Jump to content

  • Log In with Google      Sign In   
  • Create Account

Row vs Column Major Matrices: Most Useful?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 Cornstalks   Crossbones+   -  Reputation: 6991

Like
1Likes
Like

Posted 01 May 2013 - 11:51 PM

I'm working on a C++11-based math library (for fun) and am thinking about matrices lately. First, I know the difference between row and column major. That's not my question.

 

My questions are:

  • How often do you program in a row/column major dependent way vs how often do you program in a row/column major agnostic way? (for me, I've only found row/column majorness to only matter when passing matrices to my shaders... how often does the importance of row/column majorness pop up for you?)
  • What majorness do you most often use?
  • Have you ever needed to support both row and column major matrices (in the same program)?
  • If you have supported both row and column major matrices, what's your preferred way of distinguishing between the two? Postfixing a "_r" or "_c" on the end of the type name? Adding a template parameter?

 

I'm just trying to think of "the real world" when making this...


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

Sponsor:

#2 Hodgman   Moderators   -  Reputation: 31860

Like
7Likes
Like

Posted 02 May 2013 - 12:16 AM

Ignoring row-major storage vs column-major storage for a moment, there's matrices that have been constructed to transform mathematical row-vectors and matrices that have been constructed to transform mathematical column-vectors.

 

Whether you're using row-vectors or column-vectors simply depends on whether you write vec * mat (mat1x4 * mat4x4), or mat * vec (mat4x4 * mat4x1). With the former type of mathematics, the forward/right/up axes will be in the first 3 rows, whereas with the latter, these axes will be in the first 3 columns (they're the mathematical transpose of each other).

 

Therefore, if you work with row-vectors, I'd prefer to store my matrices in row-major order, so that it's easy to extract the basis vectors (this also makes the matrix multiplication code simpler on a lot of hardware).

Likewise if you work with column-vectors, I'd use column-major storage order, for the same reason.

 

Personally, I work with column-vectors (and matrices designed to transform column-vectors), because that's the way that most maths material I've used teaches it -- it seems the be the prevalent convention. Therefore, I prefer column-major storage.

 

One place where I have to mix storage conventions is when saving space. Sometimes you want to pass matrices around as 3rows x 4columns, with a hard-coded/assumed 4th row of [0,0,0,1]. Often your registers (shader uniforms or CPU SIMD) are 4-wide, so this storage format isn't possible with column-major storage (or, it takes the same amount of space: 4 registers). So when storing a 3x4 matrix, I'd use row-major storage (which only uses 3 registers).

This same problem presents itself with the opposite convention: with row-vectors + row-major storage, you'd want to use a 4x3 matrix with an assumed 4th column of [0,0,0,1], forcing you to use column-major storage for space efficiency.


Edited by Hodgman, 02 May 2013 - 12:27 AM.


#3 tivolo   Members   -  Reputation: 991

Like
4Likes
Like

Posted 02 May 2013 - 03:28 AM

Ignoring row-major storage vs column-major storage for a moment, there's matrices that have been constructed to transform mathematical row-vectors and matrices that have been constructed to transform mathematical column-vectors.

 

Whether you're using row-vectors or column-vectors simply depends on whether you write vec * mat (mat1x4 * mat4x4), or mat * vec (mat4x4 * mat4x1). With the former type of mathematics, the forward/right/up axes will be in the first 3 rows, whereas with the latter, these axes will be in the first 3 columns (they're the mathematical transpose of each other).

 

Therefore, if you work with row-vectors, I'd prefer to store my matrices in row-major order, so that it's easy to extract the basis vectors (this also makes the matrix multiplication code simpler on a lot of hardware).

Likewise if you work with column-vectors, I'd use column-major storage order, for the same reason.

 

Personally, I work with column-vectors (and matrices designed to transform column-vectors), because that's the way that most maths material I've used teaches it -- it seems the be the prevalent convention. Therefore, I prefer column-major storage.

 

One place where I have to mix storage conventions is when saving space. Sometimes you want to pass matrices around as 3rows x 4columns, with a hard-coded/assumed 4th row of [0,0,0,1]. Often your registers (shader uniforms or CPU SIMD) are 4-wide, so this storage format isn't possible with column-major storage (or, it takes the same amount of space: 4 registers). So when storing a 3x4 matrix, I'd use row-major storage (which only uses 3 registers).

This same problem presents itself with the opposite convention: with row-vectors + row-major storage, you'd want to use a 4x3 matrix with an assumed 4th column of [0,0,0,1], forcing you to use column-major storage for space efficiency.

 

Very well put. It's often overlooked to differentiate between row vs. column-major matrices regarding operations, and row vs. column-major regarding storage.

Here's a bit more food for thought why one should try to go for column vectors and write multiplications like v' = M * v.



#4 Cornstalks   Crossbones+   -  Reputation: 6991

Like
0Likes
Like

Posted 02 May 2013 - 07:30 AM

Huh. Awesome. I had never thought of the mathematical notation. I was going to use column-major notation (u = M * v) because that's standard mathematical notation, but let the matrix be either row or column major...

 

Well that settles it for me. Column major only for my little math library. Thanks guys!


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#5 unbird   Crossbones+   -  Reputation: 6016

Like
0Likes
Like

Posted 02 May 2013 - 08:11 AM

Before you're dead set on using column-vectors, check what your shaders use, because, oh joy, HLSL uses row vectors and GLSL column vectors AFAIK, another major difference (pun indended).

Personally I find reading the transformation sequence with row vectors easier (left to right, world, view, projection). I wonder what people with right-to-left languages (hebrew, arabic) think about that wink.png

 

Edit: Correction, HLSL can use both, see below.


Edited by unbird, 02 May 2013 - 08:48 AM.


#6 japro   Members   -  Reputation: 887

Like
0Likes
Like

Posted 02 May 2013 - 08:18 AM

You can also use column vectors in hlsl if you want to. Just setup you matrices accordingly... This is always a funny conversation since anyone from a math background will be more used to the column vector convention while occasionally non-math-programmers (a concept I never managed to understand :P) argue that "row vectors are the programmers convention" since the transforms appear in the "right order".



#7 Cornstalks   Crossbones+   -  Reputation: 6991

Like
1Likes
Like

Posted 02 May 2013 - 08:19 AM

Before you're dead set on using column-vectors, check what your shaders use, because, oh joy, HLSL uses row vectors and GLSL column vectors AFAIK, another major difference (pun indended).

Really? So HLSL uses row vectors but (defaults to) column-major matrices?


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#8 l0calh05t   Members   -  Reputation: 816

Like
0Likes
Like

Posted 02 May 2013 - 08:38 AM

Before you're dead set on using column-vectors, check what your shaders use, because, oh joy, HLSL uses row vectors and GLSL column vectors AFAIK, another major difference (pun indended).

Really? So HLSL uses row vectors but (defaults to) column-major matrices?

HLSL defaults to column-major matrix storage.This is completely unrelated to the use of row or column vectors. IIRC HLSL supports both column- and row vectors. Fun fact: if you store a Matrix used with a column vector system in row-major order and load it in column-major order it is now an equivalent matrix for a row vector system as it was transposed ;)


Edited by l0calh05t, 02 May 2013 - 08:38 AM.


#9 Cornstalks   Crossbones+   -  Reputation: 6991

Like
0Likes
Like

Posted 02 May 2013 - 08:54 AM

HLSL defaults to column-major matrix storage.This is completely unrelated to the use of row or column vectors.

But it is related, at least that was the whole point behind Hodgman's and tivolo's posts, if I understood them correctly.


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS