Knee Curve と Soft Knee

UnityのBloomエフェクトの調整項目にSoft Kneeというものがあります。

docs.unity3d.com

これに関連して、Knee Curve周りに関するメモです。

Knee Curve?

ここでいうKnee Curveとは下記の計算式で表される曲線のことです。
元の値をSource Value閾値をThresholdとしたとき、

{ \displaystyle
\frac{max(source-threshold, 0)}{source}
}

このグラフは次のようになります。

f:id:halya_11:20180215001917p:plain

これは、Source Valueのうち、Thresholdの値よりも大きいものにのみ影響を与えたいときなどに役に立ちます。
見ての通り、計算量もかなり少なめです。

なお、シェーダで記述する際にはゼロ除算を防ぐため次のような数式になります。

{ \displaystyle
\frac{max(source-threshold, 0)}{max(source, 0.0001)}
}

Knee Curveの問題点

上述のグラフを見るとわかる通り、Knee CurveはThresholdの値が小さいほどカーブの曲率が大きくなります。

この特徴により、例えばThreshold = 0.25のとき、Source Valueが0.25以上の範囲において、Source Valueが小さいほど変化量が大きくなってしまいます。

f:id:halya_11:20180215002827p:plain

これで問題が起こらない場合はいいのですが、例えばブルームをかける明度の閾値計算にこれを使ったとき、ブルームがかかる部分とかからない部分が急激に切り替わるという現象が起こります。

そこで登場するのがSoft Kneeです。

Soft Knee

Soft Kneeではまず、Soft Thresholdという0〜1の値を定義します。
さらにこれをThresholdと掛け合わせたものをKneeとします。

{ \displaystyle
knee = softThrshold * threshold
}

次にこのKneeを使ってSoftという値を計算します。

{ \displaystyle
soft = \frac{(min(knee * 2, max(0,source - threshold + knee)))^{2}}{4 * knee * 0.00001}
}

そしてKnee Curveの式の、ゼロとのmaxを取っていた部分をSoftとのmaxを取るように書き換えます。

{ \displaystyle
\frac{max(source - threshold, soft)}{max(source, 0.0001)}
}

この計算式で表されるグラフがSoft Kneeを使った曲線となります。

Soft Kneeのグラフ

例えばThresholdが0.25のとき、Soft Kneeの曲線は次のようになります。

f:id:halya_11:20180215010357p:plain

Soft Thresholdを上げていくほど変化がなだらかになることがわかります。
ただしその代わり、Threholdとして設定した値よりも小さい値についても、計算結果が0より大きくなってしまいます。

Soft Kneeの計算量

Soft Kneeを適用することによって計算量が多くなりました。
まあまあ長い数式になっていますが、これはCPUで計算できる部分も多いため、シェーダで使う際にはうまくスクリプトと組み合わせると処理負荷は少なくできます。

この辺りはいずれ具体的に追記するかもしれません。