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 color *= Col.xyz;
}
こちらのサイトを参考にしました
http://maverickproj.web.fc2.com/pg35.html