月 の 上

UnityのVFXGraphでパーティクル芸やる方法

最近仕事の合間にVFXGraph (Visual Effect Graph)を触ってます。

Uniteの発表動画みた時は「おいおいHoudiniかよ?」と思ったけど、今の所は「ノードベースのGPUパーティクルシステム」という感じ。
ベータなのでノードの数も使い勝手もまだまだだけど、それでもサクサクっとおもしろパーティクルアニメーションを作れるので楽しいですね。

この記事では、VFX Graphの基本的な操作方法や、これまでに作ったエフェクトの作成方法を解説します。
まだベータなのでこれから変わるかも。

使い方

VFX GraphはUnity 2018.3からの新機能です。
インストール方法はのたぐすさんのスライド見てください。

notargs.hateblo.jp

Projectタブで Visual Effect を作成してダブルクリックすると、ノードエディタ的なやつが開きます。

f:id:amagitakayosi:20181115193535p:plain

System はパーティクルシステム全体、 Node はグラフを構成する要素ですね。
システム内のNodeには Block を追加して、パーティクルの挙動をコントロールできます。

(以下では ノード とか ブロック とも表記します)

ノード画面の基本操作

  • ノードorBlockクリック: 選択
  • 何もない所でドラッグ: 矩形選択
  • 何もない所で、中ドラッグ or Alt + ドラッグ: グラフを移動
  • 何もないとこで右クリック: ノードの追加
  • ノードを右クリック: ブロックの追加、ノードの削除

キーボードショートカット

  • A: 全ノードが画面内に収まるようにズームアウト
  • O: 原点に戻る
  • F: 選択中のノードorブロックにズーム
  • [ / ]: 選択中のブロックの前or後のアクティブなブロックを選択
  • ノードを選択して Space: ブロックを追加
  • Ctrl+D: 選択中のノードorブロックを削除

Tips

体系化むずいので箇条書きで……

新たにエフェクトを作るには?

Create Node > System で何か選ぶ。
Simple Swarm Particle System を選ぶとカッコいいツブツブが出ます。

パーティクルに力を与えたい

Updateノードに Force 内のブロックを追加すると色々できます。

僕のお気に入りは Conform to Sphere 。 パーティクルを引き寄せる球体を作ることができます。

より進んだ使い方は後述。

パーティクルにゆらぎを持たせたい

Updateノードに Turbulance ブロックを追加しましょう。
Vector Field Force でも良いけどVector Fieldを自分で作る方法がわからん……。

Inspectorから値を操作したい

Blackboard からできます。

また、 VFX *** Binder みたいなスクリプトを使って、Sphere ColliderをVFXにバインドすることもできる。

時間で変化する値を作りたい

Total TimePeriodic Total Time ノードを使うと良いです。
Sine Wave ノードや Remap ノードを使って、値の動きを調整するといい感じになります。

ケーススタディ

一応プロジェクトはここで公開してます(コミットログは破茶滅茶だが……)

GitHub - fand/vfx-graph-study

作例1: リングっぽいの

Initializeノードに Position (Circle)ブロックを追加して、Updateに Conform to Sphere を追加。
Conform to Sphere のForceなんかをSine Waveで変化させてるだけです。

作例2: 球体からパーティクル出てるやつ

球体を画面中央に向けて Rigidbody.AddForce しつつ、 VFX Sphere Binder で初期位置に設定してるだけです。
bindしたSphereは、Blackboardで追加したパラメーター同様にノードとして取得できるので、Initializeノードの Position (Sphere) に繋いでやると良い。

作例3: 3Dモデルからパーティクル出すやつ

Point Cacheって奴で出来ます。

メニューから Window > Visual Effects > Utilities > Point Cache Bake Tool を開き、メッシュを追加して Save to pCache file... ボタンを押すと、メッシュに対応するポイントキャッシュが作成されます。 あとはPositionみたいなやつにポイントキャッシュファイルを食わせてあげると、パーティクルがメッシュからスポーンするようになる。

f:id:amagitakayosi:20181115230042p:plain f:id:amagitakayosi:20181115232723p:plain f:id:amagitakayosi:20181115232737p:plain

パーティクルを3Dモデルに集まらせるやつは Conform to SDF でやるんだろうけど、今のところ自分でSDFを作る方法はなさそう……? Forumでみんな「SDF作りたいよ〜」って言ってるのは観測した。

https://forum.unity.com/threads/feedback-wanted-visual-effect-graph.572110/

作例4: パーティクルが球から球へと飛び移っていくやつ

Spawnノードに Single Burst ブロックを入れて、InitializeノードでLifetime系のブロックを削除すると、一度生成したパーティクルをずっと飛ばし続けることが出来ます。 あとは Position (Sphere)Conform to Sphere に同じSphereを渡して、 Attraction Force をSine Waveで変化させてるだけ。

Attraction Force をマイナスにすることで一瞬ふわっと広がらせるのがミソです。

