【Unity】シェーダーグラフで作るエフェクト用シェーダー:UVスクロール

f:id:Effect-Lab:20180630213349j:plain

 

こんにちは。

 

今日はエフェクトでよく使う表現、UVスクロールのシェーダーを、シェーダーグラフで作ってみたいと思います。

 

今回作るUVスクロールシェーダーの内容は下記の3つになります。

  • 一定の速度でUVスクロールするシンプルなシェーダー
  • パーティクルの寿命に合わせてスクロール速度が変化するシェーダー
  • パーティクルシステムでスクロールのアニメーションを可能にしたシェーダー

3つありますが、エフェクトでよく使うのは3つ目の「パーティクルシステムでアニメーション可能なシェーダー」だと思います。
ただし、初めの2つも使う場面はよくあるので是非ご覧下さい。 

 

また、今回はシェーダーだけではなく、Vertex StreamsCustom Dataも使う必要があるため、そちらの使い方も一緒に解説しています。
「Vertex Streams?Custom Dataって何?」という方は是非読んでみてください。新しい発想のきっかけになるかもしれません。

 

ちなみに僕は「何それ?おいしいの?」状態だったのですが、ツイッターで池和田さん(Yusuke Ikewada (@ivoryfunc) | Twitter)が使い方を教えて下さり、「シェーダーと連動させてなんかいろいろできそうだぞ!」と道が開けた感じがしました。
サンプルデータまで用意して教えていただき本当に助かりました。
池和田さん、ありがとうございました!

 

では、シェーダーの解説に進みましょう。

  

まだ公式から配布されているサンプルのプロジェクト内でないとシェーダーグラフが使えないようですので、こちらのページから「ShaderGraphExamples-master」プロジェクトをダウンロードして下さい。

 

シェーダーグラフの使い方が解らない!という方は下記のページで使い方の基本を解説していますので御覧ください。

 

それではいってみましょうー! 

 

 

 

一定の速度でUVスクロールするシンプルなシェーダー

まず最初に一番シンプルなUVスクロールシェーダーを作ってみましょう。
シンプルと言っても、下図のようにマテリアルでUとVのスクロール速度を変更できるようにだけはしてあります。 

f:id:Effect-Lab:20180708230950g:plain

 

 

 シェーダー全体図

f:id:Effect-Lab:20180714171404j:plain

 

シェーダーの全体は上図のようになります。
ここから各ノードで何をしているのか、全体の流れを解説していきます。 

 

 ① アニメーションをさせる

今回は一定の速度で流れるUVスクロールを作りたいので「Time」ノードを使います。「Time」ノードのTime(1)に繋げれば、1秒でUVが1周分流れる速度にできます。

  

 ②③ マテリアルからスクロール速度を変更できるようにする

ここでは「Vector1」ノードを「Time」ノードの速度に乗算して、UとVそれぞれのスクロール速度に倍率をかけられるようにしています。

 

さらにパラメーター化する事で、マテリアルから速度を変更できるようになります。

 

 

 ④ テクスチャノードのUVに繋ぐ

①②③で作成したノードを「Combine」でXYの2チャンネルの値にまとめ、この値を「Tiling And Offset」のOffsetに繋ぎます。

 

これでテクスチャのUVオフセットがそれぞれ指定した速度で動くので、スクロールアニメーションが可能になります。

 

以上で今回のシェーダーは完成です。

 

「Vertex Color」ノードの部分は、パーティクルシステムからカラーとアルファの値を編集できるようにするためのノードなので今回のUVスクロールとは関係ありません。

 

 

 

パーティクルの寿命に合わせてスクロール速度が変化するシェーダー

次はパーティクルの寿命の長さに応じてスクロール速度が変化するシェーダーを作ります。

下図は左から順番に0.5秒、2秒、5秒の寿命を持つパーティクルに、これから作る寿命内で1周するシェーダーアサインした状態です。
寿命の開始と終了がわかりやすいようにアルファのアニメーションも加えています。

f:id:Effect-Lab:20180715112230g:plain


寿命が長くなるほどスクロールスピードも遅くなっているのがわかると思います。

 

では実際に作ってみましょう。

  

 シェーダー全体図

f:id:Effect-Lab:20180715013237j:plain

 

 

シェーダーの全体は上図のようになります。
ここから各ノードで何をしているのか、全体の流れを解説していきます。 

 

 ① パーティクルの寿命とスクロール速度を連動させる

今回のシェーダーはパーティクルの寿命の長さに応じてスクロール速度を変えたいので、パーティクルからシェーダーへ、寿命のパラメーターを渡す設定を加える必要があります。

 

そのためには、Rendererモジュールにある「Custom Vertex Stream」という項目で、「AgePercent(TEXCOORD0.x)」を追加します。

f:id:Effect-Lab:20180715155501j:plain

 

追加するには右下の+ボタンを押してLifetime→AgePercentを押します。

f:id:Effect-Lab:20180716160246j:plain

 

「AgePercent」を使うと、各パーティクルの寿命の経過割合を0~1の範囲でシェーダーに渡す事ができます。

 

例えば寿命が3秒のパーティクルの場合、AgePercentの値は発生時は「0.0」、1.5秒経過時点で「0.5」、3秒経過時点で「1.0」となります。
この値をシェーダー側でUVのオフセット値として受け取る事で、寿命に対して1周分スクロールする表現が可能になります。

 

ではこのAgePercentの値をシェーダー側で受け取る設定をしていきましょう。

 

 

