【Unity】ハーフランバートシェーダー

ハーフランバート照明とは
ハーフランバート照明とは、ランバート拡散反射を改良したもので、ランバート拡散反射よりも、ベースカラーから影色の変化をなだらかになります。

上記の画像はランバート拡散反射のもので、影の色が目立ってしまっています。
計算方法
ハーフランバートによる光の強さは以下の式で求めることが出来ます。
この計算式は、ランバートよりも法線ベクトルとライトベクトルの内積の値の変化をなだらかにしたものを示しています。
Desmosを使いグラフ化すると、ハーフランバートとランバートの違いが分かります。
Y軸は、色を示しています。(1なら白、0以下なら黒)
X軸は、ライトベクトルと法線ベクトル間の角度を示しています。()
青の線のほうが、なだらかに色の変化していることがわかります。

ShaderLabで実装する
環境
- Unity 2021.2.11f1
- Build-in Rendering Pipline
- Shader Calibration Scene
HalfLambert.shader
https://gist.github.com/went5/e5c9a80ed1ab5599f5cb67c7871cb5c9
ハーフランバートを求める
float3 NdotL = dot(i.worldNormal, lightDir);
float3 HNdotL = pow(0.5 * NdotL + 0.5, 2);
NdotL がランバートで、 HNotL がハーフランバートです。
計算方法の式をプログラムで表した形になります。
条件コンパイルで2種類のハーフランバートを切り分ける
float3 NdotL = dot(i.worldNormal, lightDir);
#ifdef IS_DARK
float3 HNdotL = pow(0.5 * NdotL + 0.5, 2);
#else
float3 HNdotL = 0.5 * NdotL + 0.5;
#endif
ハーフランバートには、最後に2乗をするものとしないものがあります。
プロパティで切り分けをできるように、条件コンパイルを入れています。
IS_DARK をプロパティにするには、以下のようにToggleとpragmaディレクティブを記述する必要があります。
Properties
{
[Toggle(IS_DARK)] _IsDark ("Is Dark", Float) = 0
}
Pass {
#pragma shader_feature IS_DARK
}
IS_DARK にチェックをつけたものが冒頭のpow2の画像になります。
以上で、冒頭の画像が再現できます。
Table of contents