Vulkan実践入門 グラフィックスの基礎からレイトレーシング、メッシュシェーダーまで
- 山田英伸 著
- 定価
- 4,950円(本体4,500円+税10%)
- 発売日
- 2025.10.27
- 判型
- B5変形
- 頁数
- 512ページ
- ISBN
- 978-4-297-15257-4 978-4-297-15258-1
サポート情報
概要
VulkanはOpenGLの後継として登場した次世代のグラフィックスAPIで、開発者がGPUをより細かく制御することで、従来以上にGPUの性能を引き出すことが可能です。UnityやUnreal Engineなどのゲームエンジンから内部的に利用されており、多くの開発者にとって普段意識することは少ないものです。しかし、⾼度なグラフィックスを実現する際やデバイスに最大限のパフォーマンスを発揮させる場合には、その知識が重要になります。またGPUを用いた汎用計算にも対応しており、シミュレーションやAIの分野での利用もあります。この書籍では、基本的な描画や計算処理を通じてVulkanを直接扱い、GPUグラフィックスプログラミングの基礎を学びます。
こんな方にオススメ
- 3Dグラフィックスを描画する低レイヤのしくみを学びたい人
- ゲームエンジンの開発など高度なグラフィックスプログラミングを担当するエンジニア
目次
- はじめに
第1章 Vulkan概要
- Vulkanとは
- 低レイヤーに位置付くGPU操作のAPIセット
- マルチプラットフォーム対応
- マルチコア時代を活かしたマルチスレッド対応
- SPIR-Vを用いたシェーディングの中間言語の採用
- バージョン更新が続くAPIセット
- GPUのアーキテクチャの歴史
- ハードウェアによるジオメトリエンジン搭載
- プログラマブルシェーダーの登場
- ユニファイドシェーダーの時代
- グラフィックスAPIの歴史
- 固定機能による描画世代
- OpenGL1.5/2.x(プログラマブルシェーダー世代)
- OpenGL3.x世代
- OpenGL4.x世代
- Vulkan 1.0
- Vulkan 1.1
- Vulkan 1.2
- Vulkan 1.3
- Vulkan 1.4
- 画面に3Dグラフィックスが描画されるまで
- CPUからGPUへコマンドを発行
- GPUでグラフィックスパイプラインを実行
- [コラム]DirectXにおけるテッセレーション用シェーダー
- OpenGLからVulkanへの変化
- ドライバの機能がスリム化
- シェーダーコンパイラが分離
- [コラム]シェーダーの中間表現
- マルチスレッドへの対応
- レイヤーと拡張機能
- レイヤー
- 拡張機能
第2章 ウィンドウの表示
- アプリケーションクラスの準備
- Vulkanコンテキストクラスの準備
- メインループの作成
- Vulkanの初期化処理
- Vulkanインスタンスの作成
- 物理デバイスの選択
- Vulkan論理デバイスの作成
- コマンドプールの作成
- デバッグ機能を有効化
- Validation Layer
- VK_EXT_debug_utils拡張機能
- 検証レイヤー有効化によるデバッグ支援
- Vulkanの同期オブジェクト
- フェンスの作成・破棄
- セマフォの作成・破棄
- プレゼンテーション関係の初期化処理
- サーフェスとは
- サーフェスの作成
- スワップチェイン
- スワップチェインの生成
- スワップチェインが保持するイメージへのビューを生成
- スワップチェインのフレームコンテキスト
- スワップチェイン初期化を繋ぐ
- [コラム]スワップチェイン作成関数の補足
- Vulkanによる描画処理
- コマンドバッファクラスの実装
- フレームコンテキストの作成
- スワップチェインから描画先を取得
- [コラム]スワップチェインから得られるイメージのインデックスに注意
- 描画ループを作る
- フレームコンテキストの同期処理
- [コラム]プレゼンテーション完了待ちセマフォのトリック
- 画面のクリア処理
- [コラム]セマフォについて
- Vulkanの終了処理
第3章 ポリゴンの表示
- Vulkanによるポリゴン描画までの流れ
- アプリケーションクラスを修正
- OnInitializeの実装
- OnCleanupの実装
- 頂点バッファの作成
- [コラム]情報
- VkBufferの生成
- メモリの確保と割り当て
- VertexBufferクラスの作成
- InitializeTriangleVertexBufferの実装
- アセットパスを取り扱う仕組みの準備
- シェーダーの準備
- 頂点シェーダーの記述
- フラグメントシェーダーの記述
- シェーダーのコンパイル
- パイプラインレイアウトの作成
- パイプラインの作成
- グラフィックスシェーダーステージ
- 頂点入力ステート
- 入力アセンブリ情報
- テッセレーション情報
- ビューポート情報
- ラスタライザー設定
- マルチサンプル情報
- デプスステンシル情報
- カラーブレンド情報
- 動的ステート情報
- 動的レンダリング情報
- [コラム]動的レンダリングにより実装がしやすくなった
- その他
- パイプラインビルダーの作成
- 描画コマンドの作成
- パイプラインのバインド
- 頂点バッファのバインド
- ポリゴンの描画コマンド
- 後始末
第4章 3Dポリゴンの表示
- 3Dオブジェクト描画までの流れ
- サンプルプログラムの初期化コード
- デプスバッファの作成
- VkImageの作成
- メモリの確保と割り当て
- VkImageViewの作成
- DepthBufferクラスの作成
- ステージングバッファクラスの作成
- リソースアップローダーの作成
- 3D立方体データの作成
- インデックスバッファクラスの作成
- 立方体のジオメトリデータ
- 各バッファの作成
- 3D処理のための行列計算
- 行列の準備
- [コラム]GLMの設定に注意
- 頂点シェーダーの実装
- ライティング処理
- 拡散反射光: Lambert拡散反射モデル
- 鏡面反射光: Phong鏡面反射モデル
- 環境光
- フラグメントシェーダーの実装
- ユニフォームバッファの作成
- UniformBufferクラスの作成
- 描画で使用するユニフォームバッファの作成
- [コラム]ユニフォームバッファのアクセス場所の切り替え方
- ディスクリプタセットの準備
- ディスクリプタプールの作成
- ディスクリプタセットレイアウトの生成
- ディスクリプタセットの確保
- ディスクリプタへ内容を書き込む
- パイプラインレイアウトの作成
- パイプラインの作成
- デプスステンシルステートの設定
- ビューポートの上下反転設定
- パイプラインの作成
- 描画コマンドの作成
- ユニフォームバッファの更新
- 動的レンダリングの開始とバッファクリア
- グラフィックスパイプラインに各リソースをバインドする
- ポリゴンをインデックス付き描画する
- 後始末
- ディスクリプタセット関連の後始末
- SimpleCubeApp::OnCleanup()の実装
第5章 テクスチャの表示
- テクスチャの概要
- テクスチャの種類
- テクスチャ座標系
- テクスチャフィルタリングモード
- ミップマップ
- テクスチャアドレッシングモード
- テクスチャのフォーマット
- テクスチャの作成
- 画像ファイルの読み込み
- VkImageの作成
- メモリの確保と割り当て
- VkImageViewの作成
- テクスチャクラスの作成
- テクスチャローダーの実装
- 画像内容の転送
- [コラム]テクスチャ向けファイルフォーマットについて
- パイプラインバリアとリソースバリア
- パイプラインバリア
- リソースバリア(リソース同期)
- [コラム]最も安全なバリア
- シェーダーの準備
- サンプラーの作成
- VkSamplerの作成
- サンプラークラスの実装
- サンプルプログラムでの実装
- ディスクリプタセットの準備
- ディスクリプタセットレイアウトの作成
- ディスクリプタセットの準備
- パイプラインの作成
- 描画コマンドの作成と実行
第6章 モデル(ポリゴンメッシュ)の表示
- 3Dモデルデータフォーマット
- glTFフォーマットについて
- [コラム]glTFの埋め込み形式について
- モデルデータのロード
- Open Asset Import Library(assimp)
- モデルデータの構築
- 発展的なライティング処理の基本
- 法線マッピング(Normal mapping)
- [コラム]もっと詳しく知りたい場合には
- 物理ベースレンダリング(PBR:Physically-based rendering)
- レンダラーの作成
- ディスクリプタセットの設計
- BasicPBRRenderクラスの作成
- プッシュ定数(Push Constant)の導入
- モデル描画パイプラインの作成
- 描画用データの構築
- ModelResourceクラスの作成
- DrawObjectクラスの作成
- ダイナミックユニフォームバッファの作成
- PBRシェーダーの実装
- シーン用ディスクリプタセットの準備
- モデルのロードと描画インスタンスの作成
- モデルの描画
- モデル行列の更新
- ダイナミックユニフォームバッファへの書き込み
- OnDrawFrameでの描画処理
- BasicPBRRender::Drawの実装
- [コラム]モデルの描画方法は1つではない
第7章 テッセレーション
- テッセレーションの概要
- テッセレーションの処理の流れ
- テッセレーションのモード
- テッセレーションの分割制御モード
- テッセレーション使用時の注意事項
- テッセレーションを有効にしたプログラムの実装
- パッチデータの準備
- ディスクリプタセットレイアウトの準備
- パイプラインの作成
- シェーダーの実装
- テッセレーション制御シェーダー(TCS)
- [コラム]テッセレーション係数の設定について
- テッセレーション評価シェーダー(TES)
- 頂点シェーダー
- 描画コマンドの作成
第8章 コンピュートシェーダー
- コンピュートシェーダーの概要
- コンピュートシェーダーの実行モデル
- GPUの構造
- Vulkanにおける計算タスクの構成要素
- 各階層構造の実行関係
- 計算処理結果の利用
- コンピュートパイプライン
- Shader Storage Buffer Object
- ディスクリプタセットレイアウトの作成
- ディスクリプタセットへの書き込み
- シェーダーの書き方
- ワークグループのサイズ設定
- リソースの割り当て
- 計算対象の特定
- コンピュートシェーダーの実行
- パイプラインの生成
- 実行
- 共有メモリ
- 画像フィルター
- 初期化の流れ
- ガウス関数
- ストレージバッファ・イメージクラスの作成
- リソースの用意
- ガウスフィルターシェーダーの実装
- ディスクリプタセットの準備
- 計算の実行とパイプラインバリア
- 共有メモリを使用する
- [コラム]どのくらい速くなるか
- 合計値を求める
- アトミック操作
- リダクション操作と共有メモリを使用した実装
- [コラム]コンピュートシェーダーの実装は奥が深い
- [コラム]アトミック加算が出来ない環境の場合
- 32bit整数型以外のアトミック操作について
第9章 メタローダーを使う
- ローダーとは
- メタローダーの使用
- volkを組み込む
第10章 レイトレーシング
- レイトレーシング基本アルゴリズム
- 古典的レイトレーシング
- パストレーシング
- Vulkanレイトレーシング
- Vulkanレイトレーシングの概要
- Acceleration Structure
- レイトレーシングパイプライン
- [コラム]レイの再帰処理も可能
- レイクエリー(Ray Query)
- レイトレーシングの実装・共通
- レイトレーシング機能を有効化
- BLASの構築
- TLASの構築
- TLAS/BLAS構築の便利クラスの作成
- 描画結果バッファの作成
- 描画結果をコピーするパイプラインの作成
- [コラム]レイトレーシング結果の書き込みとコピーについて
- レイトレーシングパイプラインで三角形を描画する
- 初期化の流れ
- Acceleration Structureの作成
- ディスクリプタセットの設計と準備
- レイトレーシングのシェーダー
- シェーダーのコンパイル
- レイトレーシングパイプラインの作成
- Shader Binding Tableの作成
- ディスクリプタセットの作成
- レイトレーシングの実行
- レイトレーシングパイプラインで古典的レイトレーシングの実装
- 初期化の流れ
- ディスクリプタセットの設計
- ModelResource,DrawObjectクラスの実装
- Acceleration Structure(BLAS)の作成
- モデルデータのロードとTLASの作成
- レイトレーシングのシェーダー
- レイトレーシングパイプラインの作成
- Shader Binding Tableの構築
- レイヒット時に使用されるシェーダーレコードの関係
- ディスクリプタセットの作成
- レイトレーシングの実行
- [コラム]バインドレス
- レイクエリーでパストレーシングの実装
- 初期化の流れ
- ディスクリプタセットの設計
- BLASと対応するジオメトリ情報の構築
- 乱数状態バッファの準備
- 累積加算バッファの準備
- レイクエリーを使用したシェーダーの実装
- [コラム]結果取得のcommittedについて
- パイプラインの作成
- 描画コマンドの構築と実行結果
第11章 メッシュシェーダーパイプライン
- メッシュシェーダーパイプラインとは
- メッシュシェーダーによる描画実装の流れ
- シンプルなポリゴンの描画
- メッシュシェーダーパイプラインを有効化する
- ディスクリプタセットレイアウトの作成
- 頂点バッファやインデックスバッファの作成
- ディスクリプタセットの作成
- メッシュシェーダーの実装
- メッシュシェーダーパイプラインの作成
- 描画コマンドの構築と実行結果
- メッシュレットによる描画
- メッシュレットとは
- ディスクリプタセットレイアウトの作成
- ModelResourceクラスの作成
- DrawObjectクラスの作成
- メッシュレットを作る
- メッシュシェーダーの実装
- フラグメントシェーダーの実装
- メッシュシェーダーパイプラインの作成
- 描画コマンドの作成
- メッシュシェーダーパイプライン活用のヒント
- メッシュレットのカリング
- メッシュレットの詳細度を変更
- タスクシェーダーの利用
- ワークグループサイズの選択
- [コラム]共有メモリサイズに注意
第12章 RenderDocによるデバッグ
- インストールとプログラムの起動
- GPUキャプチャ方法
- 各ウィンドウの説明
- Event Browser
- Texture Viewer
- Pipeline State
- Mesh Viewer
- Shader Viewer
- その他ツールの紹介
- GFXReconstruct
- NVIDIA Nsight Graphics
- Intel Graphics Performance Analyzers
付録A タイムラインセマフォ
- タイムラインセマフォ
- タイムラインセマフォの生成・破棄
- タイムラインセマフォの更新と待機(GPU側)
- タイムラインセマフォの更新と待機(CPU側)
- コマンドバッファ同期に使用したフェンスを置き換える
- [コラム]タイムラインセマフォのカウンタ値に注意
付録B レンダーパスを使う描画
- レンダーパスとは
- [コラム]レンダーパスを使用した描画は非推奨
- レンダーパスの作成
- フレームバッファの作成
- 描画処理
- 後始末
付録C Vulkanプロファイル
- プロファイル
- Vulkan Profiles Libraryの利用
- インスタンスの初期化
- デバイスの初期化
付録D Windows向け開発環境の設定
- Vulkan SDKの入手とインストール
- C++プロジェクトの作成と設定
- プロジェクトの設定
- プロジェクトテンプレートの利用
付録E 他のプラットフォームへ対応する
- Linux向け対応
- Android向け対応
- Android向けサーフェスの作成
- Androidのメッセージループ
- プロジェクトの構成変更
- 実行
- 索引
- あとがき
プロフィール
山田英伸
株式会社セガに所属。マルチプラットフォーム開発スペシャリスト。
業務では主にゲーム開発におけるアプリケーションの技術支援を担当し、幅広い技術知識を活かして開発をサポートしている。VulkanやDirectX12といったグラフィックスAPIに強い関心を持ち、日頃から最新情報を追いながら実装や検証にも積極的に取り組む。サーバー関連やネットワーク通信、OSを含む低レイヤ領域についても、自ら手を動かしながら実践的に知識を深めている。技術領域をまたいだ橋渡しを得意とし、外部講演の実績も多数。知見の共有や技術の普及にも力を注いでいる。