我在 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”矩阵是一个二维正交矩阵。我将此设置与directx9一起使用,一切正常。
进入 dx11 我遇到了麻烦。我相信我设置 ViewProjection 矩阵的方式或在着色器中读取它的方式有问题。
首先,我使用 PIX 检查我的顶点缓冲区/顶点进入顶点着色器的顺序:
所以这看起来很好。接下来,我添加了 viewprojection 矩阵以将顶点投影到屏幕空间中,如我发布的着色器代码所示。结果...
如您所见,顶点的投影不正确。对于初学者:
- prim0vert0 = prim0vert1
- prim1vert4 = prim1vert5
这对我来说没有意义,因为正在处理不同的顶点值。您可以通过查看 UV 坐标来判断顶点的输入顺序与我最初测试的顺序相同。这是我的 3x3 viewprojection 矩阵缓冲区的外观:
我在顶部手动写了缓冲区值对应的矩阵行/列。底部的三个值只是填充以确保我的缓冲区大小是 16 的倍数。所以......就像在 directx 中一样:
- m00 = 矩阵第 1 行、第 1 列
- m01 = 矩阵第 1 行、第 2 列
- ETC
右侧的红色值表示我的 ViewProjection 矩阵如何访问 hlsl 代码中的缓冲区。
出于某种原因,它将其视为 float4x4?这可能是我的问题......还是我在解决我的问题方面的轨道
-更新-
我做了一些研究,现在假设 float3x3 在存储在寄存器中时会变得碎片化(因为它被打包成 4 个浮点组)。
现在看来,即使我的应用程序完全是 2D 的,由于这种烦人的行为,我仍然应该使用 4x4 矩阵。这是正确的,还是有一些我不知道的解决方法?