rn.log

備忘録など

Unityエフェクトレシピ02 - 六角形シールド表現 (2/2)

はじめに

六角形シールド表現を作る方法を紹介します。

www.youtube.com

 

前回の記事では、エフェクト用の3Dモデルの作り方を紹介しました。

今回の記事ではシェーダーの作り方を紹介します。

 

目次 

 

サンプルデータ

今回のエフェクトはGitHubにて公開中です。

github.com

前回作成した3Dモデル

f:id:r-ngtm:20200609104721p:plain

 

3Dモデルの頂点には、エフェクトで使用するデータが格納されています。

アトリビュート 説明
uv
テクスチャ座標(モデル全体)
uv2
面それぞれに対して展開したテクスチャ座標
頂点カラー(Rチャンネル)
メッシュの中心から外側へ向かう、0~1のグラデーション
頂点カラー(Gチャンネル)
五角形・六角形メッシュの番号(0, 1, 2, ・・・, N)をNで割り、0~1の範囲に収まるようにしたもの

 

エフェクトの要素

今回のエフェクトは、6個の要素によって構成されています。

1. テクスチャ

f:id:r-ngtm:20200609225102g:plain

オーラ系のテクスチャをUVスクロールで流します。

2. ライン

f:id:r-ngtm:20200609230801g:plain

ラインを追加します。

3. 波紋

f:id:r-ngtm:20200610002351g:plain 

広がる波紋を追加します。

4. フレネル

f:id:r-ngtm:20200713224700g:plain

球のシルエットの部分を発光させます。(フレネル効果) 

5. 頂点アニメーション

f:id:r-ngtm:20200713213742g:plain

メッシュを法線方向にアニメーションさせます。

6. 文字スクロール(完成)

f:id:r-ngtm:20200713214106g:plain

文字テクスチャをUVスクロールで流し、完成です。 

 

第2章. シェーダーの作成

ここからは、エフェクトの作り方を解説していきます。 

 

Part 1 :  テクスチャスクロール

STEP 1 : テクスチャをモデルに貼る

f:id:r-ngtm:20200715225131j:plain

 

Masterノードは以下のように設定します。

f:id:r-ngtm:20200715225249p:plain

 

テクスチャをLerpで色をつけ、マスクテクスチャを乗算します。

f:id:r-ngtm:20200715225028p:plain

 

補足 : Lerpを使った色のブレンドについて

Lerpを使うと、色が暗い部分にはA、明るい部分にはBの色を付けるように色を混ぜることができます。

f:id:r-ngtm:20200609213808p:plain

 

今回のシェーダーでは、以下の部分でLerpを使用しています。

f:id:r-ngtm:20200715231757p:plain

 

STEP 2 : UVスクロール

UVに時間とVector2の数値を乗算したものを加算し、テクスチャがスクロールするようにします。

f:id:r-ngtm:20200715230155p:plain

 

結果

テクスチャが時間経過でスクロール移動するようになります。

f:id:r-ngtm:20200609225102g:plain 

 

Part 2 :  ラインの追加

次に、光が流れるラインを追加します。

f:id:r-ngtm:20200609230801g:plain

 

Step 1 : ラインを作る

3Dモデルの頂点カラーRチャンネルには以下のようなグラデーションが乗っています。

f:id:r-ngtm:20200609232038p:plain

 

このグラデーションにStepをかけて線を作ります。

f:id:r-ngtm:20200609233814p:plain

 

シェーダー

 頂点カラーのRチャンネルに、Stepをかけます。

f:id:r-ngtm:20200609232234p:plain 

結果

f:id:r-ngtm:20200609232353j:plain

 

補足 : Stepノードの挙動

Stepノードは以下のようなふるまいを持っています。

  • Edge < In なら 1
  • Edge > In なら 0

ある値をしきい値として二値化を加えたい場合に便利なノードです。

f:id:r-ngtm:20200609232856p:plain

 

Step 2 : 流れるグラデーションを作る 

今回は面ごとのテクスチャ座標をuv2アトリビュートとして保存していました。

f:id:r-ngtm:20200619121225p:plain

 

このuv2を利用してグラデーションのスクロールを作ります。

f:id:r-ngtm:20200609234654g:plain

 

ShaderGraph

UV1のX成分に時間を加算し、時間経過で移動するグラデーションを作ります。

f:id:r-ngtm:20200609234917p:plain

 

結果

f:id:r-ngtm:20200609234654g:plain

 

Step 3 : ラインとグラデーションを乗算する

Step1で作ったラインと、Step2のグラデーションを乗算して

ラインの上を光が流れるような表現を作ります。

f:id:r-ngtm:20200609235413g:plain

 

f:id:r-ngtm:20200610000428p:plain

 

 

Step 4 : 加算する(完成)

Part1へ今回のラインを加算すると以下のようになります。

f:id:r-ngtm:20200610000951g:plain

 

実際のシェーダーグラフは以下になります。

f:id:r-ngtm:20200610002023p:plain

 

 

Part 3 : 波紋

六角形の波紋を追加します。

f:id:r-ngtm:20200610002351g:plain

 

頂点カラーのRチャンネルには、波紋のグラデーションが格納されていました。

今回はこれを使用します。

f:id:r-ngtm:20200619122303j:plain

 

Step 1 : グラデーションを動かす

頂点カラーRチャンネルに時間を足し、Fractionをかけて0~1の範囲でリピートするようにします。f:id:r-ngtm:20200619123318p:plain

 

