CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

【2019/11/16更新】【Unityアセットアドカレ】Shader Forgeでナイトプールを作ろう!


2019/11/16 追記

製作者のFreyaさんがGithubでUnity2019に対応したバージョンを発表しました。Githubから確認できます。

続くtweetによると、Shader Forgeを売る予定がないのは変わっておらず、自分の個人的なプロジェクトに使っているのでアップデートしたそうです。


2018/6/14 追記

下記とのことですので、試される場合はGithub のリンクから取得お願いします。

GitHub - FreyaHolmer/ShaderForge: A Shader Editor for Unity


この記事は「Unity アセット真夏のアドベントカレンダー 2017」の最終日の記事です。昨日はjojomonさんによる、「【Unity】Embedded BrowserとVrGrabberを使ってVR空間で簡単ブラウザ操作 - VR Mastodon」でした。

最終日は、Shaderをノードベースで作成できる「Shader Forge」を紹介いたします。ただし、Shader Forgeについては、インターネット上に多数の情報があります。そこで、今回はそれらを参考にさせていただきながら、自分で理解したことと、実際に作ってみたものの作り方をまとめました。

なお、今回の検証はこのような環境で実施しています。

Mac OS X 10.12.6
Unity 5.6.3p1
Shader Forge v1.37

随所にShaderのコードのgithubリンクを貼ってあるので、気になる方はダウンロードして任意のマテリアルにアタッチしてみてください。
(Shader Forgeがなくても使えます)



1. Shaderとは?

こちらのP.6が参考になります。

Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編

もう少し原理的な説明は下記がわかりやすかったです。

説明しよう!シェーダーとはッ! - o_healerのブログ

個人的には、表面の質感、頂点の位置を、静的および時間的に変化させることができる仕組み、がshaderという理解に至りました。

あくまでオブジェクトの質感を変えるのがメインなので、レーザーとか炎とか、全体の形が大きく変わったり、複数のオブジェクトが発生するようなものはParticle Systemで作る、と考えると区別できる気がします。(条件を限定して作り込めばShaderでもできるかもしれませんが)

一方、風でなびく旗とか、クリスタル・氷の彫像とか、水面とか、オブジェクト単体の表面上の変化に類するものはShaderが得意と考えるのがよさそうです。

2. Shader Forgeとは?

2-1. 概要

ノードをつなげてShaderを開発できるアセットです。このような画面でShaderを作ります。

shader forgeの画面例

通常、UnityでShaderを書こうとすると、ShaderLabという言語を使ってテキスト形式で記述する必要があります。Shader Forgeを使うと、個別の機能をノードで表現してつなぐことで、Shaderを作ることができます。

ところで、「ノードベースで〜する」、というのは、Shader Forgeに限らず色々なソフトウェアのツールでよく聞きます。「ノード」が何を指しているかがいまいち曖昧だったので調べました。

http://wa3.i-3-i.info/word1300.html

これによると、「ノード」とは個別の機能部分を指し、ノードとノードを接続する線を「エッジ」と呼びます。説明する図を作って見ました。

ノードとエッジの例

他にもいくつか調べましたが、「ノード」と「エッジ」の指す内容は同じでした。

2-2. 基本的な使い方

基本的な使い方はこちらにわかりやすくまとめられているので、参照ください。

【Unity】ノードベースのシェーダエディタ「Shader Forge」紹介 - コガネブログ

また、アセット紹介で有名なこちらのブログでも、概要がわかりやすくまとめられております。

【独自セール】ノードベースでカスタムシェーダーが作れる大人気アセット『Shader Forge』が驚愕の55%OFFでセール中 - Unity AssetStoreまとめ

3. 出現頻度が高かったノードの概要

Shader Forgeの使い方を理解するために、チュートリアルや公開されている例を色々と調べました。その過程でよく出たノードについて、機能紹介や使い方の例を整理しました。個別のノードを完全には理解できていないので、原理を説明しきれていない場合もあるのでご了承ください。

Multiply
2個以上のノードをつなぎます。つなげるものは幅広くてTexture2Dや、Value、Colorなどです。

・Texture同士を繋げる場合
Texture同士を繋げる場合

ここでは、レンガのテクスチャと、緑と白のテクスチャを合成しています。Photoshopのレイヤーの概念に似ています。

・TextureとColorを繋げる場合
TextureとColorを繋げる場合

色を重ねることもできます。他にも、複数の性質を統合するという意味で、Multiplyを使う機会は非常に多かったです。

Lerp
2個のノードをつなぎます。三つ目にTau(T)という項目があります。Tauは動的な変化を指定できます。ここに時間的な処理をつけると、shaderを時間的に変化させることができます。

