【Unity】シェーダーグラフで作るエフェクト用シェーダー:アルファと加算 ~前編~

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

 

こんにちは。

 

今日は、エフェクトを作るにあたって絶対に外せないアルファブレンドと加算ブレンドのシェーダーを、シェーダーグラフで作ってみたいと思います。
これがないと始まらないというような基本のシェーダーです。

 

今回作るシェーダーの内容は下記の4つになります。
全てパーティクルエフェクト用のシェーダーですよ。

  • テクスチャ1枚で制御する最もシンプルなアルファブレンドシェーダー
  • テクスチャ1枚で制御する最もシンプルな加算ブレンドシェーダー
  • カラーとマスクを別テクスチャで制御するアルファブレンドシェーダー
  • カラーとマスクを別テクスチャで制御する加算ブレンドシェーダー

 

 

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

 

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

 

 

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

 

 

テクスチャ1枚で制御する最も簡単なアルファブレンドシェーダー

まずはアルファチャンネル付きのテクスチャ1枚を使った、一番シンプルなシェーダーを作ってみましょう。
使用するのは下記のテクスチャです。

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

 

 シェーダー全体図

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

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

 

 

 ① マスターノードの設定

今回作成するのはアルファブレンドですので、SurfaceをTransparent(半透明)に、BlendをAlpha(アルファ)にします。

 

 

 ② 使用するテクスチャを指定

ここでは使用するテクスチャを指定しています。
マテリアルからテクスチャを差し替えられるように、「Texture 2D Asset」ノードを「Sample Texture 2D」ノードのTextureに繋ぎ、プロパティ化しています。

 

 

 ③ パーティクルシステムからカラー(RGB)とアルファ(A)を編集できるようにする

エフェクトを作る際、下図のようにパーティクルシステムのStart ColorやColor over Lifetimeなどでカラーとアルファの値を編集すると思います。

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

 

このようなパラメーターを有効にするためには、シェーダー内に「Vertex Color」ノードを含める必要があります。

 

UnityパーティクルシステムのColorは、使用しているビルボードやメッシュの頂点カラーとアルファを変更する機能(っぽい)だからです。

 

 

 ④ テクスチャカラーと頂点カラー(RGB)をブレンドする

ただ「Vertex Color」ノードを置いただけではパーティクルシステムから編集できるようにはなりません。

 

下図のように「Sample Texture 2D」と「Vertex Color」を「Multiply」ノードで乗算する事で、パーティクルシステムから変更した色が「Vertex Color」ノードに反映され、その色がテクスチャカラーに乗算されて出力されるという流れが完成します。
最後にマスターノードのColorに繋ぐのを忘れないで下さいね。

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

 

 

 ⑤ テクスチャアルファと頂点アルファ(A)をブレンドする

アルファもカラーと同様にパーティクルシステムから編集できるようにしましょう。
下図のように「Sample Texture 2D」と「Vertex Color」のアルファを「Multiply」で乗算します。

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

 

カラーには無かったノードがありますね。
「Split」ノードは、4チャンネルまでのまとまったチャンネルをバラバラに分割するノードです。
これにより「Vertex Color」のアルファ(A)チャンネルのみを抽出しています。

 

「Sample Texture 2D」からもアルファ(A)チャンネルのみを持ってきて、「Multiply」で乗算し、それをマスターノードのAlphaに繋いでいます。

 

こうする事で、パーティクルシステムで編集したアルファの値がテクスチャのアルファとブレンドされ、最終的にパーティクルのアルファへと反映されるようになります。

 

 

これで今回のシェーダーは完成です。
実際にマテリアルにアサインして使ってみましょう。

 

下図は今回作ったシェーダーをアサインしたマテリアルです。
TEX_Color & Maskという項目の右側に今回使ったテクスチャがアサインされています。
このテクスチャは自由に差し替え可能です。

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

 

このマテリアルをアサインしたパーティクルがこちらになります。

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

 

ちゃんとアルファチャンネルのテクスチャで抜けて、パーティクルが上の方に行くにつれ透明になっていると思います。
透明になってるのはColor over Lifetimeでアルファ値を減衰させているためです。
色もパーティクルシステムで付けています。

 

このように今回のシェーダーを使えば、アルファチャンネルを含むテクスチャ1枚で、アルファブレンドを使用したエフェクトが作れちゃいます。

 

次は同じテクスチャを使用して、加算ブレンドバージョンも作ってみましょう。

 

 

~おまけ情報~

 

解説の途中、⑤番の箇所で「Split」ノードを使う場面がありました。
これにより「Vertex Color」ノードのアルファチャンネルのみを抽出したわけですが、これをした時にふとこんな事を思いました。

 

「カラーもSplitノードでRGBだけ抽出する必要があるんじゃないか?」

 

アルファを「Split」ノードで分けたのは、これをしないと頂点カラー(RGB)の値が混じって正しい結果にならないからですが、カラーの方も頂点アルファ(A)の値が混じってしまうとまずいと思ったからです。

 

先に結論から言うと、この考えは杞憂でした。

 

