VRChat雑記

かやのみちゃのVRChat関連の雑記ブログです

Amplify Shader Editorに入門してみた

この記事について

これはVRChat Advent Calender 4日目の記事です。
UnityのアセットストアのセールでAmplify Shader Editorというノードベースでお手軽にシェーダーが書けるツールが安かったので購入し、積みアセットにしないためにも頑張って入門してみた!という記事です。

今後VRChatはUnity2018にアップデートされますが、そちらでは無料でシェーダーグラフというノードベースで作れるツールがありますので、今後VRChatでもシェーダーがより普及すると思います。ノードベースだと結構楽しいよ!というのが伝わると嬉しいです!

シェーダー使わないで頑張る方法と比較する

というわけで書いていこうと思いますが、シェーダーなし版とも比較しようと思います。明確なスペックなどの比較ではないですが、作業量とかできること、できないことが伝わればいいなーと思います。

今回はクリスマスも近いですし、LEDでいい感じにぴかぴかと光る床っぽいものを実装したいと思います。応用すればクリスマスツリーとかの電飾に使えるかもしれません。

自分が現状使える2つの手段をこの記事ではご紹介します。

BlenderでCube生成+Animation
メリット:
Cubeを羅列するだけなので簡単に作れます。Animationもアバターで慣れている人も多いと思います。数式を考える余裕がないときはいいかもです。
デメリット:
Blenderに苦手意識があるとつらいです。Animationの負荷がネックです。Animationする対象が多ければ多いほどFPSにとても影響しちゃいます。

シェーダーで実装
メリット:
Cubeと比べ負荷が軽く、動きをつけたりが自由にできます。
デメリット:
基礎知識がいることがネックでしょう。
Unity2017ではノードベースではないため、なおさら難しいかと思います。

だいたいざっくりとしたメリット・デメリットでした。
以下はこの2つの実際の実装を紹介したいと思います。
どちらもPostProcessingを利用していますので実際に試したい場合は下記URL等を参考に導入してみてください。
https://vrcworld.wiki.fc2.com/wiki/Post%20Processing%20Stack

BlenderでCube生成+Animationで実装

まずはBlenderを…というとつらい気持ちになる人もいるので、所要時間と操作回数を。時間は5分くらい、操作回数は20回はないと思います。たぶん。
Blenderが苦手ならUnityのCubeを一つPrefab化してコピペすれば同じことはできます。

BlenderのデフォルトCubeをキーボードのSキーを押してそこそこ小さくします。その後スパナマークからAdd Modifierを押しArray Modifierを設定します。Countは繰り返し、Relative Offsetが間隔です。ほどよい値にしてCopyを押します。コピーした方をXを0、Yを上のパラメータと同じ値を入れればOK。Applyを二回。お疲れさまでした。File -> Export -> fbxで出力します。

画像1

等間隔に並んだCubeができあがりです。これを床に埋め込んで光らせます。Unityを開いて、先程作ったFBXをどこかのフォルダにドラックドロップ。
次に右クリック->Materialで光るMaterialを新規作成します。

画像2

今回はStandard、Smoothなしにします。Emissionの数字に1以上をいれるとPost Processingでいい感じに光ってくれるようになります。

画像3

Unity上で色を調整して、2つ並べるとこんな感じになります。軽量化にはStaticをつける、CastShadows,ReceiveShadowsのOffをするといいと思います。LightProbesもReflectionProbeもOFFでいいはず…?
正直これだけでもいい感じ。

さて、次はアニメーションを加えます。光が強くなったり弱くなったりするといいですよね。適当なフォルダで右クリック->Animationを作り、HierarchyのCubeにドラッグドロップして適用します。AnimationにはLooptimeにチェックを入れておいてください。
ぼやーん->ぴかーを無限に繰り返します。

画像4

レコーディングボタンを押したあと、マテリアルのEmissionの数字をいじってあげると記録されます。色を変えてもOK。なのでグラデーションしたり、光を明滅させたりすることができます。適度に記録したらPlayしてみて出来栄えをチェックします。最初の値をコピーして最後のフレームにペーストすると始まりと終わりがきれいにつながると思います。

できあがりはこんな感じです。そんなに重くないです。少し数を増やしたいならBlenderで調整すればOK。最初からArrayModifierを適用するポリゴンの形を変えることでもっとおしゃれになります。

ちなみにUnityのデフォルトのCubeでも実装はできます。しかもそこまで悲惨なことには頑張ればなりません。

