さわぐちFMオキーステーション

幸せの鐘が鳴り響き僕はただ嬉しいふりをする

Shader Graphの超入門レシピ その10~ノイズを使ったちらつき表現~

前回の記事

amidamangrove.hatenablog.com

今回の記事

ノイズを使用したお手軽な「ちらつき表現」を紹介したいと思います。

f:id:amidaMangrove:20200419115828p:plain

ちらつきを作るシェーダー

f:id:amidaMangrove:20200419105244p:plain

Timeノード」から時間を取得し、「Fractionノード」で小数点部分のみを取り出します。取り出した値を「SImple Noseノード」のUV値に設定します。ノイズから取得した値を「Stepノード」につなぎ完成です。

Previeを見るとStepノードがちらついているのが確認できると思います。 f:id:amidaMangrove:20200419105636g:plain

この出力される値をMultiplyノードに繋げば「ちらつき」や「ランダムな効果」を与える事ができそうです。

毎回、毎回ノードを繋ぐのも面倒なのでSub Graphにして使いまわせるようにしましょう。

Sub Graphを作る

Sub Graphにしたいノードを範囲選択し、「右クリック→Convert To Sub-graph」を選択します。名前は「Flicker」とします。

f:id:amidaMangrove:20200419110039p:plain

f:id:amidaMangrove:20200419110305p:plain

Sub Graphにしてみましたが何やらエラーが出ているようです。これは値が出力されていないのが原因です。

f:id:amidaMangrove:20200419110339p:plain

作成したノードをダブルクリックで開き、出力値を設定してあげましょう。「Output」の歯車ボタンで出力する値を追加できます。Vector1型で名前はOutにしてStepからの出力を繋ぎます。

f:id:amidaMangrove:20200419110648p:plain

外部からの入力値も追加しましょう。「Scale」と「Edge」をプロパティに加え、適宜ノードに繋ぎます。 f:id:amidaMangrove:20200419110948p:plain

Save Assetで保存し、元のシェーダーグラフを確認するとオリジナルの「Flickerノード」が無事に作られています。 f:id:amidaMangrove:20200419111153p:plain

ではこのノードを使用して遊んでみましょう。

ちらつきで遊ぶ

UVにノイズを加算し描画位置をズラし、画面のブレを表現してみます。 f:id:amidaMangrove:20200419113335g:plain

f:id:amidaMangrove:20200419113322p:plain

Lerpを使用することで別の画像に切り替えるということもできます。不可解な画像を差し込んでちょっと不気味な表現もできます。

f:id:amidaMangrove:20200419115337g:plain f:id:amidaMangrove:20200419115444p:plain

10クリックでHDRP + VRを実現する

事前に用意する環境諸々

記事中ではUnity 2019.3.x + Oculus Quest + Oculus Linkを使用してます。

事前にOculus QuestをかぶりOculus LinkをOnにしておきましょう。 f:id:amidaMangrove:20200411111812j:plain

本記事はこちらを参考に執筆しています。より詳細はこちらを参照していただければ。

blogs.unity3d.com

1クリック - Unity HUBを起動する

f:id:amidaMangrove:20200411105925p:plain

2クリック - 新規作成ボタン

f:id:amidaMangrove:20200411110013p:plain

3クリック - HDRPを選択

f:id:amidaMangrove:20200411110106p:plain

4クリック - 作成ボタン、Unityを起動する

f:id:amidaMangrove:20200411110201p:plain

Unityの起動を待っている間に「男たちの挽歌」を見る

f:id:amidaMangrove:20200411113051j:plain

5クリック - Widnowメニューを開く

f:id:amidaMangrove:20200409223602p:plain

6クリック - HD Render Pipeline Wizardを選択

f:id:amidaMangrove:20200409223713p:plain

7クリック - HDRP +VR

f:id:amidaMangrove:20200409223807p:plain

8クリック - Fixを選択

f:id:amidaMangrove:20200409223937p:plain

9クリック - Playボタンを選択