グラデーションが動き、以下のようになります。

f:id:r-ngtm:20200619124115g:plain

 

Step 2 : 二値化する

グラデーションをStepで二値化します。

f:id:r-ngtm:20200619124745p:plain

 

結果

広がるラインになります。

f:id:r-ngtm:20200619124956g:plain

 

Step 3 : 波紋をランダムにする

ここで、頂点カラーのGチャンネルには面の番号を0~1に収まるようにした値が設定されていました。

これを利用して波紋のタイミングをランダムにずらします。

f:id:r-ngtm:20200715151451p:plain

 

 シェーダー

頂点カラーのGチャンネルからランダム値を作り、これをグラデーションと足し合わせます。

f:id:r-ngtm:20200619130744p:plain

 

結果

波紋の時間がランダムにずれるようになります。

f:id:r-ngtm:20200713093031g:plain

 

Step 4

波紋をPart2と加算合成します。

f:id:r-ngtm:20200713222859p:plain

 

結果

f:id:r-ngtm:20200610002351g:plain

 

裏面の色を薄くする

メッシュのオモテ面とウラ面が重なった部分がゴチャゴチャしており、

見づらいものになっています。(赤線で囲った箇所)

f:id:r-ngtm:20200713230824p:plain

 

シェーダー 

メッシュの裏表判定(Is Front Face)を利用して手前のメッシュは濃く、向こう側のメッシュは薄く表示されるようにします。

 

Is Front FaceノードとBranchノードを以下のように接続します。

f:id:r-ngtm:20200713231227p:plain

 

オモテ面の場合は色をそのまま出力

ウラ面の場合は、1より小さい値を乗算した色を出力します。

f:id:r-ngtm:20200713232126p:plain

 

結果

f:id:r-ngtm:20200713233116j:plain

 

ビフォーアフターを並べてみました。 右のほうが見やすいですね。

f:id:r-ngtm:20200713233046p:plain

 

Part 4 : フレネル効果

シルエットの部分を発光させてバリアっぽい質感を加えます。

f:id:r-ngtm:20200713224700g:plain

 

フレネルの作り方 

STEP 1 : 内積

カメラ方向ベクトルととモデル法線Nの内積(Dot Product)をとります。

カメラの手前は黒く、奥は白くなります。

f:id:r-ngtm:20200715131118p:plain

今回は、両面の半透明描画なので、これだと球全体が白く表示されてしまいます。

 

STEP 2 : 絶対値Abs

内積値に絶対値Absを適用します。

カメラから見て球の中央は白く、フチの部分は黒くなります

f:id:r-ngtm:20200715131900p:plain

 

STEP 3 : OneMinus

OneMinusを適用すると、フチの部分だけ白くなります。

f:id:r-ngtm:20200715132335p:plain

 

フレネル部分のシェーダー

フレネル効果をシェーダーグラフで実装すると以下のようになります。

 

f:id:r-ngtm:20200713235826p:plain 

内積(Dot Product) + Abs + OneMinusでフレネルを作った後、

Pow でコントラストを調整しています。

Normal Vectorノードで法線が取れます。

 

全体

今回作ったフレネルは、AddでPart 3と合成します

f:id:r-ngtm:20200714001336p:plain

 

 結果

f:id:r-ngtm:20200713224700g:plain

 

フレネルあり・なしを並べてみました。右のほうが質感がリッチですね。

f:id:r-ngtm:20200715140338p:plain

 

Part 5 : 頂点アニメーション

シェーダーで頂点をアニメーションさせます。

f:id:r-ngtm:20200713213742g:plain

 

STEP 1 : sinで頂点を動かす

頂点を法線方向へsinで動かすようなシェーダーを組みます。

f:id:r-ngtm:20200715144009p:plain

 

Add(計算結果)はMasterノードのVertex Positionの部分へ接続します。

f:id:r-ngtm:20200715144501p:plain

 

sinカーブでメッシュが動くようになりました。

f:id:r-ngtm:20200715142421g:plain

 

STEP 2:  頂点アニメーションをランダムにずらす

次に、六角形ごとに頂点がランダムに動くようにします。

f:id:r-ngtm:20200713213742g:plain

 

シェーダー

STEP1で組んだシェーダーグラフに変更を加えます。

ランダム値をTimeにAddし、それをSinへ入力します。

f:id:r-ngtm:20200715152715p:plain

 

ここでは頂点カラーGチャンネル使用していますが、

Gチャンネルには以下のような色が格納されています。

f:id:r-ngtm:20200619125137j:plain

 

 

結果

頂点アニメーションのタイミングがランダムにズレるようになりました。

f:id:r-ngtm:20200713213742g:plain

 

 

Part 6 : 文字スクロール

最後に文字スクロールアニメーションを加えます。

f:id:r-ngtm:20200713214106g:plain

 

シェーダー

文字テクスチャを時間経過でスクロールさせます。

f:id:r-ngtm:20200715161419p:plain

 

 そして、Part 5と文字テクスチャをAddで合成します。

f:id:r-ngtm:20200715233634p:plain

 

結果

文字がスクロールするようになりました。

f:id:r-ngtm:20200713214106g:plain

 

 

f:id:r-ngtm:20200715163433p:plain

以上でエフェクトの完成です。

 

最終的なシェーダーは以下にようになります。 

f:id:r-ngtm:20200609133051p:plain