0

I am learning HLSL shading, and in my vertex shader, I have code like this:

VS_OUTPUT vs_main(    
    float4 inPos: POSITION, 
    float2 Txr1: TEXCOORD0 )
{
    VS_OUTPUT Output;

   Output.Position = mul( inPos, matViewProjection);
   Output.Tex1 = Txr1;

   return( Output );

}

It works fine. But when I was typing codes from the book, the code was like this:

VS_OUTPUT vs_main(    
    float4 inPos: POSITION, 
    float2 Txr1: TEXCOORD0 )
{
    VS_OUTPUT Output;

   Output.Position = mul( matViewProjection, inPos );
   Output.Tex1 = Txr1;

   return( Output );

}

At first I thought maybe the order does not matter. However, when I exchanged the parameters in the mul function in my code, it does not work. I don't know why.

BTW, I am using RenderMonkey.

Noah
  • 135
  • 3
  • 11

2 Answers2

1

Not sure if this is caused by matrix order (row major or column major), take a look at Type modifier and mul function

Updated:

I have test this in my project, use the keyword row_major make the second case work.

row_major matrix matViewProjection
mul(matViewProjection, inPos);
zdd
  • 8,258
  • 8
  • 46
  • 75
  • Well, I don't think it is caused by matrix order. Either of code works fine, but when I exchange these parameters, it won't work. – Noah Jun 13 '14 at 10:34
  • And I delete the viewprojection matrix from the code in the book, and I imported it again just as I did to my own code, It still works fine. Thus it should not be the problem of matrix – Noah Jun 13 '14 at 10:36
  • @Noah, this is really caused by matrix order, I have test that in my project, if you declare your matViewProjection matrix as `row_major matrix matViewProjection`, you will find it works for `mul( matViewProjection, inPos );` – zdd Jun 16 '14 at 02:55
  • **-1**: This answer should have been a comment, it provides no actual information. – Andon M. Coleman Jun 16 '14 at 23:54
  • 1
    @AndonM.Coleman in my opinion, if my words can solve his problem, that's an answer, no matter how short it is. – zdd Jun 17 '14 at 01:56
  • Link-only answers are not appreciated on Stack Overflow, and that is the reason for the down-vote. If you are not going to explain anything links belong in comments. You should also give justification in comments before down-voting something. – Andon M. Coleman Jun 17 '14 at 02:11
  • @AndonM.Coleman my code works, that's the great explanation. workable code is more important than lines of word. – zdd Jun 17 '14 at 02:13
  • What code? Your answer simply states that you are not sure if it is an issue with matrix order and then gives links to something else. That is hardly an answer. – Andon M. Coleman Jun 17 '14 at 02:14
  • @AndonM.Coleman I have no time to argue with you, let's stop here. – zdd Jun 17 '14 at 02:15
  • @AndonM.Coleman if you look at that page carefully, you will find that's not `something else`, in the section of `Type_Modifier` – zdd Jun 17 '14 at 02:17
  • That is not the point of Stack Overflow though. Quality answers do not simply point the person somewhere else and claim "I do not know the answer, but you can figure it out yourself if you look here." I was actually justified in down-voting your answer, but out of spite you down-voted mine with no justification. I am done arguing with you, however... this is why I tend to avoid DirectX questions, the community is awful. – Andon M. Coleman Jun 17 '14 at 02:22
1

This issue is known as pre- vs. post-multiplication.

By convention, matrices produced by D3DX are stored in row-major order. To produce proper results you have to pre-multiply. That means that for matViewProjection to transform the vector inPos into clip-space inPos should appear on the l-hand side (first parameter).

Order absolutely matters, matrix multiplication is not commutative. However, pre-multiplying a matrix is the same as post-multiplying the transpose of the same matrix. To put this another way, if you were using the same matrix but stored in column-major order (transposed) then you would want to swap the operands.

Thus (vector on r-hand side -- also known as post-multiplication):

[ 0, 0, 0, m41 ]   [ x ]
[ 0, 0, 0, m42 ] * [ y ]
[ 0, 0, 0, m43 ]   [ z ]
[ 0, 0, 0, m44 ]   [ w ]
  • When the vector appears on the r-hand side it is interpreted as a column-vector.

Is equivalent to (vector on l-hand side -- also known as pre-multiplication):

[ x, y, z, w ] * [ 0,   0,   0,     0 ]
                 [ 0,   0,   0,     0 ] 
                 [ 0,   0,   0,     0 ]
                 [ m41, m42, m43, m44 ]
  • When the vector appears on the l-hand side, it is interpreted as a row-vector.

There is no universally correct side, it depends on how the matrix is represented.

Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • To be exactly, hlsl compiler use `column_major` as default if you didn't specify one. – zdd Jun 16 '14 at 03:22
  • Yes, I should have been more clear. In HLSL itself matrices are column-major by default. It is actually the ***other*** parts of Direct3D that use row-major matrices (e.g. the D3DX math library). If you pass a matrix created using D3DX to HLSL, it will be transposed. – Andon M. Coleman Jun 16 '14 at 03:26