f:id:amidaMangrove:20200409224228p:plain

ヘッドセットを被って確認してみましょう。無事に起動できているはずです。 f:id:amidaMangrove:20200411112444j:plain

10クリック - Playボタンを選択して終了

f:id:amidaMangrove:20200411113312p:plain

普通にOculus Quest向けにビルドするよりも簡単にセットアップできましたねー。ということでまた次回!

Shader Graphの超入門レシピ その9~モノクロ、セピア、ネガポジ、モザイク、二階調化~

前回の記事

amidamangrove.hatenablog.com

今回の記事

今回は1枚のテクスチャにシンプルな画像処理を施してみたいと思います。ノード数も多くないのでさくっと試せるんじゃーないかなーと思います。 f:id:amidaMangrove:20200329213334p:plain

モノクロにする

モノクロに変換には以下の式を適用します

color = r *0.3 + g * 0.59 + b * 0.11

この計算は内積 = Dot Productで簡単に行う事ができます。 f:id:amidaMangrove:20200329113211p:plain

計算後に「Stepノード」を追加することで二階調化も簡単に行えます。 f:id:amidaMangrove:20200329205845p:plain

ネガポジ反転

ネガポジ反転は「One Minus」を使用する方法とその名の通り「Invert Color」を使用する2つの方法があります。 f:id:amidaMangrove:20200329113605p:plain

Invert Colorは色の要素単位で反転が可能です。 f:id:amidaMangrove:20200329113659p:plain

セピアにする

セピアはモノクロに変換した値に対してそれぞれ以下のスケールをかけ合わせれば実現できます。

mono = r *0.3 + g * 0.59 + b * 0.11

color.r = mono * 1.07

color.g = mono * 0.74

color.b = mono * 0.43

モノクロで出力した値をCombineノードで結合し各要素に対してセピアのスケール値を乗算すればできそうです。 f:id:amidaMangrove:20200329115121p:plain

モザイクにする

「Posterrizeノード」を使用することでモザイクを実現できます。このノードは入力された値を指定した階調で出力してくれるノードです。このノードをUVの入力値として使用します。 f:id:amidaMangrove:20200329120928p:plain

レトロ風にする

写真に縦線を入れてレトロっぽく表現してみます。モノクロのに対してノイズのX方向のみを取り出し掛け合わるだけでそれっぽい表現となります。 f:id:amidaMangrove:20200329213819p:plain

シンプルなシェーダーが連続しましたがエフェクトの隠し味として色々使えそうですね。

Shader Graphの超入門レシピ その8~ノイズで遊ぼうーディゾルブエフェクトとか頂点アニメーションとか~

前回の記事

amidamangrove.hatenablog.com

Simple Noiseノード

Simple Noiseノードは入力されたUV値とScale値に基づいてノイズを発生させます。今回はこのノードを使用してディゾルブエフェクトや頂点のアニメーションを作ってみようと思います。

f:id:amidaMangrove:20200322100400p:plain

f:id:amidaMangrove:20200322234437p:plain

f:id:amidaMangrove:20200322215429p:plain

ノイズをアルファ値に使用してみる

Alpha値とAlphaClipThreshold値にノイズを使用することで古地図のような表現ができます。作成したShader Graphがこちら。 f:id:amidaMangrove:20200322212116p:plain

Simple NoiseをAlpha値に接続しています。次にTimeノードをFractionノードに接続しています。「Factionノードは入力された値の小数点部分を返すノード」で、出力される値は0以上~1未満となります。

接続先の「Alpha Clip Threshold」「そこに入力された値よりもアルファ値が下回っていたら描画しない」というもので0~1に変化する過程でNoiseの暗い部分から徐々に描画がスキップされていきます。

f:id:amidaMangrove:20200322212832g:plain

ノイズのUV値を変更する

UV値を変更するとノイズの出力結果も変わります。デフォルトではUV0が指定されていますが、その値を「Polar Cordinateノード」に変えます。このノードは入力されたUV値を極座標に変換してくれるノードです。 f:id:amidaMangrove:20200322231921p:plain

