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分

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

個人用Windowsマシンでの開発環境構築メモ

f:id:amagitakayosi:20180822160527g:plain

6月に転職してWindowsマシンを触ることになったんだけど、環境構築で色々とハマったので、忘れないうちにメモっとく。 キーバインドとか結構特殊にしてるので参考にならないかも……

TL;DR

筆者のスペック

マシン: MSI GS65 Stealth

今の仕事ではGPUパワーが必要になるのでゲーミングPCを選んでいたんだけど、どれも見た目が微妙……。 界隈ではRazer Bladeがイケてるみたいな風潮があって、ちょっと気になって、あまりにも壊れやすいという情報もあったので今回は見送り。 そんなとき、 @ayumu_naga 氏がMSI GS65 Stealthを使っているのをみて、購入を決めた。

英字配列の製品はAmazon JPにはないので、総務の人に無理言ってAmazon.comから購入してもらった……🙇

見た目は控えめだしGPUGeForce GTX1060で十分だし概ね満足している。 ただ、PCを閉じてもスリープ失敗してカバンの中でメチャクチャ熱くなるという現象が発生して困っている。 今に壊れそうでヒヤヒヤする、BIOSの設定で直るんかな……

あ、あとトラックパッドが微妙。 一応どこ触ってもクリックできることになってるけど、端っこでクリックすると明らかにトラックパッドがたわんでて、今にも壊れそう。 Bluetoothマウスやトラックボールを一緒に持ち歩くと良いでしょう。 僕は昨日ロジクールのMX ERGOを買ったよ。

キーバインド

  • AutoHotKey: 左右のAltを英字/日本語のIME切り替えに割り当てる
  • keyhac: カーソル移動、AltをCmd代わりに使う

AutoHotKeyは「すり抜け」という問題がある。 例えば Ctrl + N キーにマッピングしている時、 Ctrl + N を押しっぱなしにしていると、たまに N が入力されてしまう。 すり抜けについては以下のブログ記事が詳しい。

AutoHotkey:キー押しっぱなし病・ホットキーすり抜け病対策の研究

これではカーソル移動に使うにはちょっと厳しいので、keyhacと兼用することにした。 AutoHotKeyIME切り替えにのみ使うので、AHK本体ではなくこちらのパッケージを使っている。

GitHub - karakaram/alt-ime-ahk

keyhacはPythonで設定を書けるので便利。 MSI GS65 Stealthでは、AltがほぼmacでいうCmdの位置にあるので、よく使うショートカットではCtrlとして使えるようにした。 郷に入っては郷に従えという言葉もあるが、MBPを触ったあとにWin機を触るとマジで入力ミスりまくって仕事にならないので……。

しかし、AltをCtrlに割り当てると、Ctrlが押しっぱなしになってしまう現象が発生した。 仕方ないので、CtrlのKeyUpも一緒に入力することで対処している。

    # Ctrl押しっぱなしになってしまうので、Ctrlをもう一度押して解除する関数
    withC = lambda x: (x, "D-Ctrl", "U-Ctrl")

    # Alt as Command
    keymap_global[ "A-C" ] = withC("C-C")  # Copy
    keymap_global[ "A-V" ] = withC("C-V")  # Paste
    keymap_global[ "A-F" ] = withC("C-F")  # Find
    keymap_global[ "A-T" ] = withC("C-T")  # New Tab

keyhacの設定ファイルはこちら: https://gist.github.com/fand/91f090a41639e65a16bf807631fe24af#file-config-py

シェル

f:id:amagitakayosi:20180822160527g:plain

ConEmu + PowerShell。 oh-my-poshっていう、oh-my-zshPowerShell版みたいな奴も使っている。

WSL + bashを使っていないのは、Windowsでの開発方法や文化を学びたいから。 僕はAtomパッケージを作ってるんだけど、ネイティブ拡張や外部アプリケーションとの連携でWin特有の問題が発生することがあり、そういうのを学ぶにはできるだけPowerShellとかcmd.exeを使ったほうが良い。 あと、WSL上のgitでUnityプロジェクトを管理するといかにもぶっ壊れそう、という理由もある。

当初、Cmderって奴がイケてると聞いて、↓の記事を参考にCmderをセットアップしたんだけど、Powerlineでカーソルがずれる問題がどうしても直せない。 (ググると「monospaceのチェックを外せ」と出てくるが、効果なし)

PowerShell, Cmder / ConEmu, Posh-Git, Oh-My-Posh, Powerline Customization · GitHub

CmderはConEmuのラッパーなのだけど、ConEmuを直接起動するとカーソルがずれる問題は発生しないことがわかったので、以降はConEmuを利用している。 スタートアップにConEmuを登録し、 Alt + Space で表示するようにした。 (MSI GS65の Alt + Space はMBPの Cmd + Space と同じ位置)

MacではGitプロジェクトをghq + pecoで管理し、Ctrl + ] でレポジトリの絞り込みができるようにしていた。 PowerShellではキーバインドで関数呼ぶのが難しそう?なので、 gh コマンドでレポジトリを絞り込みできるようにした。

function gh () {
  cd $(ghq list --full-path | peco)
}

PowerShellのプロファイルはこちら: https://gist.github.com/fand/91f090a41639e65a16bf807631fe24af#file-powershell_profile-ps1

エディタ

普段使いはAtomでいいんだけど、C#では使い物にならず、Unity開発ではVSCodeを使っている。

C#には、様々なエディタでIntelliSenseによる補完が使えるようになるomnisharpというプロジェクトがある。 Atomではomnisharp-atomというパッケージで補完が効くようになる……はずなんだけど、一年くらいメンテが停止しており、動かなくなってしまっている……

Visual Studioはなんか性に合わなかったので、結局VSCode + omnisharpでC#開発してる。 他の言語ではやはりAtomの方が快適なので、Atomも併用。

その他

ランチャ

Macでは Alt + Space でSpotlightを表示できるようにしている。 MSI GS65の場合、同じ位置にあるキーは Win + Space になるんだけど、Windowsでは Win + SpaceIME切り替えに登録されており、変更できない(!)。

Woxを試してみたりしたけど、他にしっくりくるキーバインドが無いのと設定が面倒なので、使うのをやめてしまった。 結局スタートメニューをランチャとして使っている。

なんか良い方法ないかな……keyhacで Win + Space を上書きしたらええんかな……

スタートメニュー

f:id:amagitakayosi:20180822161351p:plain

デフォルトで表示されてるパネル邪魔すぎるので全部消して、よく使うやつだけ登録し、サイズも最小になるようにした。 Classic Shellってやつも試してみたけど、表示がもっさりしたり、タスクバーが隠れなくなったりする問題があるのでやめてしまった。

フォント

フォント汚くて目がチカチカするのでMacTypeを使っている。 大昔にも使ってたけど、まさか2018年にもなってMacTypeを使うことになるとは…………

デスクトップ

VJパフォーマンス中の万一の事故に備え、壁紙を真黒にし、デスクトップのアイコンをすべて非表示にした。

仮想WebCam

ビデオ入力を用いたシステムのテストにはManyCamを利用する。 デスクトップのキャプチャや動画ファイル、Youtubeの映像を仮想WebCamとして使えるようになる。

キーボード

MSI GS65 Thinは設定でキーボードの光り方を変更できる。 テンションを上げたい時に便利。


他にいいTipsあったら教えてくれ~~~~~~~~