作例5: 渦

現在のVFX Graphでは、パーティクルに「ある軸にそって回転する力をかける」ことは出来ないのだけど、これを頑張って擬似的に再現した。 円を小さな弧に分割して、それぞれに Conform to Sphere をかけることで、全体に回転する力がかかっているように見せている。

f:id:amagitakayosi:20181116105651p:plain

同じ要領で、回転する炎?みたいなエフェクトも作れる。


Meshをスポーンさせるやつはまだあんまり触ってないです。 ParticleごとのIDも取得できるみたいなのでコンピュートシェーダー的な表現もできそう?

これからの機能追加に期待ですね。

みんなVFX Graphで遊ぼうぜ〜〜

UnityでVJシステム作ってパフォーマンスした

f:id:amagitakayosi:20180831004034g:plain

こんにちはアマギです。もうすぐUnity歴3ヶ月です。
8/27、表参道のADIRECTORチャネルにてVJ出演しました。

ADIRECTORはavexによるテクノロジーとアートのイベントです。 4階建てのビルをまるごと使って、FEMMによるパフォーマンスや、観客参加型のプロジェクションマッピングなどを楽しめました。

https://adirector.jp/

会場には6画面の透過スクリーンを使ったライブ会場があり、Radical Hardcore CliqueがDJパフォーマンスを行っていました。 最終日のVJとして、僕、Scott Allenさん、rystyleeさんの3人で挑みました。

Radical Hardcore Clique、バキバキの音でかっこよかった…… 他のVJもめちゃくちゃ高品質で最高だった、勉強になります!!

こっちは妙な動きでVJする僕です:

雷雨の中たくさんの方々に来ていただき、大いに盛り上がりました。 ご来場いただいた皆さま、ありがとうございました!!めちゃくちゃ楽しかったです。

同業のみなさまとも交流できて嬉しかったです。 お誘い頂いたBRDGの方々、会場の方々、ありがとうございました……!


さて、今回のVJでは、Unityでシステムを作ってパフォーマンスを行ないました。
この記事では、このVJシステムについての紹介と反省を書きます。

Unityを選んだ理由

今回のイベントでは、DJを前後3枚ずつの透過スクリーンで囲んで投影した。 そのため、フルHDを2画面出力できるツールを選ぶ必要があった。

僕は普段のVJでは、自作のVJソフトVEDAか、TouchDesignerを使っていた。

VEDAはGLSLのライブコーディングができるツールだ。 VEDAは2画面出力に対応していない。たぶん実装するのは簡単なんだけど、商業イベントでいきなり使うのはちょっと怖い。 あと、DJのサンプル音源を聞いてみて、今回はライブコーディングではないキャッチーな映像を出してみたいと思った。

TouchDesignerの場合、無料版では1280x1280までしか出力できない。 フルHDを2画面出力するためにはProライセンスへの課金が必要となる。

他のツールとしては、Unityが選択肢に挙がる。 最近はVJやジェネラティブアート界隈でUnityを使った作品をよく見るし、今回のイベントでもトップバッターのKeijiroさんが使っていた。 僕は6月に転職してからUnityを触っており、UnityでVJシステムを作るのも良い経験になりそうだ。

というわけで、TouchDesignerにお金を払うか、UnityでVJシステムを自作するかの2択となった。 せっかくなので新しい事に挑戦したいと思い、後者を選んだ。

作ったもの

github.com

Main.unity がメインのシーンです。 実行にはREADME.mdに書いたアセットをimportする必要があります。

めっちゃ急いで実装した結果コードはハチャメチャなのであんまり見ないで……! マルチシーン部分とか、エフェクト操作部分は参考にしていただければ。

構成

f:id:amagitakayosi:20180828212154p:plain

めちゃくちゃ詰め込んだシステムになった。 特徴はこんな感じ。

  • 2画面出力 + 操作用の画面の3ディスプレイ構成
  • Unityシーンの加算ロードによる映像ソース切り替え
  • 外部からのビデオ入力を利用
  • キーボードとMIDIコンによる操作
  • 前後スクリーン同時にエフェクトかけられる
  • レイマーチングもあるよ!

3ディスプレイ構成

前述の通り、今回は2画面出力する必要があった。 加えて、映像ソースの切り替えや、実際にスクリーンを並べたときの状態をプレビューするため、操作用の画面を作成して、PCのディスプレイに表示した。

Unityではカメラを複数用意することでマルチディスプレイ用のアプリを作成できる。 映像ソース切り替えにも専用のカメラを配置したため、メインのシーンだけで7個のカメラを使うことになった。

今回はリハの時間がとれなかったので、京都で何度も動作確認を行っていた。
動作確認の様子:

www.instagram.com

ゲーミングPCじゃないと動かないと思う😇

Unityシーンの加算ロード

f:id:amagitakayosi:20180830180543p:plain

