У меня проблемы с рендерингом спрайта в 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 для проверки моего буфера вершин / порядка, в котором вершины входили в вершинный шейдер:
Так что это казалось нормальным. Затем я добавил матрицу проекции представления, чтобы проецировать вершины в пространство экрана, как показано в коде шейдера, который я разместил. Результат…
Итак, как вы можете видеть, вершины не проецируются правильно. Для начинающих:
Это не имеет смысла для меня, так как обрабатываются разные значения вершин. Вы можете сказать, что вершины входят в том же порядке, что и мое первоначальное тестирование, посмотрев координаты UV.
Вот так выглядит мой буфер матрицы проекционного вида 3×3:
Я вручную написал поверх какой строки / столбца матрицы соответствуют значения буфера. Три значения внизу просто дополняют, чтобы размер буфера был кратен 16. Итак … как в DirectX:
Красные значения справа представляют, как моя матрица ViewProjection обращается к буферу в коде hlsl.
По какой-то причине он рассматривает это как float4x4? Может ли это быть моей проблемой … или я не могу решить мою проблему?
-ОБНОВИТЬ-
Я провел небольшое исследование и сейчас работаю в предположении, что float3x3 фрагментируется при хранении в регистрах (поскольку он упакован в группы по 4 числа с плавающей запятой).
Теперь кажется, что даже если мое приложение полностью 2D, я все равно должен использовать матрицу 4×4 из-за этого раздражающего поведения. Это правильно, или есть какой-то обходной путь, о котором я не знаю?
Современное графическое оборудование разработано / оптимизировано для работы с 4х4 байтовыми векторами, это 4 значения с плавающей запятой. Даже когда вы используете вектор float3, он все равно занимает один регистр, который содержит float4.
Чтобы векторная математика работала правильно, каждая точка должна начинаться с адреса, выровненного на 16 байтов, что является проблемой, если у вас есть float3xN, потому что 2-я точка начала бы с байта 12
Таким образом, вы должны дополнить свои данные до 16-байтового выравнивания. Попробуйте использовать float4x3. Внутренне, ваши операции float3x3 все еще будут занимать пространство float4x3
Других решений пока нет …