「 DirectX11 」一覧

ソフトパーティクルの実装方法


テクスチャとして読み込むデプスバッファと、アウトプットマージャーにセットしたデプスバッファでデプステストを使っての事例として、ソフトパーティクルがお題に合致している感じだったので試してみました。
ようやく読み込み専用 DepthStencilView を意味あるものとして使えたかなと思います。

ソフトパーティクル

ソフトパーティクルとは、パーティクルに使用するビルボードとモデルや背景の境界部分をぼかすことによって、ハードなエッジを見せないようにするための技法です。
ハードなエッジとは以下のようなものです。ソフトパーティクルを無効化して描画したものになります。

続きを読む



読み取り専用 DepthStencilView


今更ですがディファードレンダリングのコードを書いていました。ポイントライトをたくさんおける仕組みなのがいいですね。
古いタイプのレンダリングコードとはまた違った感じで、入力は既に描画したテクスチャを参照してデータが入ってくるのは新鮮でした。

そのときに、既に描画済みのデプスバッファを参照しつつも、デプステストは有効にしたいというようなケースでワーニングに出遭ってしまいました。

リソースハザードの発生

今回の場合では、デプスバッファがシェーダーへの入力と、パイプラインの出力(出力マージャー)に設定されているために、リソースハザードの警告が発生しました。
デプスステンシルステートで、 D3D11_DEPTH_WRITE_MASK_ZERO を設定して、書き込まれないようにしていてもこの警告は発生します。

ピクセルシェーダーで ShaderResource として読み込む設定だったため、以下の警告が VisualStudio で表示されました。

対応策

今回の例では ID3D11DepthStencilView をもう1つ作成することになりました。
読み込み専用としての ID3D11DepthStencilView を作成します。これは以下のようにして作成します。
フラグに D3D11_DSV_READ_ONLY_DEPTH を設定するのがポイントです。難点はこのフラグの存在に気付きにくいことでしょうか。

今更ですが、デプスバッファをテクスチャとして読み込むためには、デプステクスチャ作成時に BindFlags を D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE で作成します。このとき、フォーマットは DXGI_FORMAT_D32_FLOAT ではなく、 DXGI_FORMAT_R32_TYPELESS を使って作成しておく必要がありました。
DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D32_FLOAT のフォーマットを指定して、各ビューの作成を行います。

感想

現時点においては簡単なものしか入れていないため、まだデプスバッファをINにもOUTにも設定して有効活用するといったところまでは到達していません。やろうと思ったら今までに説明した内容に出遭ってしまったので記事にしてみました。

デプスバッファを出力マージャーに設定しておきたいのはデプステストや Depth Bounds Test とかを活用したいという狙いです。
あとは、デプスを入力として参照したかったのは SSAO や ワールド位置の復元をこのバッファから出来れば、G-buffer に出さなくていい(削減できる)と考えたからです。


EXT_external_objects の実験


OpenGL 4.6 の発表の中で、各Graphics API との Interop の話がありました。
ここで、EXT_external_objects 拡張 (スライドでは EXT_memory_object となっていましたが) が、面白そうだったので触ってみました。
ただしこの内容は OpenGL 4.6 に含まれるものではなく、追加という位置付けとなっているようです。

説明など

この EXT_external_objects 拡張は、 OpenGL に他の API で作成されたオブジェクトを利用するためのものとなっているようです。
提供される API 群は、こちらの仕様の方を確認してください。

OpenGL にとっての外部メモリを利用して、OpenGL のリソースを生成する(インポートする)といった感じで、機能が準備されています。

続きを読む


Vulkan へ DirectX11 テクスチャをインポート


世の中の多くの Windows 環境で安定して使えるグラフィックス API は DirectX11 や OpenGL といったところだと思います。
Vulkan API は新しい API のため、既存のライブラリやフレームワークではまだサポートされていなかったりします。そのような状況のためか、 NIVIDA の Vulkan Extension では、 Vulkan とその他 API でやりとりするための機能が用意されました。

また現時点においては、 Khronos の KHX 拡張としても整備が進みそうな気配です。NVIDIA だけでなくサポート範囲が広がってくれることに期待です。

続きを読む



Windows Server 2016 で RemoteFX GPU の実験


Windows Server 2016 で個人的に魅力的に感じている RemoteFX 仮想 GPU について実験してみました。

Windows Server 2016側の準備

Hyper-V の役割だけでなく、リモートデスクトップ仮想化ホスト の役割もインストールして RemoteFX を使えるようにします。
今回の環境では Intel HD Graphics のドライバがうまく適用できなかったので、
Radeon 7750 を装着して DirectX, OpenGL が動くようにしました。
ちなみに最近のドライバをインストールしましたが、 WHQL 非取得でしたが、 7750 でも Vulkan も動きました。
(vulkaninfo を実行できて、情報が色々と表示されました)。

