• Advertisement
Sign in to follow this  

pass matrix to shader problem

This topic is 1118 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

Can anyone explain the below behavior?

 

having:

D3D11_INPUT_ELEMENT_DESC _desc[] = {
    {"VERT_COORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"WVP", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
    {"WVP", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
    {"WVP", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
    {"WVP", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1},
};

when I:

// (vertex shader)
float4 main(float4 _vert : VERT_COORD, float4x4 _wvp : WVP) : SV_Position {...}

"_wvp" matrix is transposed (I do it on the CPU side). But if I:

// (vertex shader)
float4 main(float4 _vert : VERT_COORD, float4 _wvp0 : WVP0, float4 _wvp1 : WVP1, float4 _wvp2 : WVP2, float4 _wvp3 : WVP3) : SV_Position {
    float4x4 _wvp = float4x4(_wvp0, _wvp1, _wvp2, _wvp3);
    
    // or
    
    float4x4 _wvp = float4x4(
        _wvp0.x, _wvp0.y, _wvp0.z, _wvp0.w,
        _wvp1.x, _wvp1.y, _wvp1.z, _wvp1.w,
        _wvp2.x, _wvp2.y, _wvp2.z, _wvp2.w,
        _wvp3.x, _wvp3.y, _wvp3.z, _wvp3.w
    );
    ...
}

"_wvp" is now not transposed.

Edited by zeo4

Share this post


Link to post
Share on other sites
Advertisement

Ok, I've got it.

The problem lies within operations on float4x4 when column-majority packing is on. Simply all the float4x4 operations then assume that columns (not rows) are stored next to each other in memory. Therefore:

 

this

#pragma pack_matrix(column_major)
float4x4 mtx = float4x4(val0, val1, val2, val3);

is stored in memory like that

mtx
val0.x  val1.x  val2.x  val3.x  val0.y  val1.y  val2.y  val3.y  val0.z  val1.z  val2.z  val3.z  val0.w  val1.w  val2.w  val3.w

and this

#pragma pack_matrix(row_major)
float4x4 mtx = float4x4(val0, val1, val2, val3);

is stored in memory like that

mtx
val0.x  val0.y  val0.z  val0.w  val1.x  val1.y  val1.z  val1.w  val2.x  val2.y  val2.z  val2.w  val3.x  val3.y  val3.z  val3.w

Another example of an operation that takes into account the above rule is operator[].

// mtx (float4x4)
// 00 01 02 03
// 10 11 12 13
// 20 21 22 23
// 30 31 32 33
// memory
// 00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33

#pragma pack_matrix(row_major)
// get third row in a row-major configuration
mtx[2]; // row-major is on, so it's instructed that row values are next to each other in memory, so it takes {20 21 22 23}

#pragma pack_matrix(column_major)
// get third row in a column-major configuration
mtx[2]; // column-major is on, so it's instructed that row values are every 4th value in memory, so it takes {02 12 22 32}
Edited by zeo4

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement