この記事では、Shader Graphの使い方の解説記事の第7回です。
ShaderやShader Graphを初めて触る方は、以下の内容を読んでからの方が理解出来る内容になっています。
はじめてのShader・Shader Graph 解説 その1 :シェーダーってそもそも何?ShaderGrphはなにが出来る?
はじめてのShader・Shader Graph 解説 その2:ShaderGrphで学ぶ、CGの色のキホン
はじめてのShader・Shader Graph 解説 その3:超汎用・頻出ノードの使い方
はじめてのShader・Shader Graph 解説 その4:ShaderGraphの編集画面の見方(解説書)
はじめてのShader・Shader Graph 解説 その5:基本のテクスチャを動かすUVスクロールのやり方
はじめてのShader・Shader Graph 解説 その6:ノイズの使い方
3ヶ月かかりましたが、今回でこの連載は一段落の予定です。ここまで付いてきてくれた方、ありがとうございます!
ではいきましょう!

ShaderGraphを使ってパーティクル表現をもっとリッチに!!
前回の解説までで、シェーダーを使うと、ノイズを使うなどをすると様々な模様を作ることができ、それらに色を付けたり、スクロールして動かすことで、多様な表現が出来る、ということを解説しました。
最後に、このシェーダーを使って、パーティクル(エフェクト)をよりリッチな表現にしていく方法を解説します。
パーティクルシステム(Shuriken)でエフェクトを作るときのポイント
出現と消滅を自然に見せることが大事!
パーティクル(Shuriken)の基本的な説明や使い方について全部まともに解説すると、何本も記事を書かないといけないので、本記事のShaderGraphの解説に絡む部分だけ解説。
まず、パーティクルシステム(Shuriken)とは、一言で言えば、エフェクトを作るための1つのツールです。

こういったパーティクルを違和感無く自然に見せるコツは、出現と消滅を自然に見せることです。
無からパーティクルが急に湧き出てくるケースは無くはないのですが、唐突な印象を見せてしまいがちです。
パーティクルの出現と消滅の表現には、透明度を切り替えて表現することが多いです。
透明度を切り替えるには、パーティクルシステムの「生存期間の色」から調整可能です。

こういったフェードイン/フェードアウトを透明度を変える表現で行うのもアリなのですが、ShaderGraphを使うことで、さらにリッチなフェードイン・フェードアウト表現を行うことが出来ます。
例えば、右の煙の表現より、左の煙の表現の方がちょっとリッチに見えないでしょうか?


デフォルトのShaderの場合、パーティクル用のTextureのサイズや色を変えることは出来ますがTexture自体に細工は出来ません。
しかし、カスタムShaderを作ることで、Texture自体に細工を加えることが出来るため、よりリッチな表現が可能になるのです。
上記の例だと、Textureを徐々に消していくディゾルブ(徐々に欠けていく表現)をShader側で行っています。
他にも、ShaderGraphで作ったノイズの模様を、パーティクルとして出力することで、動きのある複雑でリッチな表現も可能になります。
例えば、この炎のエフェクトはどのように出来ているのかというと、

ノイズを使って作った模様をUVスクロールさせるShaderを作り、このShaderを割り当てたパーティクル達が上に進むにつれて徐々に小さくなっていくことで実装しています。

ノイズがどういったものか忘れてしまった人は、以下の記事をチェック!

UVスクロールがなにかを忘れてしまった人は、以下の記事をチェック!

パーティクル用のShaderを作れるようになると、パーティクル表現の幅が無限大になります。あのゲームで見たあんな表現やこんな表現も作れるようになるかも!
ぜひ、使い方を、ぜひマスターしましょう!
※本記事では、VFX Graphの解説はしません。ですが、VFX Graphを使うことで、パーティクルシステム(Shuriken)よりも連携がしやすくなります。数少ないUnity標準のイチオシ機能です。
ShaderGraphで作ったShaderをパーティクルで使う方法
今回は、以下のように、徐々にリングが細くなっていく波紋エフェクトの作り方を通じて、ShaderGraphとパーティクルシステムとの連携方法のやり方を紹介します。

ShaderGraph側の作業
イメージとしては、以下のようなテクスチャに対して、くり抜かれる範囲を広げていく、みたいなイメージで作っていきます。

※著作権は放棄しているので、好きにDLして使ってもらってOKです。
また、今回は説明のために上記のテクスチャを使用していますが、好きなものに変えていただいて問題ありません。
文字で書くよりも、実際にご自身で作ってみた方が理解が早いので、まずは以下のようなノードで、ShaderGraphを作ってみてください。
画像が見づらかったらクリックしてください、大きくなります。

プロパティには、Texture2Dをセットし、Texという名前にしました。
Texには、先ほどDLしたTextureをセットしてください。

あとは確認です。
Sliderの値を変化させて、Textureがどう切り替わるか確認してみましょう。

Sliderの値を増やすと、大きくくり抜かれ、値を減らすとなくなることが確認出来ればOKです。
簡単にどういったことをやっているかを解説。
Step1でやっていることを、3つのエリアに分けて解説します。

