【Unity】トゥーンシェーダー


トゥーンシェーダーとは

トゥーンシェーダーとは、陰影を急激に変化させてアニメのような塗りを再現したシェーダーのことです。
基本色と影色の2色で表現することが多いですが、影色を2つに増やすこともあります。

計算方法

法線ベクトルとライトベクトルを内積した結果から、基本色と影色の2色に振り分けます。
途中まではLambert拡散反射の計算と同じです。

ID={1(NL0.5)0(NL<0.5)C=C1(1ID)+C2ID\begin{align} I_D &= \begin{cases} 1 & (N \cdot L \geq 0.5)\\ 0 & (N \cdot L < 0.5) \end{cases} \\ C &= C_1(1-I_D) + C_2I_D \end{align}
パラメータ 説明
IDI_D 拡散反射した光の強さ
NN 法線ベクトル
LL ライトベクトル
C1C_1 影色
C2C_2 基本色

ShaderLabで実装する

環境

  • Unity 2021.2.11f1
  • Build-in Rendering Pipline

基本色と影色の2値で実装していきます。

Toon.shader

https://gist.github.com/went5/4d4e22f7f65021d602ad38d2c176384e

頂点シェーダーの説明は省略します。

NdotLを求める

fixed4 frag(v2f i):SV_Target
{
    float3 normal = normalize(i.normal);
    half3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
    half NdotL = saturate(dot(normal, lightDir));
    //.....
}

Lambert拡散反射と同じく、ライトベクトルと法線ベクトルの内積からNdotLを求めます。
詳細な説明は【ShaderLab】ランバート拡散反射を実装するにて解説しています。

NdotLの値から色を振り分ける

fixed4 color = lerp(_ShadowColor, _BaseColor, step(0.5, NdotL));

step(edge,in): inがedge未満なら0を返し、edge以上なら1を返す
lerp(A,B,T): Tが0の場合はAを返し、Tが1の場合はBを返す。Tが0.5の場合は、AとBの中間値を返す。

NdotLの値が0.5未満なら _ShadowColor を返し、0.5以上なら _BaseColor を返します。

以上で冒頭の画像を再現できます。

Table of contents


©️ 2026 went5. blog icon by

icons8