f:id:amidaMangrove:20200322232625g:plain

ディゾルブエフェクトを加える

ディゾルブエフェクトの作り方はkeijiroさんのサンプル「例2:ノイズを使ったディゾルブエフェクト」を見て頂くとわかりやすいのでこちらを紹介します。(手抜きとか言わないで・・・

Shader Graph Examples インストラクション · GitHub

ちなみに先ほどのノードにエフェクトを加えてパラメータをいじるとこんな感じになります。 f:id:amidaMangrove:20200322233510p:plain f:id:amidaMangrove:20200322233627g:plain

同じエフェクトでもUVの値を変更するだけでも多少変化をつけられるようになりますね。

f:id:amidaMangrove:20200322234627g:plain

おまけ:頂点のアニメーションにノイズを加えてみる

頂点座標にノイズを加算することで少し変わった効果を作れます。前回の記事でも実は使用していました。 ノイズを発生させ、法線の方向に乗算した結果を座標に加算する・・・という内容です。実際のShader Graphは以下 f:id:amidaMangrove:20200322215131p:plain

作成したシェーダーをスフィアに適用すると以下のようにちょっとぐにゃぐにゃした感じに。 f:id:amidaMangrove:20200322215429p:plain

Noiseのスケールを下げUV値をアニメーションさせてみます。 f:id:amidaMangrove:20200322220136p:plain

シャボン玉っぽいような面白いアニメーションが作れました。 f:id:amidaMangrove:20200322220631g:plain

ノイズを使うことで表現の幅は結構増えそうですね!特にディゾルブエフェクトは単純かつ見た目も派手なのでとても使い勝手が良さそうです。 ということでまた次回!

Shader Graphの超入門レシピ その7~輪郭を明るくする2つの方法~

前回の記事

amidamangrove.hatenablog.com

今回の記事作成の参考とさせていただきました!

www.youtube.com

www.hanachiru-blog.com

今回作成するもの

f:id:amidaMangrove:20200314213249p:plain

図のようにSphereの輪郭を光らせバリアっぽいエフェクトを作成します。赤色と青色がありますが2つは異なる方法でシェーダーを作成しています。 非常にシンプルにノードが組める&カッコいいエフェクトを作るのにはうってつけの方法で、リムライト的な表現も作れるようになります。

シーンの中身は単純にスフィアの中に板ポリを置いてるだけです。シェーダーとポストエフェクトでここまで見た目が変わるのはやっぱり面白いですね。 f:id:amidaMangrove:20200314213631p:plain

輪郭を明るくする方法1~フレネルエフェクトノードを使用する~

フレネルエフェクトノードを使用すると僅かなノード数で先ほど見たエフェクトを作る事ができます。

f:id:amidaMangrove:20200314220652p:plain

フレネルエフェクト = フレネル反射とは入射する角度が平行であればあるほど反射率が高く、垂直なほど反射率が低くなる・・・超ざっくり言うとそのような反射を表現するものです。 f:id:amidaMangrove:20200314215218p:plain

ちょうど水面を思い浮かべるとなんとなくイメージできると思います。水面を真上から見ると底まで透き通って見えますが、目線を平行にすると底ではなく周りの背景が水にうつり込むはずです。 f:id:amidaMangrove:20200314220424j:plain (↑京都は嵐山、天龍寺の池です)

実際に作ってみる

f:id:amidaMangrove:20200314221913p:plain f:id:amidaMangrove:20200314222146p:plain

マスターノードのSurfaceを「Transparent」に変更しておきましょう。これで完成です。 f:id:amidaMangrove:20200314222308p:plain

一点の問題点・・・

非常にシンプルに作れるのですが、実はFresnel Effectは「両面描画を行った際、裏側も計算されてしまう」という細かな問題があります。実際に確認してみましょう。

マスターノードのTwo Sidesにチェックを入れることで両面描画ができます。 f:id:amidaMangrove:20200314222600p:plain

すると・・・ f:id:amidaMangrove:20200314222710p:plain

裏側も計算されてしまいました。状況によってはハマってしまうかもしれません。

輪郭を明るくする方法2~視線ベクトルと法線ベクトルの内積で計算する~

両面描画の問題を解消するにはこちらの方法を使います。モデルの法線ベクトルと視線ベクトルの内積を計算しその結果をフレネル反射として扱います。自前でライティングの計算をした方には馴染みのある方法ではないかと思います。

View Directionノードはオブジェクトまでの視線ベクトルを取得します。取得する値はそのまま距離が入ってくるので計算するために正規化をしてあげます。 f:id:amidaMangrove:20200314230934p:plain

この視線ベクトルと法線ベクトルの内積を計算します。正規化したベクトルの内積は「お互いのベクトルの近似度」を表すので向きが同じ場合1、逆向きの場合-1、垂直に近づくにつれ0となります。 f:id:amidaMangrove:20200314231803p:plain

普通に内積を使用してしまうと垂直寄りの方が0となってしまいますが欲しい値のはこの逆(垂直の方が1になってほしい)なので「OneMinusノード」で値を変換しましょう。OneMinusノードは「1 - In」を返すノードです。

というわけでガチャガチャ色々書いてますがこちらの動画の12:30~見た方が多分わかりやすいと思います。

さっそく作ってみましょう。実際のノードグラフがこちら。 f:id:amidaMangrove:20200314225550p:plain

この手法なら「Two Sides」にチェックを入れてもおかしいことにはなりません。無事完成です! f:id:amidaMangrove:20200314230347p:plain

ちょっと色々いじってみる

f:id:amidaMangrove:20200315002048p:plain

これまでの記事で紹介したUVスクロール + 頂点アニメーションと組み合わせると少し動きのある表現ができるようになります。(ノイズはまだ紹介していませんが・・・

ざっくりと説明すると法線ベクトルにノイズの値を掛け合わせ、その値を頂点の座標に加算しています。 f:id:amidaMangrove:20200315002413p:plain

機会があったらこの辺りも紹介できたらと思います。 というわけでここまで!

Shader Graphの超入門レシピ その6~頂点を波のように動かしてみる~

前回の記事

amidamangrove.hatenablog.com

頂点を動かす

シェーダーグラフでは色情報のみではなく、頂点の座標も操作することができます。今回はその機能を使用してうねうねと動くPlaneを作ってみましょう。

使用する素材はこちらからお借りました。

g-sozai.com

エドゥアール・マネの代表作「フォリー・ベルジェールのバー」です。背後の鏡に映ったバーメイドと紳士の位置関係が物議を醸しだした名画です。興味のある方は調べてみてください。

今回のサンプルの完成形はこんな感じです。 f:id:amidaMangrove:20200308010102g:plain

ベースとなるシェーダーの作成

「VertexAnimation」という名前のUnlit Graphを新規に作成します。ノードエディタを開いたらMain Preview→右クリック→Custom Mesh→Planeに変更しておきましょう。

f:id:amidaMangrove:20200307172653p:plain

次に「Positionノード」を追加します。このノードを使用することでSpaceに指定した座標空間から頂点またはフラグメントの値を取得します。今回のサンプルではSpaceにObjectを指定しておきます。

f:id:amidaMangrove:20200308001015p:plain

この頂点のX位置を使用して高さを計算します。試しに次のようなノードを組んでみましょう。 f:id:amidaMangrove:20200308002758p:plain 追加したノードは「Splitノード」「Sineノード」「Combineノード」の3つです。特に「Splitノード」と「Combineノード」はとても使い勝手が良いノードなのでこれからも頻繁に使用していくと思います。

ここでやっていることは「入力されたXの座標値を元にSine関数を使用してY座標を求める」というシンプルなものです。メインプレビューを見るとPlaneがぐにゃぐにゃしているのが確認できます。無事頂点の座標が変化しているようです。しかし、入力される値が固定なので一切動きません。ということで次は動くようにノードを追加してみましょう。

f:id:amidaMangrove:20200308004037p:plain 取得しているX値に時間を加算しそれをSineの入力値としています。こうすることで頂点が波を打つようにうねうねと動くようになります。ここまで仕上がれば、あとはノードを追加して調整していくだけです。

波の速度、波の高さ、波の幅を変えてみる

各計算過程に「Multiplyノード」を挟むことで波の速度、幅、高さを変更できます。 f:id:amidaMangrove:20200308005042p:plain

良い感じに調整ができたらテクスチャを追加 & マテリアルを作成し実際にPlaneに張り付けましょう f:id:amidaMangrove:20200308005351p:plain

f:id:amidaMangrove:20200308010102g:plain

できました!シンプルですが頂点を動かすことでまた別の表現もできそうですねー。

というわけで本日はここまで!また次回!

Shader Graphの超入門レシピ その5~Flipbookノードを使用したテクスチャアニメーション~

前回の内容

amidamangrove.hatenablog.com

テクスチャアニメーション

1枚のテクスチャの座標を切り替えてアニメーションを行います。要するにパラパラ漫画ですね。Shader Graphは「Flipbookノード」を使用する事で実現できます。

素材の準備

今回の素材は「ぴぽや倉庫」様よりお借りいたします。

pipoya.net

記事中では「エフェクト戦闘(基本)」を使用します。

シェーダーの作成

「FlipbookAinmation」という名前でUnlig Graphのシェーダーを作成し、続けてダウンロードした素材からアニメーションで使いたいテクスチャをインポートします。記事内ではカッコよさそうなこのテクスチャを使用します。

f:id:amidaMangrove:20200306003448p:plain

f:id:amidaMangrove:20200306004427p:plain

まずは今回の主役である「Flipbookノード」を追加します。

f:id:amidaMangrove:20200306004539p:plain

入力値 説明
UV 入力UV値
Width 水平タイルの量、横方向の枚数
Height 垂直タイルの量、縦方向の枚数
Tile タイルのインデックス

今回サンプルで使用する画像は、横方向に14枚連なっているのでWidthに14と入力します。一度Sample Texture 2DのUVに繋げてみましょう。

f:id:amidaMangrove:20200306005357p:plain これであとは「Tile」の値を変更すればアニメーションができそうです。ということでアニメーションを行うための「Timeノード」を繋げるのですが、速度を変更する「Multiplyノード」と小数点を切り捨てる「Floorノード」を間に挟みます。

f:id:amidaMangrove:20200306010637p:plain

最後に「Sample Texture 2Dノード」のRGBAをマスターノードのColorへ、A(1)をAlphaにそれぞれ繋ぎます。AlphaClipThresholdは0にしておきます。

f:id:amidaMangrove:20200306011206p:plain

さぁこれで完成...と思ってMain Previewを見ても背景透過されてません。マスターノードで「Opaque(不透明)」か「Transparent(透明)」かを選択できるので「Transparent」に設定しておきます。設定はマスターノードの歯車マーク→Surafaceの項目を変更するだけです。 f:id:amidaMangrove:20200306011509p:plain

ここまで出来上がったら実際にマテリアルを作成して挙動を確認してみましょう。

f:id:amidaMangrove:20200306011854g:plain

アニメーションを逆再生

FlipbookのInvertXにチェックをつけることでインデックスによるタイルの参照が「左→右」だったのが「右→左」に変わります。InvertYの場合は「上→下」が「下→上」になります。

f:id:amidaMangrove:20200306012125p:plain

アニメーションが2段にわかれたテクスチャの場合

例えば以下のように上下に分かれていた場合 f:id:amidaMangrove:20200306012756p:plain

何も考えずにFlipbookのWidthとHeightに値を入れればOKです。この場合Width = 5、Height = 2ですね。ちなみにデフォルトでInvertYにチェックがついているので外しておきます。 f:id:amidaMangrove:20200306013042p:plain

f:id:amidaMangrove:20200306013812g:plain

というわけで本日はここまで!また次回!