Проблемы со спрайтом в DX11

У меня проблемы с рендерингом спрайта в dx11, я только начал с основ. Вот мой простой код шейдера:

//Shader Model 4.0
//Default shaders for rendering a point sprite

Texture2D DiffuseTexture : register( t0 );

SamplerState DiffuseTextureSampler : register( s0 );

cbuffer cbViewProj : register( b0 )
{
float3x3 ViewProjection;
}

struct VS_INPUT
{
float2 Pos : POSITION;
float2 Tex : TEXCOORD0;
};

struct PS_INPUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
};

PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output;
float3 oVec = float3(input.Pos.x, input.Pos.y, 1.0f);
oVec = mul(oVec, ViewProjection);

output.Pos = float4(oVec.x, oVec.y, 0.0f, 1.0f);
output.Tex = input.Text;

return output;
}

float4 PS( PS_INPUT input) : SV_Target
{
return DiffuseTexture.Sample( DiffuseTextureSampler, input.Tex );
}

Как вы можете видеть, он имеет минимум, даже не матрицу мира для перемещения спрайта. Моя матрица «ViewProjection» представляет собой 2D-орфографическую матрицу. Я использовал эту настройку с DirectX9, и все работало нормально.

Переезд в dx11 У меня проблемы. Я считаю, что что-то не так с тем, как я настраиваю свою матрицу ViewProjection или как она читается в шейдере.

Сначала я использовал PIX для проверки моего буфера вершин / порядка, в котором вершины входили в вершинный шейдер:
BadSprite1

Так что это казалось нормальным. Затем я добавил матрицу проекции представления, чтобы проецировать вершины в пространство экрана, как показано в коде шейдера, который я разместил. Результат…
BadSprite1

Итак, как вы можете видеть, вершины не проецируются правильно. Для начинающих:

  • prim0vert0 = prim0vert1
  • prim1vert4 = prim1vert5

Это не имеет смысла для меня, так как обрабатываются разные значения вершин. Вы можете сказать, что вершины входят в том же порядке, что и мое первоначальное тестирование, посмотрев координаты UV.
Вот так выглядит мой буфер матрицы проекционного вида 3×3:

введите описание изображения здесь

Я вручную написал поверх какой строки / столбца матрицы соответствуют значения буфера. Три значения внизу просто дополняют, чтобы размер буфера был кратен 16. Итак … как в DirectX:

  • m00 = матрица row1, column1
  • m01 = матрица row1, column2
  • так далее

Красные значения справа представляют, как моя матрица ViewProjection обращается к буферу в коде hlsl.

По какой-то причине он рассматривает это как float4x4? Может ли это быть моей проблемой … или я не могу решить мою проблему?

-ОБНОВИТЬ-

Я провел небольшое исследование и сейчас работаю в предположении, что float3x3 фрагментируется при хранении в регистрах (поскольку он упакован в группы по 4 числа с плавающей запятой).

Теперь кажется, что даже если мое приложение полностью 2D, я все равно должен использовать матрицу 4×4 из-за этого раздражающего поведения. Это правильно, или есть какой-то обходной путь, о котором я не знаю?

2

Решение

Современное графическое оборудование разработано / оптимизировано для работы с 4х4 байтовыми векторами, это 4 значения с плавающей запятой. Даже когда вы используете вектор float3, он все равно занимает один регистр, который содержит float4.

Чтобы векторная математика работала правильно, каждая точка должна начинаться с адреса, выровненного на 16 байтов, что является проблемой, если у вас есть float3xN, потому что 2-я точка начала бы с байта 12

Таким образом, вы должны дополнить свои данные до 16-байтового выравнивания. Попробуйте использовать float4x3. Внутренне, ваши операции float3x3 все еще будут занимать пространство float4x3

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]