オブジェクトごとに異なるシェーダーDirectX 11


13

私はを学習Direct3D 11しています。シェーダーの作成で見つけたすべての基本的なチュートリアルでは、VertexシェーダーとPixelシェーダーが書かれているため、シーン全体を同じように変換できます。テクスチャ付きキューブのレンダリングのようなチュートリアル...

しかし、どうやってオブジェクトを区別するのでしょうか。たとえば、あるオブジェクトの鏡面をシミュレートし、別のシェーダーを使用して残りのシーンをレンダリングしたい場合はどうでしょうか?ほとんどのゲームでは、さまざまな外観と変換を実現するために、多くの頂点シェーダーとピクセルシェーダーを使用する必要があると思います。

ありがとうございました。

回答:


23

はい、ゲームエンジンには一般にさまざまな異なるシェーダーがあります。典型的なパターンは次のとおりです。

  1. エンジンを初期化し、ゲームの世界をロードしながら、レンダリングに使用するすべてのシェーダーを準備します。「準備」とは、それらをメモリにロードし、必要に応じてコンパイルしID3D11Device::CreatePixelShader、D3Dシェーダーオブジェクトを割り当てて準備ができるように、すべての同様の呼び出しを実行することを意味します。オブジェクトを配列またはその他のデータ構造に保持します。

    通常、連携するように設計された頂点シェーダーとピクセルシェーダーの間には1対1の関係があります。頂点シェーダーとピクセルシェーダー(おそらくジオメトリ/ハル/ドメインシェーダーも含む)が実際に含まれているとしても、それらを「シェーダー」と呼ぶ単一のオブジェクトと考えています。

  2. 各フレームで、レンダリングするオブジェクト(メッシュ)のリストを見つけたら、シェーダーで並べ替えます。特定のシェーダーを持つすべてのオブジェクトを一緒に描画することで、フレーム内のシェーダーを切り替える回数を最小限に抑えるという考え方です。(あなたは確かにフレームごとにその数百または数千回を行うことができますが、それは本当にありませんので、シェーダを切り替えはやや高価な操作であるためであること、高価な)。

    実際、1つ先に進んで、最初にシェーダー、次にマテリアルでメッシュを並べ替えることができます。「マテリアル」とは、シェーダーと一連のテクスチャーとそのパラメーターの組み合わせを意味します。シェーダーには通常、それらにフィードするいくつかのテクスチャーと数値パラメーター(定数バッファーに格納)があるため、たとえば、レンガマテリアルとアスファルトマテリアルは、異なるテクスチャーだけで同じシェーダーコードを使用する場合があります。

  3. 描画するには、シェーダーをループし、で各シェーダーをID3D11DeviceContext設定し、パラメーター(定数バッファー、テクスチャなど)を設定してから、オブジェクトを描画します。私が言及したシェーダー/マテリアルの区別を含む疑似コードで:

    for each shader:
        // Set the device context to use this shader
        pContext->VSSetShader(shader.pVertexShader);
        pContext->PSSetShader(shader.pPixelShader);
    
        for each material that uses this shader:
            // Set the device context to use any constant buffers, textures, samplers,
            // etc. needed for this material
            pContext->VSSetConstantBuffers(...);
            pContext->PSSetConstantBuffers(...);
            pContext->PSSetShaderResources(...);
            pContext->PSSetSamplers(...);
    
            for each mesh that uses this material:
                // Set any constant buffers containing parameters specific to the mesh
                // (e.g. world matrix)
                pContext->VSSetConstantBuffers(...);
    
                // Set the context to use the vertex & index buffers for this mesh
                pContext->IASetInputLayout(mesh.pInputLayout);
                pContext->IASetVertexBuffers(...);
                pContext->IASetIndexBuffer(...);
                pContext->IASetPrimitiveTopology(...)
    
                // Draw it
                pContext->DrawIndexed(...)
    

オブジェクト、メッシュ、シェーダー、入力レイアウト、定数バッファーなどの管理については他にも多くのことが言えますが、これで十分です。:)


シェーダーで並べ替え、次にマテリアルで並べ替えを提案します。シェーダーの切り替えとマテリアルの切り替えのコストに関するハードデータはありますか?ああ、DX9の場合、VS / PSの組み合わせは「プログラム」と呼ばれます。彼らがDX11でその用語をまだ使用しているかどうかはよくわかりません。
パンダパジャマ

1
@PandaPajamaいい質問ですね。いいえ、マテリアルやシェーダーの切り替えの実際のコストに関する最近の測定値はありません。このアプローチは何年もの間「常識」でしたが、状況がどのように変化したかを確認するために実際の測定を行うことは価値があります...時間を見つけることができればそれを行うかもしれません。:)
Nathan Reed
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.