vvvvを使ったインスタレーションアートの制作記録
先日vvvvをメインツールとしたインスタレーションアートの制作をしました。
全くの初学者から、まるまる一ヶ月ほぼ毎日付き合ってみて、ある程度全容が掴めてきましたので、vvvvに興味のある人や、これからvvvvを使ったインスタレーションを作成する同業者に向けて、開発環境や設計から全体の所感をここに残したいと思います。
はじめに
vvvvvとは何か?
vvvvは、.NET(C#)をベースにしたビジュアルプログラミング環境です。主ににインタラクティブなメディアアートやインスタレーションの制作に使われています。
その特徴は、ノードベースのプログラミングスタイルで、視覚的にプログラムを構築できるため、プログラミングの専門知識がなくても直感的に操作可能です。また、オブジェクト指向プログラミングの機能もあり、ノードベース(関数型風)プログラミングとオブジェクト指向プログラミングの良いところを両取りできる点も魅力的に感じます。
インスタレーションアートの制作に向いている理由
vvvvがインスタレーションアートに非常に適している理由の一つは、ノードベースのプログラミングによる直感的な操作性です。視覚的にプログラムを構築できるため、右脳(創造性)を常に稼働させながら、ビジュアルプログラミングをすることができます。
また、リアルタイムでの変更が即座に反映され、デバッグが容易なため、試行錯誤を繰り返しながら最適な表現を探るプロセスがとてもスムーズです。
さらに、vvvvvの特徴は
- オープンソースのゲームエンジンのStride+DirectXを利用した高性能なグラフィックスAPIにアクセスできる。
- センサーやデバイスや他のアプリとも簡単に連携できる。(NDI/SpoutやHTTP/UDPなどなど)
- .NETのライブラリやリソースを活用できる。
- VL.FuseというGPUプログラミングを取り扱うライブラリが強力
苦手な点
vvvvは小規模から中規模のプロジェクトには適していますが、大規模で複雑なアプリケーションの制作は、管理が難しくなることがあります。特に、多数のノードを使用した場合、全体の構造が複雑化(スパゲッティ化)し、メンテナンスや変更が困難になることがあります。
その他、
- UIが日本語フォント対応していないほか、日本語での情報やコミュニティが限られています。
- 基本的にはプログラミング環境なので、便利機能などはライブラリ頼みです。
- Gitでバージョン管理できるが、Mergeにクセがある。
- Windows限定+DirectX限定なので、Macでの開発不可。
- VL特有の命名(SpreadやClass, Record, Operation, Pad, Region)などの他の言語では見られない独特な名前や概念には慣れが必要です。
インスタレーションアートの設計
複数人数での開発と、ほぼ一人での開発では設計の重要度が変わってきます。
最終的にはほぼ一人で実装しましたが、2〜3人程度が参加する前提での開発を意識しつつ、個人開発のスピードを落とさないような設計を目指していました。
開発環境
バージョン管理
プロジェクトファイルのVLDocument(.vl)はXMLベースの構造なので、Gitでの管理ができます。しかし、VLDocumentの競合のマージは構造を把握しないと難しいため注意。(マージツール有り)
あくまでビジュアルプログラミングなので差分はノードの情報でしかないことに注意しましょう。もし複数人数で開発する場合は、作業者ごとに編集範囲や編集ファイルのコントロールが必要になってくると思います。
ファイルやフォルダ管理は割と自由です。
一例ですが、僕は開発するモジュールやコンポーネントの粒度と命名規則を意識しながらサクッと決めたものが下記の画像です。
アセット管理
画像、フォント、動画など様々なデータを取り扱える。
- AssetLoader的なものを自前で実装してもいい
- 個人的にはパスを吸収するProcessを用意しておくのが手軽でよい。
設計と実装
ファイル分割
各機能やコンポーネントごとにファイルを分割することで、変更の影響範囲を最小限に抑え、新しい開発者がシステムに参加した際にも迅速に理解できるようになります。
vvvvはVLDocument同士を依存関係(Dependency)でつなぐことができ、それによって、ファイル分割による共同編集を可能にしています。
ざっくりと設計のイメージ図を書いてみました。ポイントは
- MainAppとなるファイルには、Windowとコンポーネントの参照のみを置く
- 循環依存にならないようにする。(依存は一方通行)
- Modelを介してデータのやり取りをする
Singletonパターン
Singletonパターンは、クラスのインスタンスがアプリ上で一つだけ存在することを保証するデザインパターンです。このパターンは、設定情報や共通リソースの管理など、アプリケーション全体で使い回す状態を維持するために使います。
- MasterInstanceというSingletonInstanceを返すだけのOperationを置いておく。
- 全てのVL.Documentに依存を通す。
- どの場所で呼び出しても、一意のMasterInstanceが呼び出される。
そしてこのInstanceがModelの役割を果たし、データの仲介役になります。
ChannelによるReactiveプログラミング
Reactiveプログラミングは、データの流れと変化に応じたプログラムを構築するためのパラダイムです。ユーザーの入力や外部イベントに対して迅速に反応するアプリケーションを設計することが可能になります。
特にVLのChannelを用いた実装は、シンプルなPubSubの機能を持っていて非同期処理を効率的に管理するのに有効です。Channelを使うことで、異なるコンポーネント間で簡単にデータをやり取りすることができ、システムのリアクティブ性が向上します。
主な使い方は、
- Channel<T>をプロパティとして持つクラスを作る。
- そのChannelに対して、SetValueとValue(Pub-Sub)をする
だけでOK。
そのクラスをMasterInstanceに置いておくことで、様々な場所で使い回せる。
※あちこちで自由にSetValueしすぎると処理を追えなくなります。
シーケンシャルなアニメーションの実装
KairosEditorというプラグインがあるが、かなりクセがある。使用感があまり良くなく、安定感にも疑問があったため、導入するなら覚悟が必要。
個人的には外部ソフトウェアからOSC等を飛ばしてアニメーションさせるのをおすすめしたい。
TouchDesigner、Ableton Live、Chataigne、TouchDesigner、Blender、Unity, UE5など用途に応じてシーケンスが得意なソフトウェアを適宜使うと良い。
デバッグ
vvvvにはリアルタイムで値の監視ができるので、デバッグツールの世話になることが少ないと思います。エラーの位置がWarningなども比較的わかりやすい部類かなと思います。
- IOBoxesに繋いでリアルタイムで値を確認できる。
- LogノードでConsoleに出力できる。
- Ctrl+F2でLoggerパネルを表示できます。
- VisualStudioにAttachすればBreakPointを設定してデバッグできる。
- VL.FuseはGPU上の値をリアルタイムで確認できたりもする。
よくあるエラーの出現場所としては、F9でのプロセスの再起動時のエラーかと思います。Try-Catchを丁寧にしてあげたり、vvvvのLifecycle(Create,Update)への理解がデバッグの助けになると思います。
プロファイリング
F5で実行されているタスクとそのStatsが表示されますが、見づらい上に問題の箇所がわかりづらいです。
vvvvの各ノードのCPUの実行時間はマウスホバーで見れるので、作った処理が重たいかどうかをチェックすぐにできます。また、処理をProcessでまとめれば、そのProcess全体の実行時間をすぐに確認できます。
処理を削除したり、Ifで区切ったりとリアルタイムでフレームレートや実行時間が変わるので、問題のある処理を絞りながらデバッグする方法が、力技ですが効率が良いと感じました。
GPUプロファイリングは、RenderDocなど外部ツールを使って行うのを推奨されていますが、これも処理のカットや削除で、ざっくり問題点を洗っていけば、処理負荷の高いところが絞れていくと思います。
その他パフォーマンス最適化のTips
- Cacheがお手軽で強力。
- CPUで重たい処理をさせる場合はマルチスレッド・マルチプロセスな処理を意識する。
- VL.StrideではECS(Entity Component System)がベースなのでその仕組みをなるべく活かす。
- VL.Fuseを使えば、GPUを活かした処理も手軽に実装できるので、大量の計算を並列で処理したい場合はGPUの力を借りることをおすすめしたいです。
- アプリケーションをExport(ビルド)する。
まとめ
感想
vvvvあくまでプログラミング環境なので、便利なGUIやシーケンスなどは期待しないほうが良いです。逆にそういったものを何でも作れてしまう自由度はあるのかなと思います。
ゲームエンジン特有の多機能かつ高機能なGUIのものと比べると見劣りはしますが、グラフィックスプログラミングを、高速かつシームレスにプロトタイプしていく体験は他のソフトウェアでは味わえない使い勝手だと感じました。
ノードベースプログラミングで高速にプロトタイプを制作したり、CPUとGPUの連携を素早く実装できたりと、良いところはたくさんありますね。
特にVL.Fuseを使ったGPUパーティクルシステムは、NiagaraやVFXGraphに比べてカスタマイズが手軽にできると感じました。
参考文献と学習リソース
人によって学習の方法は違ってくるとは思いますが、個人的なおすすめの学習方法を紹介します。
- HelpBrowserのサンプルをすべてチェックする。
- ライブラリの中身もVLで実装されていることが多いので、処理を深堀りできる。
- .NET(C#)周りのリファレンスも参考にする。
Discussion