Game Engine Gems 1 "Camera-Centric Engine Design for Multithreaded Rendering"の概要

Game Engine Gems 1 "Camera-Centric Engine Design for Multithreaded Rendering"を読みましたので, その概要について書きます.

  • この記事では, カメラベースのグラフィクスエンジンについての説明がしてあります.
  • まず, D3D9のようなグラフィクスAPIを直接呼ばずに,
    1. 描画コマンドを準備する.
    2. 描画コマンド実行する.

といった手順を踏むために, 以下のようなRenderCommand構造体を導入します.

struct RenderCommand
{
    // 頂点バッファのハンドル
    ResourceHandle VertexBufferHandle;  
    // 頂点宣言の種類のインデックス
    uint32 VretexDeclEnumIndex;
    // 三角形の数
    uint32 NumTriangles;
    // 頂点数
    uint32 NumVerts;
    
    // プリミティブの種類
    PrimType PrimitiveType;
    
    ...
}
  • 次に, Cameraクラスと, Cameraクラスとレンダリングターゲットや描画コマンドを持ったRenderViewクラスについて以下のように定義します.
struct Camera
{
    Float3 at, up, right;
    float  aspectRatio;
};

struct RenderView
{
   // カメラ
   Camera  ViewCamera;
   // 視錐台
   Frustum Frust;
   // レンダリングターゲットとなるカラーバッファ
   RenderTargetHandle DestColorRTT;
   // レンダリングターゲットとなるデプスバッファ
   RenderTargetHandle DestDepthRTT;
   // 描画コマンド
   List<RenderCommand *> RenderCommands;
  
   // グラフィクスAPIへのサブミットの順序を決める型
   enum ViewType
  {
     // シャドウマップ
     kVT_ShadowMap = 0,
     // リフレクションマップ
     kVT_ReflectionMap,
     // メインのカメラ
     kVT_MainCamera,
     // ポストエフェクト
     kVT_PostProcessing,
     kVT_Count
  };
   viewType ViewType;
};  
  • 例えばシャドウマップを使ったシーンのレンダリングを行うときには, シャドウマップ用のRenderViewとメインカメラのRenderViewを作っておきます.
  1. RenderViewごとのRenderCommandsの準備
    • 各RenderViewごとにそのRenderCommandsを準備するときには, カメラの視錐台でカリングを行い, 視錐台内のモデルのオブジェクトごとにRenderCommandsを準備します.
    • またモデルのオブジェクトを走査してRenderCommandsを準備する処理を並列化するために, モデルオブジェクトを走査する処理をスレッドセーフにしておきます.
  2. 各RenderViewのRenderCommandsの実行
    • RenderViewの「グラフィクスAPIへのサブミットの順序を決める型」を保存しているviewType ViewTypeのメンバの型に基づいた順に, 描画コマンドの実行を行います.