DXライブラリで自作のシェーダを使う方法のあれこれ。先人たちの真似をしたら盛大に躓いたので忘れずにメモ。
※DirectX11を使用する前提になります。DXライブラリはVer3.23d。
DirectX11の仕様に合わせる
2024年現在デフォルトではDirectxは11を使用するようになっている。シェーダの場合DirectX9・9EXとは仕様が異なるため、DXライブラリ本家にあるサンプルコードをそのまま使うとpso/vsoファイルの読み込みに失敗して何も表示されない。
使用するDirectXのバージョンを9EXにすればいいのだが、別記事で書いたEffekseerと連携する場合は11が推奨されるので11に合わせたいところ。
本家のサンプルコードにDirectX11版のものはないが、同サイトのQ&Aに対応したものがあるのでこちらをダウンロードしてコードを編集していく。サイトはこちら。
サンプルコードに手を加えて作っていく場合は必然的に<1頂点へ影響を与えるフレームの数が1~4個のスキニングメッシュのディレクショナルライトあり描画>、もしくは<MMD互換のトゥーンレンダリング スキニングメッシュでディレクショナルライト一つ>を選ぶことになると思う。
頂点シェーダは***VS.fx、ピクセルシェーダは***PS.fxのファイルから編集する(デフォルトではVisual Studioで開くようになっているはず)。pso/vsoファイルは違うので注意。
もちろんHLSLファイルで一から作っても構わない。
シェーダの処理の流れやコードの書き方とかを知りたい場合はこの本がオススメ。
pso/vsoファイルの出力
fxもしくはHLSLファイルをゴリゴリ編集していったあと、pso/vsoファイルに出力してそれを読み込ませる必要がある。
DXライブラリ本体または上の11対応サンプルコードをダウンロード・インストールする際についてくるShaderCompiler.exeを使うとfxファイルからpso/vsoファイルが出力できる。ただし直接ShaderCompiler.exeを起動しても意味がないのでコマンドプロンプトからコマンドを指定する。
コマンドプロンプトを起動してShaderCompiler.exeがあるディレクトリに移動したら以下のようにコマンドを指定する。
psoファイルを作る場合
ShaderCompiler.exe /Tps_4_0 (ピクセルシェーダ用のfx/HLSLファイルのパス)
vsoファイルを作る場合
ShaderCompiler.exe /Tvs_4_0 (頂点シェーダ用のfx/HLSLファイルのパス)
ps_*_*/vs_*_*にはいろいろバージョンがあるが、_4_0以降でないとおそらくエラーが出ると思う(多分プログラマブルシェーダーのバージョンの関係)。
pso/vsoファイルが出力されたら成功。
C/C++側の記述
冒頭にDirectX11がデフォルトで使われると書いたが念のためにDxLib_Init()の前にDirectX11を使用する宣言をする。
// 使用する Direct3D のバージョンを設定 SetUseDirect3DVersion(DX_DIRECT3D_11); // DXライブラリ初期化処理 if (DxLib_Init() < 0) { //エラーなら終了する return -1; }
シェーダーファイルの読み込みと読み込んだシェーダーを使う宣言。
int PixelShaderHandle; int VertexShaderHandle;
// 頂点シェーダーを読み込む VertexShaderHandle = LoadVertexShader("(vsoファイルのパス)"); // ピクセルシェーダーを読み込む PixelShaderHandle = LoadPixelShader("(psoファイルのパス)"); // モデルの描画にオリジナルシェーダーを使用する設定をONにする MV1SetUseOrigShader(TRUE); // 使用する頂点シェーダーをセット SetUseVertexShader(VertexShaderHandle); // 使用するピクセルシェーダーをセット SetUsePixelShader(PixelShaderHandle);
必要最低限のコードを載せたが、他の人にプレイしてもらう目的がある場合は読み込めなかった場合の処理やプログラマブルシェーダーのバージョンの確認処理などが必要。
その他注意事項
ブログ主が嵌った点についていくつか。
シェーダとは直接関係ないが、ウィンドウモードのサイズを変更するSetGraphMode()関数を使っている場合は読み込んだ画像や3Dモデルが一旦破棄されてしまうので画像や3Dモデルの読み込みはこの関数の後で行うこと。
あと上でスキニングメッシュ対応のサンプルコードを取り上げたが、モデルにボーンが無い場合は正しく表示されないので注意。マップ(ステージ)などにも入れておくこと。
同じくスキニングメッシュ対応のサンプルコードを実行してモデルの一部分が固定されて引き伸ばされるような描写になった場合は1頂点へ影響を与えるフレームの数が5つ以上になっている可能性がある。上の11対応のサンプルコードが載っているページに対応策が載っているのでそちらを参考に。
コメント