2

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 を使用して頂点バッファーをチェックし、頂点が頂点シェーダーに入る順序を確認しました。 バッドスプライト1

それで問題ないようでした。次に、私が投稿したシェーダー コードに示すように、viewprojection マトリックスを追加して、頂点をスクリーン スペースに投影しました。結果... バッドスプライト1

ご覧のとおり、頂点が正しく投影されていません。手始めに:

  • prim0vert0 = prim0vert1
  • prim1vert4 = prim1vert5

異なる頂点値が処理されているため、これは私には意味がありません。UV 座標を見ると、最初のテストと同じ順序で頂点が入力されていることがわかります。これは、私の 3x3 ビュープロジェクション マトリックス バッファがどのように見えるかです。

ここに画像の説明を入力

バッファ値が対応する行列の行/列を上に手動で書きました。一番下の 3 つの値は、バッファー サイズが 16 の倍数になるようにパディングするだけです。つまり、directx のように:

  • m00 = マトリックス行 1、列 1
  • m01 = 行列の行 1、列 2

右側の赤い値は、ViewProjection マトリックスが hlsl コードのバッファーにアクセスする方法を表しています。

何らかの理由でそれをfloat4x4として扱っていますか?それは私の問題でしょうか...それとも私は問題を解決するのに道のりを歩んでいますか

-アップデート-

私は少し調査を行い、現在、float3x3 がレジスタに格納されるときに断片化されるという仮定の下で作業しています (4 つの float のグループにパックされているため)。

私のアプリケーションが完全に 2D であっても、この迷惑な動作のために 4x4 マトリックスを使用する必要があるようです。これは正しいですか、それとも私が知らない回避策がありますか?

4

1 に答える 1

1

最新のグラフィック ハードウェアは、4x4 バイト ベクトル、つまり 4 つの浮動小数点値で動作するように設計/最適化されています。float3 ベクトルを使用する場合でも、内部的には float4 を保持する単一のレジスタを占有しています。

ベクトル計算が正しく機能するためには、各ポイントは 16 バイト アラインされたアドレスから開始する必要があります。これは、float3xN の場合に問題になります。

したがって、データを 16 バイト アラインメントにパディングする必要があります。float4x3 を使用してみてください。内部的には、float3x3 操作は引き続き float4x3 のスペースを占有します。

于 2016-04-05T08:11:27.153 に答える