Unity シェーダーチュートリアル 即時的かつ効率的にSmoothnessを設定する方法
シェーダー
PBSマテリアルにおいて、最も重要と言っても過言ではい項目が Smoothness です。
(ソフトウェアによって Glossiness だったり Roughness だったりします)
今回はこの Smoothness の即時的かつ効率的な設定方法について書いていきます。
即時的な設定と銘打っているため、速度重視でアーティスティックなやり方ではありませんが、
時間に対するコストパフォーマンスと調整のし易さはかなり高いと思います。
以下がシェーダーのサンプルコードです。
テクスチャ作成
Smoothness の設定に必要なチャンネルは1つなので、
アルベドテクスチャのアルファチャンネルに含めて作っていきます。
速度重視なので細かい書き込みはせず、RGBチャンネルをそのままアルファチャンネルにコピーして
適当にコントラストを付けて終わりにします。
ここで重要なのが、ヒストグラムを0~255まで広く分布させることです。
右側の図のようにヒストグラムが全体に分布していない状態だと、
後述のシェーダー側での調整が正しくできません。
プロパティ
Unity側で最終的な見た目を確認しながら値を調節できるように、
以下の2つのプロパティで Smoothness を設定します。
_SmoothMin ("Smooth Min", Range(0, 1)) = 0.0
_SmoothMax ("Smooth Max", Range(0, 1)) = 1.0
テクスチャで与えられた0〜1(255)のレンジを
最小値・最大値でギュイっと調整します。
先述のヒストグラムについて、しっかり0~255まで分布させていれば、
プロパティの数値がそのまま Smoothness の最小・最大値になりますが、
分布していなければ、プロパティの数値がそのまま Smoothness の最少・最大値にはなりません。
これでは作成したマテリアルをざっと眺めた時、
数値的に Smoothness の確認ができず、混乱してしまいます。
Smoothness の計算
Smoothness の最終的な値は、テクスチャのアルファチャンネルと、
_SmoothMin 、_SmoothMax を使って計算します。
以下が抜粋コードです。
sampler2D _MainTex;
half _SmoothMin;
half _SmoothMax;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
o.Smoothness = mainTex.a * (_SmoothMax - _SmoothMin) + _SmoothMin;
}
これで、数値通りにレンジを調整できます。
おわりに
冒頭にも書いたように、アーティスティックなやり方ではありませが、効果は高いです。
しかし、一つのテクスチャに様々な素材が含まれている場合は、(金属と革など)
ある程度の描き分けをしなければならないので、場合によって使い分けましょう。