※この記事で使用しているUnrealのVersionは04.26.0です。

※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト

4.26から、「step」と「smoothstep」関数が新たにMaterialExpressionに追加されました!

今まで「smoothstep」の方は、MaterialFunctionでありました。
(中身はCustomノードで「smoothstep()を呼んでいるようです」)

「step」の方に至ってはMaterialFunctionですらなかったので、「if」ノードで代用か、自分でCustomノードを作成しなければなりませんでした。

今回は新しくMaterialExpressionとして追加されたstepとsmoothstepについて使い方等をまとめてみました。

MaterialExpression::stepについて レベル【★★】

まずはstepから。

stepは、引数にx,yとありますが、この引数に入れた2つの値を比較し、その結果によって 0 か 1 を返してくれる関数になります。

まずは実際に見てみましょう。

新規マテリアルを作成し、以下のようにノードを組みます。

そして、このマテリアルを継承したマテリアルインスタンスを作ってパラメーターをいじいじしてみます。

※「.0000」表示は「0.0000」と同義の値です。

これを見るとわかるように、X < Yの場合は値は0になって、X >= Yの場合は値は1になっています。

図解するとこんな感じです。

簡単な使い方としては、Yの値を固定値で0にすると、Xが正の値の場合は1、負の値の場合は0を返すようになります。

結果↓

図解するとこんな感じです。

これを応用すれば、例えば「sin(x)」で引数「Time」ノードを入れた場合に出た値に対して「step」を行うことで、1 → 0 → 1 → 0…と繰り返すようになってくれます。

結果↓

図解するとこんな感じです。

ここまで理解できれば使える幅は無限大!

例えばPlaneメッシュに白黒の縞模様を付けたりするなら、以下のようにノードを組めばできます。

もう少し上級者な使い方をするならば、例えば
「メッシュの面の傾斜」をstepを使って指定の度数で色分けもできたりします。

以下は指定した値未満の度数の面は黒く(0に)、それ以上の値は白く(1に)なるマテリアルの例です。

このようにstep関数は考え方次第で色々な使い方ができます。
楽しいですね!

stepを使った記事は以下でも紹介しておりますので、ご覧になってみてください。
※この時のバージョンではMaterialExpressionのstepノードがなかったのでCustomノードで実装しています。

MaterialExpression::smoothstepについて レベル【★★】

次は「smoothstep」についてです。

先ほどの「step」と似ておりますが、こちらは少しだけ複雑なものになっています。

引数には「Min」「Max」「Value」とありますが、
Valueの値とMin,Maxの値をそれぞれ比較して、

Min > Valueなら0
Max < Valueなら1
Min <= Value <= Maxなら0~1の値
※エルミート補間で値を計算

といったように値を返してくれます。

実際に見てみましょう。

以下のようなマテリアルを組んでみます。

そして、マテリアルインスタンス側でパラメーターをいじいじします。

お判りいただけたでしょうか?

ValueがMin以下のときとMax以上の時は値はそれぞれ0と1になっていましたが、0~1の値の時は、”それっぽい値”で補完してくれているように見えました。

図にするとこんな感じになります。

勘のいい人はお気づきになったかもしれませんが、
↑の動画ではMinとMaxにそれぞれ0と1をいれた状態で、Valueに値を色々入れてみましたが、例えばValueに「0.1」と入れた場合って”直感的に”言えば、返ってくる値も「0.1」な気がします。

しかし実際は「0.0280」という表示になっていました。

ここで重要なのが、「直線的な補間ではない」ということです。

どういうことかと言いますと、Min,Maxの間の値をとる方法として「エルミート補間」という計算方法を使っています。
(詳しい計算方法などはググってみてください…)

これは、簡単に言うと値の変化をなるべくスムーズに行うための計算方法なのです。

smoothstepノードを使わないでsmoothを実装するとわかるかもしれません。

↑の計算部分をhlsl化すると

float t = saturate(Value - Min/Max - Min);
return t * t * (3.0 - 2.0 * t); //ここがエルミート補間

となります。

この式は、「3x²-2x³」の3次関数なっており、「saturate」を外すと3次関数特有の曲線グラフを描きます。
↓マテリアルをグラフ化する「PlotFunctionOnGraph」関数を使って描画した結果

このように、3次関数特有の曲線が描かれます。

では逆に、補間部分を直線的なものにするならば、この3次関数的な計算式部分を使わずに、そのまま値を使えばいいだけになります。

hlsl構文だと↓

float t = clamp(Value - Min/Max - Min,0,1);
return t;

これで、直線的なsmoothstepを使うことができます。

図解すると以下のようになります。

さて、通常のsmoothstepに話を戻します。
smoothstepはどんな使い方ができるでしょうか?

smoothstepも考え方次第で無限に使い道がございます。

簡単な例としては、「のぞき穴」みたいなものを作ってみます。
マテリアルの属性(BlendMode)を「Translucent」にし、以下のようにマテリアルを組みます。

たったこれだけですが、Planeに張り付けるとのぞき穴のようになります。
(PostProcessMaterialとかの方がそれっぽくなるかもです)

もう少し発展させると、トゥーンシェーダーなんかでも使えます。

マテリアルの「Shading Model」プロパティを「Unlit」にして、以下のように組んでみます。

↓結果

Sphereだとわかりずらいので、グレイマンに適応してみます。
(グレイマンのマテリアルをUnlitにし、先ほどの処理を組み込んだもの)

こんな感じに、smoothstepはいろんなところで役立ってくれます。

これ以外にも「微分」なんかと合わせて使うと、割と面白いかと思います。

以下の記事はsmoothstepを使って水滴の屈折を微分で表現しているものになります。参考程度にご覧ください。

以上のようにstepやsmoothstepを使うと色々なことができるようになります。

是非活用してみてください!!

丁寧に書こうと思っておりましたが、結局雑な記事になってしまい申し訳ありません。

以上です!

※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です