TouchDesignerでガラスを透過したようなステルス迷彩を作りたい！

#待たせたな...
どうもみなさん初めましてお久しぶりですきゃみです．

タイトルにもあるようにですね、生粋のMetal Gear solidファンである僕としてはやはりこの野望は捨て切れないわけです．

###ステルス迷彩を作りたい！

、、、というわけで作りました．全国のステルス迷彩に野望を燃やしている中高大中小学生に届けば良いなと思っております．

![stealth.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/0f2bd522-182f-8339-c2db-4ab157ea60f6.gif)


....................
(部屋が汚い、、、)

では行こうっ！

## プロジェクトのセッティング
まずはTouchDesignerのプロジェクトを新規作成します．
デフォルトではNoiseのサンプル的なやつがあると思いますが、その辺は使わないので消してしまいましょう．

##カメラからのInput
自分がステルス迷彩を着るためには自分を映さなければ始まりませんね．
というわけでTouchDesignerにWebカメラのノードをおきましょうをおきましょう．Topノードの**Video Device In TOP**を選びます．

###動いているものの検出方法
ステルス迷彩を着るからには自分にだけエフェクトを書けなければいけないわけですが、ここで動的な動体検出の方法を何個か紹介しておきます．
( [こちらを参照しました](http://satoruhiga.com/TDWS2019/day5/) )

####フレーム差分法
これは、一つ前のフレームを参照し、現在のフレームと比較して異なる部分のみを抽出し、検出する方法です．
Feedback TOPを用いることで過去のフレームを参照することができるのですが、大きな動体を検出する際は、得てしてエッジの部分しか検出できないことが多いです．今回は確実に自分全体にエフェクトをかけたかったので、次に紹介する手法を採用することにしました．

####背景差分法
これは、あらかじめ撮影をする場所の背景を撮っておき、実際に撮影してる映像との差分を取ることで検出する方法です．あらかじめ背景の画像が必要ということもありフレーム差分法に比べて汎用性には劣りますが、背景の色が単純であればあるほど、輪郭部分のみならず（確実に）動体の中身を含めての検出もできます．今回はこちらを採用したので、これについてまずは紹介していこうと思います．

##背景差分法の実装
###フレームの固定
先ほど背景を固定しなければいけないと述べましたが、実はTouchDesignerにおいて場所ごとの背景を固定することは大して難しくありません．
さっき設置したVideo Device InからNullを繋げ、そのノードをロックしましょう．
<img width="804" alt="スクリーンショット 2020-05-08 1.23.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/cd341e0b-620e-8e52-14d6-a0ef728abe4d.png">
一番下の南京錠マークですね．これをONにすることでフレームを固定できるので、何も写ってない状態を固定しておき、これを背景として扱うことにしましょう．

###背景には存在しないものの検出
ここから、カメラに写っている自分の身を検出していきます．
今あるのは**背景**と**現在のカメラ**です．ここから自分を検出するにはどうするのか．
簡単な引き算で、
`背景` - `現在のカメラ(=背景＋自分)` = `動いてる自分`
というロジックで検出していきます．背景とVideo Device InをSubtractにつなぎましょう．

<img width="635" alt="スクリーンショット 2020-05-08 1.35.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/4b43e052-0666-6f9a-2716-c055b90ee523.png">


まあ多少セカオワのポスターも残ってますが良しとしましょう．

##検出した自分をもとに背景をずらす
さあ、自分を検出できたらあとはこっちのもんです．
背景差分法の出力のRGBを元に、固定した背景をずらしていきます．
###GLSL TOP
ピクセル処理といえば言わずと知れたGLSLによるシェーディングですね．Subtractと背景をGLSLに繋いで、以下のようにピクセルシェーダーを書いていきます．
GLSLって何？！っていうかたは[こちら](https://qiita.com/sanokazuya0306/items/530ed55a021db24ad8ec)を参照してください。

<img width="881" alt="スクリーンショット 2020-05-08 1.39.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/e87a57ce-7683-76ac-5fcb-f9aa19f5ce89.png">

```glsl:glsl_pixel.glsl
out vec4 fragColor;
void main()
{
    vec3 c = texture(sTD2DInputs[0], vUV.st).rgb;
     vec4 color = texture(sTD2DInputs[1], clamp(vUV.st+c.rb*0.08, 0.0, 1.0));
    fragColor = TDOutputSwizzle(color);
}
```

#####たったこれだけ？！

以外にこれだけの画像処理で書けちゃうんですね．
今回はRed値とBlue値でずらしていますが、そこらへんはお好みで好きな値を選んでください．
RGB値に対して0.08を掛けていますが、ここも自分で出力を見ながら数字を選んでみてください．

##完成？
<img width="1277" alt="スクリーンショット 2020-05-08 1.47.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/ca650843-e4d9-4b80-fadf-43797bb68ea2.png">

なんだか一瞬でできちゃいましたね．

でもステルス迷彩には何か足りなくないですか？

なんだろう、、何か違和感あるんだよなあ、、、

確か某オタクの博士はあの時、、、

![otakon.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/7c489945-f035-a9b1-f9cb-6e8167494b30.gif)

####そうだ！

何かデバイスみたいなものを触って起動してるじゃないか！
そしたらそれも実現してみよう！

##iPhoneをきっかけにステルス迷彩起動
というわけでこちらも考えてみました．iPhoneとTouchDesignerを手っ取り早く繋げるにはやはりOSC通信かなと思ったので、今回はそちらを採用しました．

ただし、iPhoneでOSC通信をするには専用のアプリが必要です．意外と世の中にはいろんなアプリがあるので一番使いやすいやつを採用してもらっていいんですが、僕は[ZIG SIM](https://zig-project.com/)というアプリを使いました．OSC使ったことない！っていう人はこちらをインストールしておいて下さい．

TouchDesignerには、**OSC In CHOP**を用意しておきます．

###OSCの設定
OSCとは同じIPアドレスをもつネットワーク環境下において、情報のやり取りをする技術のことです．（ざっくり）なので、TouchDsignerで扱うOSCのIPアドレスとiPhoneで扱うOSCのIPアドレスの値は同じである必要があります．まずはこれを設定していきます．

####iPhone側
IP ADDRESSとPORT NUMBERを設定していきましょう．自分が接続しているWiFiのIPアドレスは**設定>WiFi**へ移動し、繋いでいる WiFiの情報を見れば取得できます．PORT NUMBERはなんでもいいのですが、あまり小さいと他のデフフォルトのネットワークとバッティングする可能性があるので、出来るだけ大きな数字にしておきましょう．

####TouchDesigner側
**OSC In CHOP**のLocal Addressと、Network Portを、先ほど設定したものと同じ値にしましょう．Local Addressは先ほどのIPアドレスと同じものです．

##触ってみよう
この時点でiPhoneを触ってみましょう．下のタブのStartをタッチして、色々画面をタッチしてみてください．

![osc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/edd1d79e-4917-a3d6-5a4a-ea88ab7c2b77.gif)

一番上が0か1で遷移してませんか？
なってない人は、iPhone側のSensorの**2D TOUCH**の項目にチェックが入ってない可能性があります．確認してみましょう！

##タッチをトリガーに画面切り替え
**Switch TOP**を新たに作り、**Video Device In TOP**と**GLSL TOP**を接続しましょう．
Switch TOPは、異なるTOPを切り替えたいときに使います．Switchの項目のIndexの値によってシーンを切り替えられます．逆にいえば、このIndexの値を操作できれば、自分でシーンを切り替えられるわけです．

というわけで、OSC In CHOPの一番上の値を、Switch TOPのIndexにExportしましょう．

##今度こそ本当に完成！
![jituen.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502701/b17ff958-52ad-61cd-4b7a-081ca0b7966e.gif)

いやあ、これで僕もMGSの住民になれました．
まだプレイしたことない人はぜひプレイしてみてください．（趣旨が違う）

##最後に
今回、OSC通信を用いて、ステルス迷彩のようなものを作成しました．
ぶっちゃけこれを作るぞ！って決め打ちで作ったわけじゃないんですが←　偶然の産物でいいものできるのがメディアアートのいいところかなあと思います．

少しでも参考にしていただけたら幸いです！最後まで見ていただきありがとうございました！