ポリゴンメッシュの描画処理が揃ってきたので、最後にレンダリングステート系とマルチパス(同じメッシュを異なるシェーダやステートで複数回描画)を追加し、シェーダ関連の処理を整理、構造化します。その処理を使って輪郭線のある3Dモデルを表示してみます(法線方向拡大&裏面表示の輪郭線アルゴリズム)。表示させてみるとジャギーが酷かったので、マルチサンプルアンチエリアシング(MSAA)の対応も同時に行います。

シェーダエフェクト仕様(仮)
シェーダパス(class ShaderPass)
描画処理の最小単位。これを組み合わせてシーン(場面)を構成する。少し冗長になるが描画に必要なリソースをすべて保持することで、このクラス単独で描画処理を完結させる。独立した描画単位なので、スレッドでの並列処理、ソートなどの処理が簡潔になる(はず)。
シェーダテクニック(class ShaderTech)
ポリゴンメッシュの描画方法を定義するクラス。複数のシェーダパスで構成される。
メッシュ(class MeshX11)
3Dポリゴンモデルの最小単位。姿勢情報、マテリアル、形状(ジオメトリ)から成る。複数のシェーダテクニックを持ち、使用するテクニックにより描画方法が決まる。
参考 現時点でのソースコード(作成中)
~Ptrは、DirectX11インターフェイス(ID3D11Bufferなど)のスマートポインタ、Arrayは固定長配列。複数保持するメンバ変数は、数が少ないため固定長配列で確保し使った分の数を設定することで効率化。
class ShaderPass;
class ShaderTech;
class MeshX11;
class ModelX11;
typedef SPtr<ShaderPass>::Type SPassPtr;
typedef SPtr<ShaderTech>::Type STechPtr;
typedef SPtr<MeshX11>::Type MeshX11Ptr;
typedef SPtr<ModelX11>::Type ModelX11Ptr;
// モデル
class ModelX11
{
public:
std::vector<MeshX11Ptr> apMesh;
};
// メッシュ
class MeshX11
{
public:
MeshX11(){}
~MeshX11(){}
static const zgU32 TECH_MAXNUM = 8;
zgU32 numTech;
Array<STechPtr, TECH_MAXNUM>::Type apTech;
private:
};
//----------------------------------
// シェーダテクニック
class ShaderTech
{
public:
static const zgU32 PASS_MAXNUM = 4;
zgU32 numPass;
Array<SPassPtr, PASS_MAXNUM>::Type apPass;
};
//----------------------------------
// シェーダパス(描画の最小単位)
class ShaderPass
{
public:
static const zgU32 VBUFF_MAXNUM = 8;
static const zgU32 TEX_MAXNUM = 8;
static const zgU32 CBUFF_MAXNUM = 8;//16;
// 数が少ないので固定の配列
//頂点データ
zgU32 numVBuff;
Array<UINT, VBUFF_MAXNUM>::Type aStride;
Array<UINT, VBUFF_MAXNUM>::Type aOffset;
Array<IBuffPtr, VBUFF_MAXNUM>::Type apVBuff;
IBuffPtr pIBuff;
IILayoutPtr pLayout;
// 状態
IRsStatePtr pRsState;
IBdStatePtr pBdState;
IDsStatePtr pDsState;
// シェーダ
IVShaderPtr pVShader;
IPShaderPtr pPShader;
//テクスチャ
zgU32 numTex;
Array<ISRViewPtr, TEX_MAXNUM>::Type apSRView;
Array<ISpStatePtr, TEX_MAXNUM>::Type apSpState;
//定数バッファ
zgU32 numCBuff;
Array<IBuffPtr, CBUFF_MAXNUM>::Type apCBuff;
//とりあえず頂点とピクセルで定数共有
zgU32 nCount;
ShaderPass() : numVBuff(0), numTex(0), numCBuff(0), nCount(0){}
};
サンプルプログラム
マルチサンプル対応
zg_dx11.cpp InitDX11()
マルチサンプルに対応させるには、スワップチェイン作成時にDXGI_SWAP_CHAIN_DESCで指定します。ただし、事前に利用可能なマルチサンプル設定を取得する必要があります。これまで使用してきたD3D11CreateDeviceAndSwapChainでは対応できないため、DirectX11デバイス作成、利用可能なマルチサンプル設定の列挙、スワップチェインの作成の順に初期化処理を行います。
あとデプスステンシルバッファも同じマルチサンプル設定にするのを忘れずに。バッファ作成時のD3D11_TEXTURE2D_DESCとD3D11_DEPTH_STENCIL_VIEW_DESC::ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS。
描画用メッシュ(class MeshX11)の作成
//zg_mdlx11.h/cpp
//-------------------------------------------
// DX11レンダリングモデルの作成
ModelX11Ptr CreateModelX11(zgmdl::Model& model);
シェーダエフェクトを構成するためのデータがないため、直接プログラムでシェーダエフェクト構築をしています。最初のシェーダパスで法線方向に拡大、裏面だけを黒く描画、次のシェーダパスで通常の描画を行うことで輪郭線を表示しています。
「シェーダエフェクト&マルチサンプルAA」への1件のフィードバック