Есть такой пиксельный шейдер выполняющий перспективную трансформацию текстурных координат.
float4x4 matrix_transform;
struct PS_INPUT
{
float2 Tex0 : TEXCOORD0;
float4 diffuse : COLOR;
};
float2 GetCoord(float2 coord_uv)
{
float4 tex_coord = float4(coord_uv.x, coord_uv.y, 0.0, 1.0);
tex_coord = mul(tex_coord, matrix_transform);
return float2(tex_coord.x / tex_coord.w + 0.5, tex_coord.y / tex_coord.w + 0.5);
}
float4 main(PS_INPUT input) : COLOR0
{
return tex2D(texture0, GetCoord(input.Tex0));
}
Оказывается для корректного выполнения операции mul перед отправкой матрицы matrix_transform приходится делать её транспонирование.
...
D3DXMATRIX _matrix;
...
_shaderPixel.Bind();
D3DXMatrixTranspose(&_matrix, &_matrix);
_shaderPixel.setPSParam("matrix_transform", _matrix, 16);
...
Т.е. положение столбцов и строк в HLSL и DirectX перепутано! Почему так происходит? Кто-нибудь может сказать?
Сам узнал об такой оказии только после дизассембрования кода шейдера? Информации ни где толковой не мог найти.
Мой дизасемблированный код:
// Registers:
//
// Name Reg Size
// ---------------- ----- ----
// matrix_transform c0 4
// texture0 s0 1
//
/*
ps_2_0
def c4, 0.5, 0, 0, 1
dcl t0.xy //текстурные координаты input.Tex0
dcl_2d s0 //texture0
mov r0.xy, t0 //r0 -> float4 tex_coord
mov r0.zw, c4
dp4 r1.w, r0, c3 //r1.w => tex_coord.w after mul
rcp r1.x, r1.w //r1.x => tex_coord.w after mul
dp4 r1.y, r0, c0 //r1.y -> tex_coord.x after mul
dp4 r0.x, r0, c1 //r0.x -> tex_coord.y after mul
mad r0.y, r0.x, r1.x, c4.x //r0.y => ret.y = tex_coord.y/tex_coord.w + 0.5
mad r0.x, r1.y, r1.x, c4.x //r0.x => ret.x = tex_coord.x/tex_coord.w + 0.5
texld r0, r0, s0
mov oC0, r0
tex_coord after mul -> tex_coord(r1.y, r0.x, -- , r1.x)
*/