映像ソースは、Unityでシーンを作り、メインのシーンから呼び出すようにした。 Unityでは基本的に1つの世界を1つのシーンで表現するんだけど、SceneManager.LoadScene(scene, LoadSceneMode.Additive) で、現在のシーンに他のシーンを重ねて実行できる。 各シーンのルートにSubSceneControllerを置き、単独で実行された場合は通常どおりに実行、他のシーンから呼び出された場合はRenderTextureに描画結果を書き出した。

外部からのビデオ入力

せっかくなのでVEDAも使いたいよね!という事で、キャプチャデバイスからビデオ入力を受け取って、映像ソースの一つとして利用できるようにした。

Unityで映像入力を使うには、WebCamTextureを利用すると良い。 実装にあたって以下の記事を参考にした。

nn-hokuson.hatenablog.com

映像入力には去年録画用に買ったキャプチャデバイスを使ったんだけど、結構ノイズが目立ってた。 もしかしたらNDIとかのほうが画質キレイかもしれない。

キーボードとMIDIコンによる操作

KORG USB MIDIコントローラー NANO KONTROL2 ナノコントロール2 ブラック

KORG USB MIDIコントローラー NANO KONTROL2 ナノコントロール2 ブラック

いつものnanoKontrol2を使用。 キーボードでシーン切り替えとエフェクトのON/OFF、nanoKontrolでレベルとエフェクトを操作している。

  • キーボードの数字キー: シーンのON/OFF
  • キーボードの文字キー: エフェクトのON/OFF
    • 左右Shiftでフロント/リア切り替え
    • Spaceと同時押しでトグル
  • nanoKontrolのフェーダー: 各シーンの明るさ & マスター明るさ
  • nanoKontrolのつまみ: エフェクトの強さ

ちょっと複雑……。

本当はLaunchpad miniでシーンを切り替えたかったんだけど、工数が足りなかったのと、機器が増えるとトラブルの可能性も増えるので、今回は諦めた。 Unityで使いやすいようにLaunchpad Mini用の設定書いて、今後使えるようにしたいな〜……。

レイマーチング

VJといえばレイマーチング! ということで今回もレイマーチングを使ったシーンを作ったよ。

www.instagram.com

hecomiさんのuRaymarchingを使うと、Unity上で簡単にレイマーチングできる。 3Dオブジェクトのマテリアルにdistance functionを書くだけ。簡単!

tips.hecomi.com

distance functionは自分のShadertoyから持ってきた。 封神演義盤古幡をイメージしたやつ。

https://www.shadertoy.com/view/Msffzf

反省点

フレームレートが低い

8月頭に仮実装したときは「単純にシーン全部ロードしてもヌルヌル動くじゃん〜〜🤗」って思ったんだけど、シーンを作りこんでから結合したら当然重くなった!!! 😇 特にレイマーチングのシーンは単体だとヌルヌル動くんだけど、マルチシーンで使った途端めちゃくちゃ重くなってしまう。

GPUヘビーなシーンの場合、UnityのStatsでは正しいfpsが出ない……? ので、 Time.deltaTime を使ってFPS計測用のスクリプトを書く必要がある。 僕はこれコピペして使った。

An accurate FPS counter for Unity. Works in builds. · GitHub

主なボトルネックはPostProcessingStackとレイマーチングだった。 本番前の土日に、レイマーチングのループ減らしたり、PostProcessingのパラメータを色々調整して、ほぼ30FPS出るようになった。

他のVJ2人がヌルヌルサクサクだったので、本番後に「次はもっとヌルヌル動くようにしてえな〜」という気持ちになった……!

操作がわかりにくい

本番中、どのシーンがONになってるか、どのエフェクトがどのくらいの強さになってるかがわからなくなることがあった。 操作画面にどのエフェクトがONになってるか表示したいけど時間が足りなかったんだよな。

難しくはないので、次回までには実装しておきたい!

ブルームかけすぎた

ブルームかけすぎて画面全体がめちゃくちゃ明るくなる場面があった。 今回の会場では黒バックでもキレイに移るので、もうちょっとシンプルなシーンを用意しても良かったかな。 あとPostProcessingのブルームOFFにすれば負荷も減るし。

コードが汚い

😇😇😇😇😇😇😇😇😇😇😇😇


というわけでUnityでの初VJでした。 Unityは手軽にキレイな画面を作れるし、アセットも使えるので、モーショングラフィックスにも向いてるナ〜という感想です。 今回のシステムを作り込めば、複数人で別々のシーンを開発して統合、とかもできるしね。

楽しかった!!!!

【宣伝】9/15(土) 渋谷でVJやります

1nfiniterave.peatix.com

クリエイティブコーディング系の人たちが集まってDJ/VJするイベントです。 僕は今回VEDAでGLSLライブコーディングする予定です(たぶん)。

  • 日時: 2018/09/15(土) 17:00-20:00
  • 会場: Shibuya Cast
    • 渋谷駅13番出口より徒歩1分

皆様ぜひ来てください!!