初めに
ネットには描画プログラムのサンプルやデモは沢山転がっています。しかしながら実際仕事での使い方とは乖離している物もあり、そこの間を埋める資料は無くはないけど少ないので、サンプルを理解した後の次の実践的な実装で悩んでいる人も多いと思います。
細かい事は沢山ありますが、今回は大きい所を2つだけ紹介します。
マルチスレッド
ある程度の規模以上のゲームではゲームスレッドと描画スレッドが分かれています。
自前で定義した描画の書式(描画パケットと言ったり、仮想描画コマンドと言ったりチームよって様々)を積んで、同期タイミングで描画スレッドへ転送、描画スレッドではそれを解釈しながら描画API(Dx12やVulkan)を呼んでいく実装が多いと感じます。
初回の実装は大変ですが、一旦この実装を書いてしまうと、解釈部分にプラットフォームのコードをまとめられるので、その後のマルチプラットフォーム化は楽になる事が多いです。
描画スレッドの実装により、ゲームも描画も同じスレッドで処理していた時に比べ処理速度は大幅に上がりますが、例えばボタンを押してから画面に表示されるまでの応答速度は遅くなる可能性もあるので、ゲームでの重要性を見ながら処理速度と応答速度のバランスを調整する必要があります。
CPU側で書き換える可能性のある頂点やテクスチャのリソースは実装によってはダブルバッファ化する必要があります。
また、描画リソースの開放は描画スレッド側での使用が完了したのを待ってから解放するようタイミングを管理する必要があります。
負荷に困っていない小規模なタイトルでは無理して実装しなくてもいいと思います。
バッファの管理
多くのサンプルではリソース毎に直接APIから確保しています。しかしながらVulkanなどでは確保数に上限があったりするので現実的な実装ではありません。
予め大きなバッファを確保しておいて、それを管理するアロケータ経由で必要な分を確保して使う実装をする必要があります。
ディスクリプタなども同様です。
また、同時に使う事のないレンダーターゲット同士のメモリの共有の仕組みなども節約のために作る事が多いです。
最後に
細かい所だともっと色々ありますが、本やネットのサンプルと、実際仕事で使うコードとの差が大きいと感じる2つを上げてみました。具体的な実装は何も書いてなくて申し訳ないです。
最近は上記に加えて、indirect系のAPIや非同期CSも複雑に絡むので、最初に見た人は戸惑う事が多い気がします。例えば学校出たての描画エンジニアにここら辺教えるのは大変だと思うのですが、OJT以外で何かいい方法や資料&サイトあれば教えて下さい!