周期的に変化させた場合です。

周期変化させた例

lerpを使う例の解説

それぞれの処理については、赤い枠で補足説明を入れておきました。また、shaderコードは下記のgithubにおいてあります。

lerpの例のshaderコード(lerptest.shader)

テクスチャは何か適当なものを準備ください。なお、Tauにslider(Valueでもよい)ノードをつなぐと、合成の割合を手動で調整することができます。
Tauをsliderで調整する例

Remap(Simple)

変化の範囲を指定するノードです。先ほどのlerpの説明でも使っています。fromとtoにそれぞれ値を入れることで変化の範囲を指定できます。

Texture2D

テクスチャを指定できます。色々なShaderの作り方を調べていくと、テクスチャでベースを作ってから、色調整、時間的な変化を加えてShaderを作り上げるので、テクスチャの選定は重要です。

Value

値を指定できます。Lerpで説明したような色指定だけでなく、MainノードのOpacityに直接つなぐことで透明度を指定できます。

Opacityのvalueを変化させて透明度を変更

また、Outline Widthにつなぐことでオブジェクト表面に色をつけたり、という指定に使えます。

Outline Widthを変更する例

値を指定するノードなので、2個以上の別のノードに接続することも可能です。

Valueで2つ以上の別ノードに接続する例

Slider

Lerpの箇所で紹介したように、スライダーとして値を調整できます。役割はValueと同じですが、最小値と最大値を決めて、その範囲での変化をすぐに確認できるメリットがあります。

Time

時間的な変化を加えます。単体では使えず、Lerpの例のように、変化の周期(sinノードなど)、振幅(Remap(Simple)など)、変化の方針(LerpのTauなど)と組み合わせることで使うことができます。

Panner

テクスチャのUV情報と接続することで、表面の情報を動かすことができます。こちらに例がわかりやすくまとめられております。

【Shader Forge】Panner(UVをいじる)について - Qiita

ところで、UVとは何か?ですが、テクスチャをモデルに貼り付けるための情報のことです。wikipediaの記述がわかりやすかったです。

テクスチャマッピング - Wikipedia

Component Mask (Comp Mask)

接続されたものからR,G,Bの色を分離します。公式HPのにわかりやすい図が掲載されています。

Component Maskの説明

ノードは他にも多数ありますが、今回は割愛します。



4. ナイトプールを作ってみる

Shader Forgeで何を表現するかを考えていたのですが、今年はナイトプールのはやりに乗っかって、それっぽいものを表現してみました。

最終的にこのようなものを作りました。

以下、Shader Forgeで作る過程を解説します。

4-1. ステージを作る

まずはCubeとQuadを配置します。
CubeとQuadのみ配置

大きな平面がQuadです。次に、周りを描画するためにレンガのテクスチャでShaderを作りました。最初のお試しで作ったShaderですが、このようなShaderを使って描画しています。

使用したレンガを表現するShader

壁shaderの例 on github (LitTest.shader)

レンガのテクスチャは適当なものを準備ください。この時点でこうなります。

レンガのshaderを当てた状態のナイトプール

4-2. 水面を作る

大雑把に言うと、Texture2Dで波形を作り、PannerノードでUVを時間的に変更し、Opacityの調整で透明にすることで実現しています。色々探してみましたが、水面の作り方がわかりやすく紹介されていたので、最終的にこの動画の方針で作りました。

YouTube

(注1)MainノードのOpacityがalphaになっていますが、Opacityとしてノードを接続すれば問題ありません。

(注2)Comp Maskに接続していますが、色を分離しなくても水面としてきれいに見えるので、私は除外しました。

SimpleWater.shaderのshader forgeでの図

Waterのshaderコード on github (Water.shader)

水面のテクスチャは適当なものを準備ください。このShaderからマテリアルを作って、先ほどのQuadにアタッチするとこうなります。

watershaderを当てた状態のナイトプール

4-3. skyboxを作る

まず、星空のテクスチャを準備します。こちらに使用OKのテクスチャがあったので、使わせていただきました。

夜 スター 満天の星空 - Pixabayの無料画像

次に、Shader Forgeを開きます。

UnityでShader Forgeを開く

New Shaderを選んで、Skyを選択します。

Shader ForgeでSkyを選択

任意の名前をつけると、Shader Forgeのメイン画面が出てきます。すでにskybox向け設定ができているので、Texture2Dを先ほどの星空にして、その他sliderなどを調整したのがこちらです。

ナイトプール向け設定