第2世代仮想マシンでは RemoteFX GPU が使えないという情報があったので、
仕方なく第1世代仮想マシンを作成し、 Windows10 Pro をインストールしました。

ちなみに 第2世代仮想マシンで RemoteFX GPU がちゃんと動いたという情報もあるのですが、
現時点においては正式なサポートというわけでもないようなので、まずは第1世代で試したというわけです。
続きを読む


BC7の圧縮ノイズについて調べてみた


優秀だという BC7 圧縮の品質がどんなものか調べてみました。
そのためにはそこそこの品質以上の画像データが必要だったので友人に協力してもらい画像を使わせてもらっています。
この場を借りてお礼申し上げます。

BC7への圧縮については Codeplex からダウンロードできる Microsoft の TexConv を使用しています。この最高品質となる CPU で処理した結果ではなく、 GPU を用いた速度とのバランスがとれているであろうモードを選択しています。

比較

いきなりですが圧縮前後の画像を比較してみます。
左が圧縮前、右が圧縮後のデータです。圧縮ノイズなどは確認できるでしょうか?自分では等倍でぱっと見た感じわかりませんでした。心持ち髪の毛曲線部とアルファの部分でノイズが気になるかも程度です。
compare_std_bc7_sample01
compare_std_bc7_sample02

続きを読む


DirectX11の場合のシステムメモリとVRAM消費について


今までは OpenGL の場合を調査してきました。今回は DirectX11の場合を調べてみようと思います。ドライバが一緒ならきっと同じ傾向を示すんじゃないかなと予想して実験をスタートです。

実験

DirectX11のプログラムとして、100フレームごとに頂点バッファ 32MB を確保し、次フレーム以降はこのデータを使って描画するプログラムを作成しました。
各フレームでの各メモリの使用状況を取得して、グラフ化しました。

実験は以下の環境で行いました

  • GTX750Ti Windows 7 347.09
  • RADEON HD 5450 Windows 7
  • RADEON HD 5450 Windows 8

結果

それぞれの実験結果のグラフを以下に示します。

nvidia_memory_graph_dx11_win7

radeon_memoy_graph_dx11_win7

radeon_memoy_graph_dx11_win8

NVIDIA も AMD も同じような挙動を示す結果となりました。また VRAM が使用可能な状態であれば、追加のシステムメモリの消費もなく良好といえそうです。(とはいっても追加のメモリを要求されたのは NVIDIA OpenGL の場合のみでしたが)。さすが仕様が決まっている DirectX といえるかなと思います。
 ちなみに RADEON のほうのグラフ末尾がおかしなことになっていますが、このときアプリは相変わらずフリーズ状態になってしまいました。ですので、システムメモリを VRAM リソースとして使用始めたらやや注意が必要になっていきそうです。ビデオメモリ仮想化が入ったといわれる現時点においても、なるべく搭載量を超えないようにするのはマナーとしておいたほうがよさそうです。


DirectX11で複数ウィンドウを使ってみる


最近Mach-Oの調査ばっかりやっているので、DirectX11とか触ってるとほっとします。

昨今では2つのディスプレイが繋がっていることも珍しくないと思います。
それぞれに対してDirectXアプリケーションのフルスクリーンやりたいとか、独立した複数ウィンドウでDirectXの描画やりたいとかそういうときにどうしたらよいかを実験してみました。

結論から言えば、複数のデバイスコンテキストを作る必要すら無く、レンダーターゲットビューとスワップチェインを複数持つことでこれらを実現出来ることがわかりました。デバイスが独立ではないのでリソースも共有出来ます。

初期化

DirectX11の初期化部分を説明します。
D3D11CreateDeviceAndSwapChain関数を使用して初期化することは出来ないようで、必要なオブジェクトを順番に作成していく必要があります。まずは D3D11CreateDevice関数でデバイスの初期化、続いて必要な数のスワップチェインの作成となります。
スワップチェインの作成はデバイスから直で出来ず、DXGIのオブジェクトを数回経由する必要があります。

これらの処理をざっくりと以下に示します。

スワップチェインを作成できたら、それぞれのウィンドウ(場合によってはディスプレイ)に対してのバックバッファを作成しておきます。
これはpSwapChain[0]->CreateRenderTargetViewでいつも通りに作成する感じです。必要ならデプスステンシルも作成しておきます。

描画

描画の方は何も難しいことはありません。複数のレンダーターゲットを扱ったことがある人なら意識するような違いがないです。コードを以下に示します。

まとめ

マルチウィンドウにすることでどのくらい2重でデータ持ちしないといけないかと心配しましたが、結構楽に実現出来ることがわかりました。スワップチェインが個別という程度で、他はマルチレンダーターゲットやっているときと変わらない感じです。

今回試してみたプログラムでは以下のようにリソースも1つでそれぞれに描画してみました。

dx11_multi_window