1.くり抜く図形の作成(左下)
今回は円状にくり抜きたいので、まず、左下のエリアで、円のくり抜きを作っていきます。
UV - (0.5,0.5)とすることで、中心から円状に値がグラデーションしていきます。
これをStepノードに接続することで、一定の値よりも小さい値が0になり、円が出来上がります。
この円を、Textureからくり抜くため、Textureの値からSubstructしていく(引き算して消していく)、ということがやっていることの肝の部分です。
本当に文字で伝わらないことは分かっているで、ぜひご自身で左から順番に作っていくと、たぶん先程書いた説明の意味が少しだけ分かるはず...。
2.値範囲の調整(左上)
左上のエリアでやっていることはRemapという処理です。これは、値を受け取って別の値に置き換えてくれる便利ノードです。
このSliderの値が0の場合は、くり抜きされておらず、Sliderの値が1の場合にくり抜きをするためにRemapノードを設定しました。
3.Textureの取得(右上)
これは特に言うことはないですが、純粋にTextureを取得しているだけです。
次に、Step2の内容について。
その3で解説した通り、パーティクルシステムやLineRendererなどのコンポーネントの色を取得するには、VertextColorを使います。
VertexColorと、今回作成した模様をMultiplyして、BaseColorとAlphaに接続すれば完成です。
ちなみに、VertexColorを接続すると、プレビューが3Dになることがあるので、2Dのままにしておきたい場合は、GraphInspectorのPreviewを、「Preview2D」に設定すると2Dに設定出来ます。

Shader側は完成ではないのですが、ここで一旦いま作ったShaderを割り当てたマテリアルを作成し、パーティクル側の設定作業に移ります。
パーティクル側の作業
次にパーティクルです。新規でパーティクルを追加し、先程作成したShaderをセットしたマテリアルを割当てます。
スクショが貼られていない設定箇所は全部OFFだと思ってください。

設定値は以下のようにしました。この辺りはお好みで。


生存期間の色

アルファ値を20%と、70%段階で120になるようにセット。
生存期間のサイズ

カスタムデータ

これが今回の解説で一番重要です。モードをベクトルにして、設定してください。
このカスタムデータ部分が、ShaderGraphの値との接続箇所になります。
Xの値を以下のようなグラフにします。これがくり抜かれるサイズの遷移だと思ってください。

レンダラー

ここも重要です。
カスタム頂点ストリームというのが、ShaderGraphと接続出来るような値を用意しますよ、という設定です。
これが無いと、ShaderGraphの値をパーティクルシステムに持ってこれません。
チェックを付けたあとに、Custom1.xというものを追加してください。

すると、カスタム頂点ストリームの中に、Custom1.x(TEXCORD0.z)というものが追加されたと思います。

これでOKです。
正直、ここはなにやっているかよく分からなくて良いです。次で解説します。
ShaderGraphのパラメータとパーティクルを接続する作業
先程の工程で、パーティクルシステム側がShaderGraphの値を受け取れるようになりました。
次は、ShaderGraph側からもパーティクルシステムこの値を接続するよ、というの設定する必要があります。
やり方は簡単です。
とりあえず、先程のShaderGraphに一度戻り、先ほどSliderを接続していたノードを外し、UV > Split > Bを接続するように修正します。

これで完成です。
パーティクルを確認してみると、以下のように徐々にリングの幅が小さくなるはずです。

超分かりづらいと思うのですが、今回の工程の肝の部分を解説。
分かりづらいのは同じ要素が、Unity内で違う言葉で表示されているからです。
まず、パーティクル側の設定でカスタム頂点ストリームを追加し、Custom1.x(TEXCORD0.z)となっていたと思います。
TEXCORD0.zは、ShaderGraph上の、UVをSplitしたBから出力している値と同じ、という意味です。(えぇ~)
TEXCORD = UV という認識で問題ありません。
そして、.xはUVをSplitしたR、.yはUVをSplitしたG、zはUVをSplitしたBというように読み替えてください。(えぇ~)
そして、TEXCORD0の「0」の部分。
これは、ShaderGraphのChannelの「UV0」というものと対応しています。(えぇ~)

つまり、カスタム頂点ストリームが以下のように表示されていたら、

ChannelをUV1のUVをSplitしたBから出力されているものと同じ、という意味です。(なんて分かりづらい...)
UV0のChannelのBに渡す値を設定するのが、先程のパーティクルシステムのカスタムデータの箇所です。
これをカーブにすることで、徐々にくり抜き範囲が広くなっていく、という見た目になったという訳です。

このカーブの動きを変えると、また違った印象のエフェクトになるので、色を変えてみたりしてぜひ好きな表現になるように試してみてください。
まとめ
今回の方法だけ知っても、まだ自分でエフェクトは作れないよ~という人もいるとは思います。
そんな方には、「Easy Custom VFX/UI」というアセットがおすすめです(自作自演)!
豊富なエフェクト作例+実際のShaderの中身を、解説コメントとともに紹介しているアセットになっています。
ぜひ見ていってください!

今回の解説内容の分かりづらい点等あれば、アセット購入者用のDiscordにて回答率100%のQAを受付ていますので、よければ参加ください。
また、ずっとこの連載でシェーダーやシェーダーグラフをカタカナではなく、Shader、ShaderGraphと英語表記していたのには理由があります。それは、これらの情報は日本語の初心者向けの情報が非常に少ないのですが、英語のサイトには有用な情報が沢山あるからです。
このサイトの書いていることよく分かんねぇな、となったらぜひ英語で情報収集してみることをオススメします。
現代では、一瞬で翻訳出来るので、言語の壁も低いです。
私自身、Shaderをちゃんと学習するまでは、「あのゲームのリッチなビジュアル表現や演出が、一体なにをどうしたら出来あがるのか」、微塵も想像することが出来ませんでした。
ですが、英語の情報をかき集め、Shaderを学習するにつれ、ちょっとずつですが「どうやったら出来るのか」が想像出来るようになりました。
Shaderが難しそうと感じたことがあれば、それは逆にチャンスです。なぜなら他の人も同じように感じているはずだからです。周りがやらない・出来ないことが出来ると、”価値”になります!
それでは素敵なゲーム制作ライフを!
コメント