文字が小さいので、ロジックの詳細はソースコードを直接Shader Forgeに読ませてご確認ください。

skyboxのshaderコード on github (skybox_night.shader)

ここからマテリアルを作り、色や値を少し調整しました。

skybox_night.shaderをマテリアルに入れて調整したもの

このマテリアルをskyboxとして設定するとこうなります。

skyboxを設定した状態のナイトプール

4-4. 光の玉を作る

ナイトプールは光ってるイメージがあるので、光を表現します。色々探したところ、下記の画像検索で見つけたものがきれいだったので、これをベースにしました。

https://forum.unity.com/threads/shader-forge-a-visual-node-based-shader-editor.222049/page-35

色やFresnelの値を若干変更したのがこちらです。

色とfresnelを変更したshader

Sphereに使ったShaderコード on github (Sphere_light.shader)

fresnelを変化させることでこのようになります。

fresnelを変化させた例

最終的には少し赤色を混ぜました。

赤色を混ぜた光の玉のshaderの例

この状態で、このようになります。

光の玉を混ぜた状態のナイトプール

プール中の左側面のそばに赤い玉を配置したのですが、うまく見えていません。また、今回の検討では強い自己発光をさせるShaderの作り方がみつけられませんでした。

そのため、今回は内部にPoint Lightを配置して光を強調することにしました。Point Lightの設置でこうなります。Point LightはIntensityとRangeをそれぞれ10以上にしました。これで赤い玉も目立つようになりました。

point lightで光を強調した状態のナイトプール

4-5. ポストエフェクトをかける

最後にポストエフェクトをかけてみました。方法は下記の記事を参照ください。

magicbullet.hatenablog.jp

具体的には、Post Processing Stackアセットを追加し、記事の「2. Unityプロジェクトの下準備」を実行します。次に、記事の「5. Post Processing Stackの調整」のようにして調整します。最終的にできたものが、4章の最初で紹介したYou Tubeでの動画です。

なお、今回のポストエフェクトは好みだと思うので、4-4で終えるのもありです。



5. 使い方に関するTips

5-1. ベースとなるShaderがあれば、duplicateして使うと効率的

Shader Forgeでは、作るshaderの種類によって使えるノードが変わってきます。細かい設定をコピーするのは大変ですので、ベースとなるshader をduplicate(複製)して使うのが良いと思います。複製するには、複製したいshaderをProject Viewで選択してから、Edit / Duplicateを選びます。
UnityのDuplicate選択画面

(補足)
Edit / DuplicateはShaderに限らずUnity上の任意のファイルで可能です。ただし、対象オブジェクトを右クリックしても出てこないので、注意が必要です。

5-2. Shaderの記述ルールに合わないことはできない

Shader Forgeでは、最後にMainノードにつなぐために、各ノードをつなげていきます。ノード間は文法上正しいものしか接続できないようになっています。例えば、下記の例では、ValueノードはEmissionには接続できますが、Normalはグレーアウトして接続できません。

Shader Forgeでルール違反の箇所にノードを接続できない例

Mainノードだけでなく、個別のノード同士も合わないものは、グレーアウトして接続できないようになっています。

5-3. Shaderの記述ルールに合っていないと、自動補正してくれる場合がある

shader forgeを使っていると、このようにwarningが出ることがあります。

Shader Forgeのwarningウインドウ

このときは左側のアイコンをクリックすると自動補正してくれます。

5-4. サンプル通りにノードを繋いだのに、見た目が一致しない

sliderやvalueが影響している可能性があります。Shader Forgeのメイン画面でこれらを出すと、この画面上で数値を変更できます。

Shader Forgeのスライダで数値変更する例

一方、Shader Forgeのメイン画面でsliderやvalueを出すと、Unity画面のマテリアルに同じ意味の値が表示されます。

Unityのマテリアルで値を変更する例

たとえば、赤枠で囲った"refraction"は、Shader Forge画面のSliderと同じです。これらの値はどちらからも変更できますが、同期されません。サンプルと見た目が違う時は、これらの値を揃えてから調整すると合います。

5-5. Shader Forgeの画面に何も表示されなくなる

Shader Forgeを使っていると、このように灰色の画面になって何も表示されないことがあります。

Shader Forgeの画面が灰色担って何も表示されていない例

これは、Shader Forgeで調整中に、Unityのマテリアル側でShaderの調整をしたとき発生します。もう一度Shader Forgeで開けば解決します。

5-6. 個別のノードの役割を知りたい

このように、知りたいノードで右クリックすると、"What does AAAA do?"というメッセージが出ます。これをクリックすると、Shader Forgeの公式HPでの紹介ページが開きます。

