目次
- はじめに
- グラフィックスプログラミングの学習
- 些細な問題にこだわりすぎない
- なぜ Vulkan なのか?
- Vulkan の学習
- エンジン概要とフレーム分析
- 一般的なアドバイス
- おすすめの Vulkan ライブラリ
- GfxDevice 抽象化
- シェーダー処理
- プッシュ定数、ディスクリプタセット、およびバインドレスディスクリプタ
- パイプラインパターン
- Programmable Vertex Pulling (PVP) + Buffer Device Address (BDA) の使用
- バインドレスディスクリプタ
- 毎フレームアップロードが必要な動的データの処理
- デストラクタ、削除キュー、およびクリーンアップ
- 同期
- さらに多くの実装ノート
- 多数のスプライトを描画する
- コンピュートスキニング
- ゲーム / レンダラー分離
- シーン読み込みとエンティティプレハブ
- MSAA
- UI
- Dear ImGui と sRGB の問題
- その他
- Vulkan へ移行して得たもの
- 今後の作業
はじめに
- Vulkan を学び、小さなゲームエンジンを書いた経験を記録した内容。
- Vulkan の事前知識なしに 3 か月間取り組んだ。
- 小さな 3D ゲームを作り、再利用可能な部分をエンジンとして分離した。
グラフィックスプログラミングの学習
- グラフィックスプログラミングを初めて学ぶ人は、OpenGL から始めるのがよい。
- OpenGL を通じてテクスチャ付きモデルを画面に表示し、簡単なライティングやシャドウマッピングを学ぶのが有用。
- OpenGL 学習のおすすめリソース:
- learnopengl.com
- Anton の OpenGL 4 Tutorials 書籍
- Thorsten Thormählen の講義(最初の 6 本の動画がおすすめ)
些細な問題にこだわりすぎない
- 些細な問題に執着しすぎないよう注意する必要がある。
- 「本当に必要か?」「ボトルネックになるのか?」を常に自問すべき。
- 必要でない機能は後から追加できる。
- まずは簡単なゲームから始め、複雑なエンジンを作りすぎないように注意すべき。
なぜ Vulkan なのか?
- Vulkan は最新の GPU 機能を使うことができ、オープンソース技術や標準を好む人に向いている。
- OpenGL は小規模ゲームには十分だが、最新 GPU 機能を使いにくく、macOS では利用が制限される。
- WebGPU は Vulkan より学びやすく、ブラウザでゲームを実行できる。
Vulkan の学習
- Vulkan の学習は当初は難しく見えたが、Khronos が複雑な部分を簡素化し、有用なライブラリを提供しているため学びやすくなっている。
- おすすめの Vulkan 学習リソース:
- vkguide
- TU Wien の Vulkan 講義シリーズ
- 3D Graphics Rendering Cookbook 書籍
- Mastering Graphics Programming with Vulkan 書籍
エンジン概要とフレーム分析
- エンジン名は EDBR (Elias Daler’s Bikeshed Engine) で、Vulkan 学習プロジェクトとして始まった。
- エンジンは主に小規模なレベルベースのゲームに適している。
- フレームレンダリングの流れ:
- スキニング: コンピュートシェーダーを使ってモデルのスキニングを処理
- シャドウマッピング: 4096x4096 の深度テクスチャを使用
- ジオメトリとシェーディング: PBR モデルを使用
- 深度解決: フラグメントシェーダーで手動処理
- ポストプロセス効果: 深度フォグ、トーンマッピング、ブルームを適用
- UI: 1 回のドローコールで UI を描画
一般的なアドバイス
おすすめの Vulkan ライブラリ
- vk-bootstrap: Vulkan 初期化コードを簡素化
- Vulkan Memory Allocator (VMA): メモリ割り当て管理
- volk: 拡張関数のロードを簡素化
GfxDevice 抽象化
GfxDevice クラスは Vulkan 機能をカプセル化し、Vulkan コンテキスト初期化、スワップチェーンの生成と管理などを処理する。
シェーダー処理
- GLSL を使ってシェーダーを記述。
- ビルド段階でシェーダーを事前コンパイルし、ランタイム依存性を減らす。
プッシュ定数、ディスクリプタセット、およびバインドレスディスクリプタ
- Vulkan ではディスクリプタセットを使ってシェーダーにデータを渡す。
- バインドレスディスクリプタと Buffer Device Address を使って、ディスクリプタセットの使用を最小化する。
パイプラインパターン
- パイプラインクラスを使って描画段階を分離する。
init、cleanup、draw メソッドでパイプラインの初期化、クリーンアップ、描画を処理する。
Programmable Vertex Pulling (PVP) + Buffer Device Address (BDA) の使用
- 頂点タイプを 1 つに統一し、シェーダーで頂点へ直接アクセスする。
- プッシュ定数を使ってバッファアドレスを渡す。
バインドレスディスクリプタ
- テクスチャをバインドレス方式で管理し、シェーダーから直接アクセスできるようにする。
- テクスチャ ID をプッシュ定数で渡してサンプリングする。
GN⁺ の意見
- Vulkan は高い性能と最新 GPU 機能を提供するが、初期の学習曲線は急である。
- まず OpenGL を学んでから Vulkan に移行するのがよい。
- Vulkan 学習にはさまざまなリソースがあり、それらを活用すれば学びやすくなる。
- Vulkan を使って小規模なゲームエンジンを書くことは、グラフィックスプログラミングを深く理解する助けになる。
- Vulkan の複雑さを減らすために有用なライブラリを使うのがよい。
1件のコメント
Hacker Newsの意見
Hacker Newsコメント要約
ミニマルなアプローチの効果: メタバースクライアントをRustで書いており、Vulkan、WGPU、Rend3を使って複雑な問題に直面している。WGPUはさまざまなプラットフォームをサポートしようとするため、開発が難しい。
Vulkanの長所とOpenGLの手軽さ: Vulkanは高度なGPU機能を最大限に活用できるが、OpenGLはシンプルな2D/ローポリゲームに適している。AAAゲーム業界はグラフィック品質に重点を置くが、多くのプレイヤーはゲームプレイにより関心を持っている。
必要な機能だけを実装: ジュニアプログラマーは最新のツールや「ベストプラクティス」に執着しがちだが、実際の問題解決に必要な最小限の機能に集中することが重要だ。
Vulkanの複雑さ: VulkanはOpenGLに比べて性能最適化が難しく、多くのコードと同期作業が必要になる。趣味用途ではOpenGL ES3のほうが手軽だ。
追加の抽象化レイヤーの問題: Vulkanを学ぶ資料では追加の抽象化レイヤーが導入されていることが多く、基本的なメモリ管理の例を見つけにくい。
Vulkan学習の困難さ: OpenGLは学びやすかったが、Vulkanは簡単な作業さえ複雑にしてしまう。新しい技術を学ぶには多くの時間がかかる。
科学データ可視化のためのVulkan学習: Vulkanを学んで科学データ可視化エンジンを書いたが、学習過程で多くの抽象化を理解するのに時間がかかった。
Vulkan学習の難しさ: Vulkanを実際のエンジンでどう使うかを理解するのは難しい。よい抽象化やレンダリング順序の決め方を学ぶために、さらに多くの資料が必要だ。
グラフィックスプログラミングコミュニティの支援: Vulkanエンジンを開発する過程で、コミュニティの支援とフィードバックが大きな助けになった。