これはなぜかというとUnityのBatchingという機能で処理を取りまとめてもらえるからだと思います。(詳しくはない)Staticで、ポリゴンも少なく、LightProbeなどの影響もなく、Materialが同一なものに関してよしなに軽く描画してくれる機能…のはず。上の例ではCubeの数が尋常ではないことになってますが、実際のBatchesはそこそこ低いです。Saved by batchingは大変なことになっていますが。

面倒なときはUnityでがーっと作って様子を見て、Blenderモデリングするのもありかと思います。最終段階で色を調整したりするため、まずは最後まで仮の形で通すのが良いかと。MVPな開発といえばナウいはずです。形になってきたら本格的にモデリングで最適化というのもよいのでは。
ここらへんはそれぞれ作り方に個性が出そうですね。もっとみなさんの作り方を知りたい…。

この作り方だと一気に光って弱くなるというのは実装できますが、中心からふわっと広がる感じは難しいですね。個別に光らせたり色を変えるのもAnimationの数が増えて重くなりがちです。ここらが限界だと思います。

シェーダーによる実装

さて次はシェーダでの実装です。AmplifyShaderEditorをさっそく使います。

自分が今回参考にさせていただいたのが以下のブログ記事です。ありがとうございました。
http://r-ngtm.hatenablog.com/entry/2018/12/08/005401
http://nn-hokuson.hatenablog.com/entry/2018/05/24/195206
これらはシェーダーグラフの実装ですが、頑張ればAmplified Shader Editorでも実装できました。Unity2018では無料で苦労せずにできると思うのでわくわくしてVRChatのアップデートを待ちましょう!

出来上がりがこちら。こういうの結構ほしいですよね。
意外と作る難易度は低めです。だいたい初心者でも二時間くらいでできると思います。ノードベースで見るとこんな感じです。

まず上部分について。上記記事を参考にしつつ、なんとなく星型に光るようにしたかったので真似して作っています。

画像5

あまり自分も意味はわかっておらず、なんとなくつなぐとこうなる!としかやってません。やってみてすごい!となってから意味を理解し始めたほうが長続きすると思います。ノードベースで適当にサンプルを組み合わせるだけでも楽しい…。

画像6

下側は円です。Multiplyの数字、Clampの数字も非常に適当です。とりあえず望み通りになればいい…!として設定した覚えがあります。わかってないですが、ただノードベースでこうして動いているのを見ながら作ると適当でもいい感じにできてとてもよいです。
あとは最後にHDRにチェックをいれてMultiplyすればOKです。

画像7

Materialを生成し、出来上がったShaderを指定してPlaneやQuad、Cubeに適用すれば完成です。Planeなどを大きくした場合はShaderで変数にしている値を上げるだけで密度を調整できるので便利です。星の大きさも変数で調整できるのでVRで実際に見て大きい、小さいなどを把握したあと調整していくといい感じです。

という感じでサンプルがあったので拾ってやってみたのですが、別にUVから作らなくてもよいのでは?とよぎりました。(投稿一日前)

画像8

基本となる図形をテクスチャで入れてしまい、光り方もテクスチャで定義すればいいのでは?と。
https://cc0textures.com/view?tex=Tiles58
CC0なテクスチャがおいてあるサイトでいい感じのものを選んでみました。
シェーダーとしては単純でテクスチャに色つけたものともう一つのテクスチャを時間で引いたものを最後かけ合わせただけ。

たぶん円で光るように組み合わせたりもできそうです。こっちのほうが一般的なシェーダーの作り方かもしれません…。

最初は数式をそのまま写経してみて、その後で適宜テクスチャに入れ替えたりして目的のものを実装できるようになると手早くていいかもしれません。もしくはその逆でもいいかもしれない。やり方は様々ですね。

おわりに

ということで2つのタイプで光る床を実装してみました。どちらの手法でもメリット、デメリットはあると思います。
例えばシェーダーで書くよりもポリゴンでモデリングをさくっとやってしまってAnimationで動かしたほうが早いときもあるとは思います。
逆にシェーダーにも基本的なパーツがあり、それらを組み合わせたほうが早い場合もあると思います。

もしくは複雑な部分をモデリングして、動きの部分はAnimation+シェーダーで頑張る、そうなるとより面白くなるんじゃないかなと。なにを目的とするかによって取る手段は柔軟に変えていっていいと思います。

使えるものを使って、最初は気楽に入門して、たくさん組み合わせて自由な表現を楽しみましょう!