AgePercentの後ろに表示されている「TEXCOORD0.z」という表示に注目して下さい。

f:id:Effect-Lab:20180716161746j:plain

 

TEXCOORD0は各頂点のUV座標を指定するため、シェーダーグラフ内では「UV」ノードを使ってこの値を受け取る事ができます。
zは「UV」ノードのXYZWの4チャンネルのうち、Zの値で受け取る事を表しています。

 

という事は、1つ目に作った一定の速度でスクロールするシェーダーのTimeの部分を、

f:id:Effect-Lab:20180716162926j:plain

 

下図のように「UV」ノードに変えてあげれば、1秒間に1スクロールというシェーダーが、寿命の経過時間に応じてスクロールするシェーダーに変わるという事になります。

f:id:Effect-Lab:20180716163013j:plain

 

「Split」ノードでB(1)の値を抜き出しているのは、「UV」ノードの3チャンネル目(Z)でパーティクルから寿命の値を受け取っているためです。
(※シェーダー内のXYZWとRGBAは同じ意味です)

 

これでパーティクルの寿命に合わせてスクロール速度が変化するシェーダーが完成しました。

 

1つ目のシェーダーと同様にマテリアルからスクロール速度を変えられるため、寿命に応じて2周、3周とスクロールさせる事も可能です。

 

 

Vertex Streamについて

ここでVertex Streamについて簡単に説明しておきたいと思います。

 

Vertex Streamは、簡単に言ってしまうとパーティクルの頂点情報です。

 

パーティクルを新しく作成した際、Vertex Streamには下図のパラメーターが最初から設定されています。

f:id:Effect-Lab:20180717005911j:plain

Positionは頂点の位置を、Normalは頂点の法線方向を、Colorは頂点のを、UVは頂点のUV座標を、()内のシェーダー関数に渡します。

 

それぞれの値をシェーダー側で受け取る事で、パーティクルやテクスチャが正しく表示されます。

 

これらに加え、新たに頂点にパラメーターを追加する事で、今回のUVスクロールのようなデフォルト状態では出来ないような表現が可能になります。

 

Vertex Streamには色んなパラメーターが用意されているので、様々な使い方がありそうですね。

 

 

パーティクルシステムでスクロールのアニメーションを可能にしたシェーダー

では最後に、パーティクルシステムのアニメーショングラフを使ってUVを自由にアニメーションできるシェーダーを作ってみましょう。

 

下図は、1~3秒でランダムの寿命を持つパーティクルをUVスクロールさせている状態です。

f:id:Effect-Lab:20180716202706g:plain

 

このスクロールは、UVそれぞれに下図のようなアニメーションを設定しています。

f:id:Effect-Lab:20180716201424j:plain

 

実際に作っていきましょう。

 

 シェーダー全体図

f:id:Effect-Lab:20180716202332j:plain

 

シェーダーの全体は上図のようになります。
今回はマテリアルからスクロール速度をコントロールする必要は無いので前の2つのシェーダーと比べると少しシンプルですね。


ここから各ノードで何をしているのか、全体の流れを解説していきます。 

 

 ① パーティクルで指定したアニメーションとスクロールを連動させる

今回は、前回のシェーダーで使った「Custom Vertex Stream」に加えて「Custom Data」モジュールを使用します。
このモジュールを使って、UVにアニメーションを付けていきます。

 

まずはVertex Streamの設定です。

 

下図のように、「Custom1.xy(TEXCOORD0.zw)」を追加します。

f:id:Effect-Lab:20180716203137j:plain

これでTEXCOORD0のZとWが、Custom1のパラメーターの値を受け取るようになります。

 

次に、「Custom Data」モジュールを追加します。

f:id:Effect-Lab:20180722213950j:plain

今回は UとVの2つのパラメーターにアニメーションを付けたいので、Modeを「Vector」に、Number of Componentsを「2」にします。

 

以上でCustom1に設定したアニメーションが、Vertex StreamによってシェーダーのTEXCOORD0のZWに送られるようになります。

 

最後にシェーダーの設定をしましょう。

下図のように「UV」ノードを作り、「Split」ノードでRGBAの「BA」を抽出して、Custom Dataの値がテクスチャのオフセットに渡るように繋ぎます。

f:id:Effect-Lab:20180722215018p:plain

 

これでスクロールアニメーションさせる準備は整いました。

 

Custom Dataモジュールに戻って、下図のようにX(U)とY(V)に適当なアニメーションを付けてみて下さい。

f:id:Effect-Lab:20180722213037j:plain

 

すると、アニメーショングラフで設定した速度でUVがスクロールするかと思います。
(※Custom Dataのグラフはパーティクルのライフタイムと連動しているため、あえてVertex Streamで寿命パラメーターを頂点に設定する必要はありません。)

f:id:Effect-Lab:20180716202706g:plain

 

 

以上で今回のシェーダーは完成です。

 

 

 まとめ

いかがだったでしょうか。
今回はエフェクト制作に欠かせないUVスクロールのシェーダーを作ってみました。

 

UVスクロールはシェーダーだけでなく、Vertex StreamCustom Dataでパーティクルシステムから頂点に情報を追加し、シェーダー側に渡す設定を加えなければなりません。

 

ただ、一度理解してしまえば難しい事ではないかなと思います。

 

僕はまだVertex SteramとCustom Dataを今回の使い方しか知らないですが、今後また良い使い方が見つかったら、このブログに書こうと思います。

 

それでは、次回もお楽しみに!