今更だけど
トゥーンシェーダを実装してみた。
まず、色の階調化だけど、これは簡単にできた。
ライトのベクトルと法線の内積をとって、UV座標を計算。ベクトルは正規化しないとU値が1より大きくなるので注意。このままでは、値が0以下のこともありえるので、0から1の範囲になるように調整する。
次は、輪郭線の抽出。さっきと同じで、視線のベクトルと法線の内積をUV座標のV値に代入する。
後は計算したUVを元にトゥーン用のテクスチャから色を拾って描画。これで、おしまい。
描画してみた
何か輪郭線が汚い。上手く抽出できてないようだ。
以下、fxファイルの中身
float4x4 mWVP; float3 vLight = {0.557f, -0.557f, 0.557f}; // ライトの方向 float3 vEye; // 頂点シェーダー出力 struct VS_OUTPUT { float4 Pos : POSITION; // 座標 float2 Tex : TEXCOORD0; // テクスチャUV }; VS_OUTPUT ToonVS(float4 Pos : POSITION, float4 Normal : NORMAL) { VS_OUTPUT Out = (VS_OUTPUT)0; Out.Pos = mul(Pos, mWVP); // 座標変換 float3 N = normalize(Normal.xyz); // 法線を正規化 Out.Tex.x = max(dot(vLight, N), 0) * 0.5f + 0.5f; // 0から1の範囲に修正 float3 E = normalize(vEye - Pos.xyz); // 視線のベクトル Out.Tex.y = dot(E, N); // vを計算、内積が小さいとき、輪郭抽出を行う return Out; } technique ToonShader { pass P0 { VertexShader = compile vs_2_0 ToonVS(); } }