DirectX11でトゥーンシェーダー


DirectX11で簡易的なトゥーンシェーダーの実装をしたいと思います。

トゥーンシェーダーとは?

トゥーンシェーダーはこのように陰影がハッキリしています。アニメ調のゲームなどで使用されています。

ToonMapクラス

トゥーンシェーダーではトゥーンシェーダー用のテクスチャを用意します。

拡散反射光などは計算によって色を決めますが、トゥーンシェーダーはこのテクスチャから色を決めます。
ライティングの計算を行った後、その値をUV座標のX成分としてこの画像からライティングの値をフェッチします。

ToonMap.h
ID3D11Device* g_d3dDevice;  //構築済みとする
ID3D11DeviceContext* g_d3dDeviceContext  //構築済みとする

public:
    ToonMap() {}
    ~ToonMap() {}

    //初期化
    void Init();
    //テクスチャをピクセルシェーダーに設定する、モデルをドローする時に呼んでください
    void SetShaderResourceView();
private:
    ID3D11ShaderResourceView* m_srv = nullptr; 
ToonMap.cpp
void ToonMap::Init()
{
    //テクスチャを読み込みます
    DirectX::CreateDDSTextureFromFile(
    g_d3dDevice, // D3Dデバイス
    L"Assets/shader/toonmap.dds",  //テクスチャのファイルパス
    nullptr,   //nullptrでいい
    &m_srv  //シェーダーリソースビュー
    );
}

void ToonMap::SetShaderResourceView()
{
    //ピクセルシェーダーにテクスチャを設定します。
    ID3D11ShaderResourceView* srvArray[]{
            m_SRV
    };
    d3dDeviceContext->PSSetShaderResources(4, 1, srvArray);
}

シェーダー

model.fx
Texture2D<float4> toonMap : register(t4);  //toonシェーダー用のテクスチャー

//以下の実装と頂点シェーダーの実装は省きます
Texture2D<float4> albedoTexture : register(t0);  //モデルのテクスチャー
sampler Sampler : register(s0);  //サンプラー
//ディレクションライト
cbuffer LightCb : register(b1) {
    float3 dligDirection;
};
///ピクセルシェーダーの入力
struct PSInput{
    float3 Normal       : NORMAL;
    float2 TexCoord     : TEXCOORD0;
};

//ピクセルシェーダー
float4 PSMain( PSInput In ) : SV_Target0
{
    //モデルのテクスチャから色をフェッチする
    float4 color =  albedoTexture.Sample(Sampler, In.TexCoord);

    //ハーフランバート拡散照明によるライティング計算
    float p =  dot(In.Normal * -1.0f, dligDirection.xyz);
    p = p * 0.5f + 0.5f;
    p = p * p;

    //計算結果よりトゥーンシェーダー用のテクスチャから色をフェッチする
    float4 Col = toonMap.Sample(Sampler,float2(p,0.0f));

    //求まった色を乗算する
    return albedoColor *= Col.xyz;
}     

こちらのサイトを参考にしました
http://maverickproj.web.fc2.com/pg35.html