次の方法で共有


チュートリアル: ピクセル シェーディングによるオブジェクトの不足

このチュートリアルでは解除されたピクセル シェーダーによって見つからないオブジェクトを調査するために Visual Studio ののグラフィックス診断ツールを使用する方法を示します。

このチュートリアルでは、次の作業について説明します。

  • [グラフィックス イベント一覧] を使用して、問題の原因となる可能性がある部分を検索します。

  • DrawIndexed Direct3D API の効果を調べます [グラフィックス パイプライン ステージ] ウィンドウを使用して呼び出します。

  • シェーダー ステージが設定されていないことを確認するためにデバイス コンテキストをチェックします。

  • 解除されたピクセル シェーダーのソースを突き止めることができます。[グラフィックス イベント呼び出し履歴] とともに [グラフィックス パイプライン ステージ] ウィンドウを使用します。

シナリオ

オブジェクトは、3-D アプリケーションでないと、オブジェクトの前にシェーダー ステージの 1 種類が設定されていないため、です。 単純なアプリケーションでは、通常、描画オブジェクトの描画呼び出し履歴は、このエラーのソースの場所にある必要があります。 ただし、最適化に、アプリケーションは共通のシェーダー プログラム、テクスチャ、およびそのほかのデータの状態の変更によるオーバーヘッドを最小化するオブジェクトを参照してください。 これらのアプリケーションでは、エラーの原因は、描画呼び出し履歴に存在するのではなく、システム セクションで、埋められる場合があります。 このチュートリアルのシナリオは、単純な描画の必要があると、このエラーの原因は、呼び出し履歴でアプリケーションを検索できます。

このシナリオでは、テストのアプリケーションを実行すると、背景は予期したとおりに表示されますが、オブジェクトの 1 つが表示されません。 グラフィックス診断を使用すると、グラフィックス ログに問題をキャプチャして、アプリケーションのデバッグを実行できます。 問題は、アプリケーションでは次のように見えます。

オブジェクトを表示できません

調査

のグラフィックス診断ツールを使用して、テスト中にキャプチャされたフレームを検査するグラフィックス ログのドキュメントを読み込むことができます。

グラフィックス ログのフレームを調査するには

  1. Visual Studioで、オブジェクトの欠落を表すフレームを含むグラフィックス ログのドキュメントを読み込んでください。 新しいグラフィックス ログのタブが Visual Studio に表示されます。 このタブの上部に、選択されたフレームのレンダー ターゲットが出力されます。 下部の [フレーム一覧] には、キャプチャされた各フレームがサムネイル イメージとして表示されます。

  2. [フレーム一覧] で、オブジェクトが表示されないことを示すフレームを選択します。 レンダー ターゲットが更新され、選択したフレームが反映されます。 このシナリオでは、グラフィックス ログのタブは次のように表示されます。

    Visual Studio のグラフィックス ログ ドキュメント

問題を示しているフレームを選択したら、[グラフィックス イベント一覧] を使用してそのフレームを診断できます。 [グラフィックス イベント一覧] でこのフレームのアクティブにし、デバイスの状態の設定、作成、および更新するためにバッファーを作成、およびフレームに表示されるオブジェクトの描画に含まれているすべての Direct3D API 呼び出しを示します。 アプリケーションが期待どおりに動作しているとき () がレンダー ターゲットに対応する変更が常に存在するため、呼び出し例の多くの種類の描画、ディスパッチ、コピー、またはクリア呼び出しは重要です。 描画呼び出しは、それぞれがアプリでレンダリングされたジオメトリを表すので特に重要です。

他のエラーが発生しないようにはありません。レンダー ターゲットが欠落しているオブジェクトが含まれませんが、ことがわかっているため [グラフィックス パイプライン ステージ] ツールとともにどの描画呼び出しが欠落しているオブジェクトのジオメトリに対応するかを判断するために [グラフィックス イベント一覧] を使用できます。 [グラフィックス パイプライン ステージ] ウィンドウには、各描画呼び出しに対して送信されたジオメトリが、レンダー ターゲットに与える影響には関係なく表示されます。 描画呼び出し間を移動するレンダー ターゲットの状態を示すようにする呼び出しが完了した後で、それぞれの有効な段階を経由する、レンダー ターゲットの出力が更新されますで各呼び出しに関連付けられたジオメトリを示すために、パイプライン ステージが更新され。

