DirectX12で1からフレームワーク制作(6)
はじめに
こんにちは、はろ~です。
第5回からかなり時間が空いてしまったことをお詫びします。
それと同時に以前使用していたアカウントがログイン出来なくなってしまったので今後はこちらで投稿させて頂きます。
今回は、モデルにテクスチャを貼り付けてZBufferを設定するところまでやっていきます。
開発環境はお馴染みVisualStudio2022です。
Github:https://github.com/nakanoyui/DirectX12Framework
諸々の修正
先に諸々の修正をさせてください。
Application.cppのWinMain関数でComポインタの初期化時にマルチスレッド指定してましたが、管理は自分でしたいのでオプションをMULTITHREADEDからAPARTMENTTHREADEDに変更しておいてください。私の環境ではデストラクタ時に破棄したインスタンスに参照しようとして何度も警告を食らいました。
ApplicationクラスのExcute関数ですが正しくは「Execute」です。訂正お願いします。
モデルにテクスチャを貼る
ではさっそくモデルにテクスチャを貼っていきましょう。
前回モデルをロードするために作ったModelLoaderなんですが、オプションを全部とりあえず入れていたのですが不必要なものがあったのでModelLoader.cppから以下を削除しておいてください。
で、何かしていくのかと思いきや実は処理自体は前回で実装しているのでモデルデータにテクスチャを教えてあげるだけで大丈夫です。
現在のAsset/Model/Cubeフォルダの中は以下の通りになっていると思います。
ここの「Cube_Diffuse.png」を違うテクスチャに差し替えるだけで大丈夫です。
※画像用意が難しそうだったらhttps://github.com/nakanoyui/DirectX12Framework こちらから落としてもらったプロジェクトのCubeフォルダをそのままお使いください。
私はアイコンの画像にしてみました。
さて実行してみると、以下のように少し不細工なテクスチャが貼られてしまいました。
理由として二つあるのですが、まず分かりやすい方から対処していきます。
モデルのUV
さっそく答えから言っちゃいますが、モデルのUVがおかしいのが原因です。
Shaderの出力色をUVにしてみましょう。
SimpleShader_PS.hlslを書き換え見てください。
すると、以下のような出力色になったと思います。
第四回の時に案内した正しいUVは下記の通りです。
それぞれU値とV値が間隔0.5くらいしかなさそうに見えますね。直していきましょう。
下記が直したときの正しいUV値です。
ではSimpleShader_PSの方も元に戻しておきましょう。
実行してみると、テクスチャはしっかり貼られていますね!
深度バッファ
実はこのフレームワークですがモデルや板ポリの描画とほぼほぼこれだけでもゲームを作れそうな香りを醸し出し始めたんですが、欠陥フレームワークなんです(笑)
その欠陥部分を見てもらうために下記に変更を加えていきましょう。
Application.cppを以下の実装に変更してください。
読者の方はZ値1ということは今回転してたモデルの奥だからこれ見えなくね?と思われると思います。それは正しい答えなんですが今のままだとバグって両方描画されちゃいますw
さてここから直していきましょう。まずなぜああいった描画結果になってしまったのか答えから言うと深度バッファを設定していないからです。深度バッファとはZ値を考慮したいときに設定するテクスチャになります。もう少し詳しく言うと射影空間上の0~1のZ値をテクスチャの書き込みラスタライザステートにてZ比較を行い、値が小さい方を採用してZ値を塗り直して描画を行っていくものになります。これがないと深度比較が出来ないのもそうですが、手前のオブジェクトで隠れているオブジェクトがあった際に普通なら描画処理を走らせなくていいところをピクセルシェーダーが走ってしまって無駄な処理が発生しボトルネックになってしまうという問題が生じます。
長々と話してしまいましたが、以上の理由から深度バッファは必要不可欠な存在です。
さっそく実装していきましょう。
Graphics/Heapフォルダの中にDSVHeapというフォルダを作成し、その中にDSVHeap.cpp/.hを追加してください。
DSVHeap.hの実装は以下の通りです。
DSVHeap.cppの実装は以下の通りです。
いつものようにSystem.hにDSVHeap.hを追加しておいてください。
さてここでいつも通りBufferクラスも作成していくのですが、定数バッファ・シェーダリソース・深度バッファと同じようなクラスが三つ存在するようになるのでBufferという基底クラスを作成してリファクタリングを行っておきましょう。
GraphicsにBufferフォルダを作成してBuffer.hを作成してください。
Buffer.hは以下の実装です。
先にCBufferAllocaterとTextureクラスをこのBufferクラスを継承させる作りに書き換えます。
フォルダ構成のBufferフォルダ以下に二つのフォルダを配置するようにしましょう。
CBufferAllocater.hの実装以下の通りです。
System.hにBufferを追加するのを忘れていたので追加しておきましょう。
それと同時にそれぞれのクラスのパスを変更したのでバッファのパスを正しく変更しておきましょう。
Texture.hの実装は以下の通りです。
さて本題の深度バッファの実装を行っていきましょう。
BufferフォルダにDepthStencilというフォルダを作成し、DepthStencil.cpp/.hを作成してください。
DepthStencil.hの実装は以下の通りです。
DepthStencil.cppの実装は以下の通りです。
System.hにDepthStencil.hを追加しましょう。
では実際にDepthStencilとDepthHeapを使用していきましょう。
GraphicsDevice.hの実装を以下のように更新してください。
GraphicsDevice.cppの実装を以下のように更新してください。
最後にApplication.cppのRenderingSettingsのDepth設定を指定している箇所を削除すれば完成です。
実行すると奥のモデルが描画されなくなったと思います。
最後に
お疲れ様でした。久しぶりに記事を執筆したので結構疲れましたが、なんとか書き終えました~。
かなりの実装とリファクタリングをしていきましたが、途中でバグが発生した際はまず、どこから起きたかを確認して自身でバグを取る挑戦をしてみてください!分からなかったらX(旧Twitter)で連絡くださっても大丈夫です。
今後も続きを記事にするつもりですが、更新頻度に関しては不定期になります。(気が向いたら更新します)
Discussion