DX11精灵问题

时间:2012-12-14 00:38:22

标签: c++ directx 2d sprite directx-11

我在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

所以这看起来很好。接下来,我添加了viewprojection矩阵,将verticies投影到屏幕空间,如我发布的着色器代码所示。结果... BadSprite1

如您所见,顶点投影不正确。对于初学者:

  • prim0vert0 = prim0vert1
  • prim1vert4 = prim1vert5

这对我来说没有意义,因为正在处理不同的顶点值。您可以通过查看UV坐标来判断顶点的输入顺序与初始测试的顺序相同。 这就是我的3x3 viewprojection矩阵缓冲区的外观:

enter image description here

我在顶部手动写了缓冲区值对应的矩阵行/列。底部的三个值只是填充,以确保我的缓冲区大小是16的倍数。所以......就像在directx中一样:

  • m00 =矩阵row1,column1
  • m01 =矩阵row1,column2

右边的红色值表示我的ViewProjection矩阵如何访问hlsl代码中的缓冲区。

出于某种原因,它将它视为float4x4?这可能是我的问题......或者我是解决问题的方式

-UPDATE -

我已经做了一些研究,现在正在假设float3x3在存储在寄存器中时会变成碎片(因为它被打包成4个浮点数组)。

现在看来,即使我的应用程序完全是2D,我仍然应该使用4x4矩阵,因为这种恼人的行为。这是正确的,还是有一些我不知道的解决方法?

1 个答案:

答案 0 :(得分:1)

设计/优化现代图形硬件以使用4x4字节向量,即4个浮点值。即使你使用float3向量,它内部仍然占用一个保存float4的寄存器。

为了使矢量数学正常工作,每个点必须从16字节对齐的地址开始,这是一个问题,当你有float3xN时,导致第二个点将从字节12开始

所以你必须将数据填充到16字节对齐。尝试使用float4x3。在内部,你的float3x3操作仍将占用float4x3

的空间