表示されないジオメトリの描画呼び出しを見つけるには

  1. [グラフィックス イベント一覧] ウィンドウを開きます。 グラフィックス診断ツール バーで、[イベント一覧] を選択します。

  2. [グラフィックス パイプライン ステージ] ウィンドウを開きます。 グラフィックス診断ツール バーで、[パイプライン ステージ] を選択します。

  3. [グラフィックス イベント一覧] ウィンドウの各描画呼び出しを移動する中で、欠落しているオブジェクトがあるかどうか [グラフィックス パイプライン ステージ] ウィンドウで確認してください。 この操作を簡単に行うには、[グラフィックス イベント一覧] ウィンドウの右上隅にある [検索] ボックスに「Draw」と入力します。 これによって一覧がフィルター処理され、タイトルに "Draw" を含むイベントのみが一覧に表示されます。

    [グラフィックス パイプライン ステージ] ウィンドウで、[入力アセンブラー] ステージには変換後の変換され、[頂点シェーダー] ステージが同じオブジェクトを参照するために、そのオブジェクトのジオメトリを示します。 このシナリオでは、[グラフィックス パイプライン ステージ] ウィンドウが [入力アセンブラー][ 頂点シェーダー] ステージを示しますが、描画の 1 のない [ピクセル シェーダー] ステージを呼び出したことに注意してください。

    注意

    (ハル シェーダー、ドメイン シェーダー、ジオメトリ シェーダー ステージ プロセス ステージのもう一つのオブジェクトが、それが問題の原因である可能性があります。通常、結果が表示されない、または予期しない方法で表示される問題は、最も早いステージに関連しています。

  4. 欠落したオブジェクトに対応する描画呼び出しに達したら停止します。 このシナリオでは、[グラフィックス パイプライン ステージ] ウィンドウはアクティブなピクセル シェーダーがしません。、ジオメトリが GPU ([入力アセンブラー] ステージの有無によって示されます) が発行され、([頂点シェーダー] ステージで表示) 変換されたか、レンダー ターゲットで表示されません ([ピクセル シェーダー] ステージの欠落していないことを示します)。 このシナリオでは、[出力マージャー] が欠落しているオブジェクトのシルエットがステージング"を参照する:

    DrawIndexed イベントとパイプラインに対するその効果

アプリケーションによってオブジェクトのジオメトリの描画呼び出しが発行確認し、ピクセル シェーダー ステージにはアクティブでなかったことを知ることが後、調査結果を確認するデバイスの状態を調べることができます。 デバイス コンテキストとそのほかの Direct3D オブジェクト データの調査に [グラフィックス オブジェクト テーブル] を使用できます。

デバイス コンテキストを確認するには

  1. [d3d11 デバイス コンテキスト] を開きます。 [グラフィックス パイプライン ステージ] ウィンドウで、ウィンドウの上部に表示される DrawIndexed の呼び出しの一部である [ID3D11DeviceContext] リンクをクリックします。

  2. ピクセル シェーダーは、描画呼び出し中にアクティブではないことを確認するに [d3d11 デバイス コンテキスト] タブに表示されているデバイスの状態を確認します。 このシナリオでは、[シェーダーの一般情報] は— [ピクセル シェーダーの状態] の下に表示される—シェーダーが [NULL] であることを示します。:

    D3D 11 デバイス コンテキストはピクセル シェーダーの状態を示します

ピクセル シェーダーはアプリケーションで無効にするに設定されていることを確認したら、次にシェーダーが設定されたアプリケーションのソース・コードの位置を検索することです。 [グラフィックス イベント呼び出し履歴] とともにこの場所を検索するに [グラフィックス イベント一覧] を使用できます。

ピクセル シェーダーがアプリケーションのソース・コード内で設定されている場所を検索するには

  1. 欠落したオブジェクトに対応する PSSetShader の呼び出しを探します。 [グラフィックス イベント一覧] ウィンドウで、「Draw;を入力します。[グラフィックス イベント一覧] ウィンドウの右上隅にある [検索] ボックスの PSSetShader」。 これは「PSSetShader」イベントのみを含む、イベントをフィルター処理する場合は、タイトルに「Draw」を含むリストを返します。 前に欠落しているオブジェクトの描画呼び出し表示 PSSetShader の最初の呼び出しを選択します。

    注意

    PSSetShader は [グラフィックス イベント一覧] ウィンドウでこのフレームの間に設定されていない場合は表示されません。通常は、1 ピクセル シェーダーがすべてのオブジェクトで使用されている場合、または PSSetShader の呼び出しがこのフレームの間に意図せずにとばされたら発生します。どちらの場合も、PSSetShader の呼び出しをアプリケーションのソース・コードを検索する推奨し、これらの呼び出しの実行を確認する従来のデバッグ手法を使用します。

  2. [グラフィックス イベント呼び出し履歴] ウィンドウを開きます。 グラフィックス診断ツール バーで、[グラフィックス イベント呼び出し履歴] を選択します。

  3. アプリケーションのソース・コードで PSSetShader の呼び出しは、呼び出し履歴を使用します。 [グラフィックス イベント呼び出し履歴] ウィンドウで、ピクセル シェーダーに設定されている最上位の呼び出しを選択し、値を調べます。 ピクセル シェーダーを null に直接設定するか、または null 値は、関数またはそのほかの状態に渡された引数の場合に発生することがあります。 これを直接設定されていない場合、呼び出し履歴の最上位に null 値をどこかに見つけることができる場合もあります。 このシナリオでは、ピクセル シェーダーが CubeRenderer::Renderという名前の最上位の関数の nullptr に直接設定されていることを検出します:

    ピクセル シェーダーを初期化しないコード

    注意

    呼び出し履歴を調べることで null 値を見つけることができない場合、ピクセル シェーダーが null に設定されている場合は、プログラムの実行を中断できます。PSSetShader の呼び出しの条件付きブレークポイント設定を、のようにお勧めします。その後、デバッグ モードでアプリケーションを再起動し、null 値の原因を突き止める従来のデバッグ手法を使用します。

この問題を解決するには、ID3D11DeviceContext::PSSetShader API 呼び出しの最初のパラメーターを使用して正しいピクセル シェーダーを割り当てます。

修正された C++ ソース コード

コードを修正したら、それを再度ビルドし、描画問題が解決されたことを検証するためにアプリケーションを再度実行する場合:

オブジェクトが現在表示されています