ノードを右クリックする例

5-7. コメントを入れる

個別のノードで右クリックすると、"Edit Comment"というメッセージが出ます。これをクリックすると、ノードに対してコメントを挿入できます。

Shader Forgeでノードにコメントを入れる例
ただし、日本語は入れられません。

5-8. shader forgeで作られていないshaderをshader forgeで開くと、既存の内容が消えてしまう

shader forgeで作られていないshaderファイルは、Inspector上でWarningが表示されます。(①)これを開こうとすると、このようなメッセージが表示されます。 (②)

Shader Forgeのファイルが消える操作の例

この状態で開くと、元のshaderファイルの情報が消えるのでご注意ください。

5-9. 操作のTips (Macでの操作方法です)

5-9-1. 複数選択

altキーを押しっぱなしにしてマウスドラッグします。altを押さないと画面内をカーソル移動できます。

Shader Forgeでノードを複数選択する例

5-9-2. ノードを削除する

ノードを選択してcmd+x(エックス)キーを同時押しします。

ノードを削除する操作の例
(gifアニメです。自動再生されない場合はダウンロードしてご確認ください)

5-9-3. エッジ(ノードとノードのつながり)を削除する

altキーを押しっぱなしにして、対処となるノードのつながり部分を右クリックします。

Shader Forgeのエッジを削除する操作例

5-9-4. 表示の拡大・縮小

Trackpadで上下にスクロールします。

Shader Forgeの表示を拡大、縮小させる例

6. 参考になった記事

今回は色々な記事を参考にさせていただきました。せっかくなので、それぞれの記事を簡単に紹介したいと思います。
(一部、本文中の紹介した記事と重複します)

6-1. Shader Forgeの概要を紹介

Unity道場11 Shader Forge 101 ~ShaderForgeをつかって学ぶシェーダー入門~ 基本操作とよく使われるノード編

Shaderは何か?Shader Forgeで何ができるかについて、最もわかりやすい資料と思います。

6-2. Shader Forgeの概要や、使い方をスクショ付きで紹介

ノードベースのエディタで Shader をリアルタイムに編集して色々な質感を簡単に作れる Shdaer Forge を使ってみた - 凹みTips

さすがの凹tipsです。あちこちで引用されていました。

【Unity】ノードベースのシェーダエディタ「Shader Forge」紹介 - コガネブログ

2016年の情報です。Shader Forgeの画面ボタンなどの説明が一通り書かれています。

【Shader Forge】Timer + Lerp 使ってみた - Qiita

時間的に変化するShaderの書き方が紹介されています。

他の記事よりも一部に特化した内容ですが、私の場合この記事を読んだことでShader Forgeの使い方を理解できたので、参考までに掲載させていただきました。

【独自セール】ノードベースでカスタムシェーダーが作れる大人気アセット『Shader Forge』が驚愕の55%OFFでセール中 - Unity AssetStoreまとめ

アセット紹介で有名なこちらのブログでも、概要がわかりやすくまとめられております。

6-3. Shader Forgeの解説(海外サイト)

Shader Forgeのチュートリアル(公式HP)

You Tubeに上がっているチュートリアルの一覧です。全部で6つあります。まずは1つめか2つめくらいまでやってみると、Shader Forgeがどんなものかがイメージがつきます。

その上で6-1で紹介した小林さんの資料を読むと、理解が深まります。

50 Shaders of Forge – Prototyping with Shader Forge | Nordeus

水、風に揺れる葉、岩などの作り方を解説しています。

6-4. Shaderでどんなことができるかをわかりやすく紹介

シェーダー – Tsumiki Tech Times|積木製作

Shader Forgeは使ってませんが、UnityのShaderでどんな風に書けばどんな表現になるのかが、非常に丁寧に解説されています。

シェーダ カテゴリーの記事一覧 - おもちゃラボ

こちらもShader Forgeは使っていませんが、様々なShaderの表現を丁寧に解説されています。Shaderでどんなことができるのか、というイメージをつかむだけでもオススメです。

また、Unity全般について、困ったときの対処方法が多数書かれているので、その点でもオススメです。

7. 終わりに

Shaderの言語は少し特殊なので、初めてだと取っ付きづらい気がしていました。しかし、Shader Forgeによってどんな機能があって、どうやって処理をつくればよいかということが見えてきたので、Shaderに対する理解が深まりました。

Shaderを作るアセットは他にもあります。まだ他を試せていないのでどれがよいかをコメントはできませんが、Shader ForgeはShader開発を効率化するにはとてもよいアセットだと思います。まずは試してみることをオススメします。