HLSL mul  

mul은 벡터와 행렬의 순서에 따라 결과가 다르다.

mul(x, y)

x값이 vector이면 row-vector로 처리하고
y값이 vector이면 column-vector로 처리한다.

mul( vector, matrix ) ===>  row vector  (row-major matrix system)
mul(matrix, vector ) ===> column vector  (column-major matrix system)

DirectX API에서는 4차원 행렬을 넘겨줄때 전치 행렬로 설정해야 한다.
HLSL에서는 전치행렬을 사용할 필요가 없다.

//1. 어셈블리에서 사용할때는 전치 행렬이 필요하다

D3DXMATRIX tm;
D3DXMatrixMultiply( &tm, &viewTM, &projectionTM );
D3DXMatrixTranspose( &tm, &tm );

pDevice->SetVertexShaderConstantF( 0, ( float* )&tm, 4 );

//---------------------------------------------------------------------------------

//2. HLSL에서 사용할때는 전치 행렬이 필요없다

//HLSL은 컴파일된 결과물의 디폴트가 열우선이다,
//행렬이 셰이더상수에 넘어갈때 행우선->열우선으로 패킹됩니다.

예1) 상수 테이블을 사용하면 HLSL에서는 전치행렬이 필요 없다
D3DXHANDLE viewTMHandle = 0;
viewTMHandle = pShaderConstTable->GetConstantByName( 0, "viewMatrix" );

D3DXMATRIX viewTM;
pDevice->GetTransform( D3DTS_VIEW, &viewTM );
pShaderConstTable->SetMatrix( pDevice, viewTMHandle, &viewTM );

예2) ID3DXEffect 사용하면 HLSL에서는 전치행렬이 필요 없다
D3DXMATRIX &tm;
D3DXMatrixMultiply( &tm, &viewTM, &projectionTM );

pEffect->SetMatrix( pViewProjectionTMParameter, &tm )

결론)
row-majored라면 shader에서 mul( vector, Matrix )로
column-majored라면 shader에서 mul( Matrix, vector ) 해준다.

// HLSL
float4x4 mTransformA;
float4x4 mTransformB;
float4 vIn;
float4 vOut = mul(mul(vIn, mTransformA), mTransformB);


//GLSL
mat4 mTransformA;
mat4 mTransformB;
vec4 vIn;
vec4 vOut = mTransformB * mTransformA * vIn;

mul

Multiplies x and y using matrix math. The inner dimension x-columns and y-rows must be equal.

mul(x, y)

x  :   [in] The x input value. If x is a vector, it treated as a row vector.
y  :   [in] The y input value. If y is a vector, it treated as a column vector.

DirectX:
Effect matrix parameters and HLSL matrix variables can define whether the value is a row-major or column-major matrix; however, the DirectX APIs always treat D3DMATRIX and D3DXMATRIX as row-major.

OpenGL:
The m parameter points to a 4x4 matrix of single- or double-precision floating-point values stored in column-major order. That is, the matrix is stored as follows.

참고)
https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb509628(v=vs.85).aspx
http://dolphin.ivyro.net/file/directx8.0/tutorial09.html
http://www.gpgstudy.com/m/forum/post/108628

Directx API는 행벡터 방식, 쉐이더는 정의에 따라 열벡터나 행벡터로 처리한다.
OpenGL은 열벡터로 처리한다.

수학
행벡터
d3d
(row-major matrix system)
열벡터
OpenGL
(column-major matrix system)
a11 a12
a13
a14
a21
a22
a23
a24
a31
a32
a33
a34
a41
a42
a43
a44

a11 a12
a13
a14
a21
a22
a23
a24
a31
a32
a33
a34
a41
a42
a43
a44

a11
a21
a31
a41
a12
a22
a32
a42
a13
a23
a33
a43
a14
a24
a34
a44


row vector란?


x y z 1


m11 m12 m13 m14
m21 m22 m23 m24
m31 m32 m33 m34
m41 m42 m43 m44

column vector란?

m11 m12 m13 m14       x
m21 m22 m23 m24       y    
m31 m32 m33 m34       z
m41 m42 m43 m44       1