2

==================== 編集: 解決策 =====================

私はついに問題を発見しました.答えはDirectXを学んでいる初心者にとって重要かもしれないので、ここに投稿します. (私は DirectX への .NET ラッパーとして F# と SharpDX を使用しています)

私のプログラムでは、リソース (バッファー、ビューなど) は、スワップ チェーンのサイズが変更されたときにのみ変更されます。したがって、すべてのリソース割り当て (IA、OM、VS、PS) を function に入れますswitchTo2DLayout。スワップ チェーンのサイズが変更されていないswitchTo2DLayout場合は、(何もせずに) すぐに戻ります。これはフラグによって制御されます。

後で、このフラグがリセットされないことがわかったので、すべての描画呼び出しの前にリソース割り当てが行われました。この間違いを修正しましたが、画像は への最初の呼び出しでのみレンダリングされましたrenderPixels。ドローコールの前にShaderresourceView 毎回設定する必要があることがわかりました。

let renderPixels () =
    switchTo2DLayout()

    // this line was missing:
    context.PixelShader.SetShaderResource(COUNT_COLOR_SLOT, countColorSRV_2D)

    context.ClearRenderTargetView (renderTargetView2D, Color.White.ToColor4())
    context.Draw(4,0)                                                
    swapChain.Present(1, PresentFlags.None)  

これは私にとってまったく予想外でした。私が使用する DirectX に関する書籍では、(設定が変更されない限り) 1 回割り当てられるリソースと、描画呼び出しごとに割り当てられる必要があるリソースについて明示的に述べていません。

メッシュ レンダリングでは、同様の設定を使用します (ここでは前述のバグはありません)。また、同等の行がありませんでした。

let draw3D() = 
    switchTo3DLayout()

     // this line was missing:
     context.VertexShader.SetShaderResource(TRIANGLE_SLOT, triangleSRV  ) 

     context.ClearDepthStencilView(depthView3D, DepthStencilClearFlags.Depth, 1.0f, 0uy
     context.ClearRenderTargetView(renderTargetView2D, Color4.Black )                                                            
     context.Draw(triangleCount, 0)
     swapChain.Present(1, PresentFlags.None)    

これは、2D レンダリングがバグ (ピクセル シェーダーがバッファーから読み取る) のために機能し、3D レンダリングが機能しなかった (頂点シェーダーがバッファーから読み取る) 理由を説明しています。

======================= 私の元の投稿: =================

数日前に問題を投稿しました [リンク:]頂点バッファーを使用せずに計算シェーダーの結果を頂点シェーダーにフィードするにはどうすればよいですか? それはおそらく複雑すぎて答えられませんでした。その間、セットアップをより単純なケースに落とし込みました。

struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
};

RWStructuredBuffer<float4> colorOutputTable :  register (u5);
StructuredBuffer<float4> output2 :             register (t5);  

ケース A: ピクセル シェーダーが色を設定する (機能する)

// vertex shader A

PS_IN VS_A  ( uint vid : SV_VertexID )  
{
    PS_IN output = (PS_IN)0;   
    if (vid == 0) output.pos = float4(-1, -1, 0, 1);
    if (vid == 1) output.pos = float4( 1, -1, 0, 1);
    if (vid == 2) output.pos = float4(-1,  1, 0, 1);    
    if (vid == 3) output.pos = float4( 1,  1, 0, 1);    

    return output;  
}

// pixel shader A

float4  PS_A ( float4 input : SV_Position) : SV_Target
{        
  uint2 pixel =  uint2(input.x, input.y);       
  return output2[ pixel.y * width + pixel.x];   // PS accesses buffer (works)

}

ケース B: 頂点シェーダーが色を設定する (機能しない)

// vertex shader B

PS_IN VS_B ( uint vid : SV_VertexID )   
{
    PS_IN output = (PS_IN)0;   
    if (vid == 0) output.pos = float4(-1, -1, 0, 1);
    if (vid == 1) output.pos = float4( 1, -1, 0, 1);
    if (vid == 2) output.pos = float4(-1,  1, 0, 1);    
    if (vid == 3) output.pos = float4( 1,  1, 0, 1);    
    output.col = output2[vid];  // VS accesses buffer (does not work)
    return output;  
}

// pixel shader B

float4 PS_B  (PS_IN input ) : SV_Target
{
    return input.col;
}

明らかに、ピクセル シェーダーは "output2" バッファーにアクセスできますが、頂点シェーダーはアクセスできません(読み取りは常にゼロ)。

インターネットを検索しても、この動作の説明は見つかりませんでした。私の「実際の」アプリケーションでは、計算シェーダーが三角形のリストを計算し、それを RWStructuredBuffer に格納するため、頂点シェーダーから (マップされたスロットを介して) このテーブルにアクセスする必要があります。

コンピューティング シェーダーを使用する多くの人が、この問題に遭遇する可能性があると思います。これを解決する方法はありますか?(現在、レベル 11.1 または 11.2 を使用できません。11.0 に基づく解決策を見つける必要があります)

4

1 に答える 1