読者です 読者をやめる 読者になる 読者になる

catalinaの備忘録

ソフトウェアやハードウェアの備忘録。後で逆引きできるように。

DirectX11で複数のモデルを表示

DirectX11では昔(DirectX 8の時代)のやり方が通用しなかったのでメモ。
行列の管理のあたり。


1、モデルごとに行列を設定する方法

まずは結論のコードから。
VisualStudio Express12が吐き出したDirectXのスケルトンコードに対して変更を加えるならば、次のとおり。
このコードをモデルごとに実行すればよい。
(ただし、VisualStudioのスケルトンに対してこのコードを追加すると、多数のモデルを表示する場合の効率が悪い)

 

    XMMATRIX tmp = XMMatrixMultiply(rotx, roty);
    XMMATRIX tmp2 = XMMatrixMultiply(tmp, rotz);
    XMMATRIX tmp3 = XMMatrixMultiply(scale, pos);
    XMMATRIX all = XMMatrixMultiply(tmp3, tmp2);
    XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(all));
    d3dContext->UpdateSubresource(
        constantBuffer,             // コピー先リソース
        0,                          // コピー先リソースのインデックス番号
        NULL,                       // コピー先サブリソース部分を定義する3Dボックス
        constantBufferData,         // コピー元のアドレス
        0,                          // コピー元データの一行のサイズ
        0                           // コピー元データの深度スライスのサイズ
        );

 

2、コードの詳細

1、モデル、ビュー、プロジェクション変換行列を格納するための構造体を宣言
2、1で定義した構造体の領域をシステムメモリ上に確保
3、2で確保した構造体にパラメータをセット(上記コード)
4、3でセットした情報をVRAMに転送(UpdateSubresource)
5、頂点シェーダで演算を行う

 

この動作のうち、上記コードでは3~4を行っている。
これ以外は、VisualStudioが吐き出したスケルトンにコードが含まれている。

今回の簡単な改造では効率(ソフトウェア品質時間効率性)がよろしくない。
というのも、複数のモデルを表示するために変更が必要なのはmodel行列のみのはずである。
ところがUpdateSubresourceで「model, view, projection」すべてがVRAMに転送される。(上記コードには現れてはいないが、constantBufferDataの型を参照するとわかる。)

改善案としては、model, view, projectionをそれぞれ個別の定数バッファに格納してやる方法が考えられる。

modelをどう扱うかは設計方針によると思われる。
(モデルごとに定数バッファをVRAM上に取るか、定数バッファは1つとしモデルごとに使いまわす)
シェーダーのことも考えると、時間効率性か資源効率性かという話になるのかもしれない。