なぜなら、マスターノードのColorは、入力された値のRGBのみを使用するからです。
マスターノードを見ると「Color(3)」となっていますよね?
これはRGBAの上の3つのチャンネル(RGB)のみ使いますよという事を表します。

 

ですのでカラーの方は「Split」ノードでRGBを抽出する必要はありません。
やっても結果は同じですが、今回のシェーダーでは無駄なノードが増えるだけなので使っていません。

 

 

テクスチャ1枚で制御する最も簡単な加算ブレンドシェーダー

先ほど作成したシェーダーの加算バージョンも作ってみましょう。
使用するのは先ほどと同様、アルファチャンネルを含む下記のテクスチャです。

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

 シェーダー全体図

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

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

 ① マスターノードの設定

今回は加算ブレンドですので、SurfaceをTransparent(半透明)に、BlendをAddive(加算)にします。

 

 

 ②~⑤ 頂点カラーとテクスチャをブレンド

ここはアルファバージョンと同じです。

 

 

 ⑥ カラーとアルファを乗算してからマスターノードにつなぐ

 

 

アルファバージョンとの大きな違いはここです。

 

テクスチャと頂点カラーのカラーとアルファを全てブレンドしてから、マスターノードのColorに繋いでいます。

 

なぜこうするかというと、加算ブレンドのシェーダーはアルファが使えないからです。

 

試しに先ほど作成したアルファバージョンのマスターノードを加算に変更してみて下さい。
テクスチャのアルファチャンネルは無視され、Color over Lifetimeで透明度を減衰させていた設定も無効になっているはずです。

 

この問題を、エフェクトの見た目を同じに保ちつつシェーダー以外で回避する方法はありますが、その際は下記の2つの変更が必要になります。

 

①:加算用にカラーチャンネルのみで同じ見た目のテクスチャを用意する
②:パーティクルシステムの透明度をアルファではなくカラーのみで編集する

 

この2つを行えば問題は回避できますが、別の問題が出てきてしまいます。

 

①の問題点はテクスチャの容量と作成する手間が増えるという点です。
ゲームを開発する際、エフェクトの数が数百個に及ぶ事は少なくありません。
そのエフェクト1つ1つに対して新しいテクスチャを作っていては時間がいくらあっても足りませんし、エフェクト用に確保されたメモリもオーバーしやすくなってしまいます。
そのため、エフェクト用のテクスチャは他のエフェクトにも流用する事を考慮して作る事がほとんどです。
その観点からいくと、加算用、アルファ用でテクスチャを別に作るのはもったいないですね。(もちろん100%無いという事はないですよ)

 

次に②の問題点です。
加算はカラー(RGB)の値を0にすると透明になります。アルファだと黒になりますね。
そのため、加算を使ったエフェクトはカラーで透明度を編集すれば問題解決、という事になりますが、まあ、「Color over Lifetimeで色の変化もつけつつ透明度も編集する」というのがとても面倒くさいです。
できなくはないんですけどね。
一発で最終的な色が決まるという事はあまり無いので、調整の手間を考えると個人的にはこの問題は避けたいところです。

 

このような問題があるので、今回はテクスチャのアルファチャンネルも有効にしつつ、パーティクルシステムからアルファを編集できる加算シェーダーを目指しています。

 

で、実際どうすればいいのかな~としばらく悩んだ末、答えが見つかりました。

 

マスターノードでアルファが使えないのなら、マスターノードに繋ぐ前にテクスチャのカラーとアルファ、頂点カラーと頂点アルファのブレンドを全て済ましてしまえばいいのです。

 

ここで今回のシェーダーの④と⑤の工程を振り返ってみましょう。

 

④の時点ではテクスチャのカラーと頂点カラーがブレンド済みです。
⑤の時点ではテクスチャのアルファと頂点アルファがブレンド済みです。

 

という事は、これらを「Multiply」ノードで乗算してあげれば、全てがブレンドされた計算結果がここで求められるわけです。

 

その結果をマスターノードのColorに繋げてあげれば、作りたかったテクスチャのアルファチャンネルも有効にしつつ、パーティクルシステムからアルファを編集できる加算シェーダーが完成です!

 

下図は今回のシェーダーを適用したパーティクルです。
ちゃんとテクスチャのアルファチャンネルで抜けてますし、アルファの減衰もされていますね。

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

 

 まとめ

今回はエフェクトで最も基本のシェーダーとなる、テクスチャを1枚使ったアルファブレンドと加算ブレンドのシェーダーを作ってみました。

 

いかがだったでしょうか?
マテリアルからテクスチャの差し替えもしない!パーティクルシステムでカラーの編集もしない!
だったら単純にテクスチャ1枚貼ったノードを直接マスターノードに繋いでしまえばいいのですがそうもいかないですよねw
そのために今回のような一手間が必要になります。

 

本当はこの記事でカラーとマスクを別テクスチャで制御するシェーダーの解説もしたかったのですが、思いの他解説が長くなってしまったため今回は前編とし、次の後編で解説していこうと思います。

 

最後に、今回のシェーダー作成で僕が学んだ教訓をひとつだけ述べて終わりにしたいと思います。

 

  1. シェーダーは、出来ないと思った事でも解決法はある!

 

 

それでは、後編もお楽しみに!