##はじめに
北千住デザインという名前でthreejsを使ってブラウザVJをやっています。今回はそのVJネタのひとつを説明します。
##やったこと
ARみたく、実写と動的なCGを組み合わせてVJをしたいと考えた(こういう合成をマッチムーブというらしい)。
ただARは現状では精度が低かったり、リアルタイムが前提の表現なので、映像作品とみたときイマイチな場合がある。そこで、実写映像をあらかじめ撮影して別のソフトで3Dトラッキングし、それにWebGLで描画された音に反応する映像をオーバーレイさせるという方法をとってみた。静的な映像と動的な映像のハイブリットといった感じ。
こんな感じで、背景はふつうのリニアな映像、手前の動いている物体は、音に合わせてリアルタイムに変形している。
キマイラ #BRDG7 @ 渋谷WWW X
— KG (@keiji_307) 2016年9月18日
DE DE MOUSE🐭 x HEXPIEXLS with 北千住デザイン✨
これヤバすぎて🐼顔が凄くにやけた☺️☺️☺️ pic.twitter.com/775uMeOcBh
##トラッキング
実写のトラッキングにはCinema4d Studioを使った(会社にあったから)。やり方はこの辺を見ればわかる 。トラッキングができたら、Cinema4DはPythonを使える機能があるので、それを使い、毎フレーム、カメラの座標・回転(クォータニオン)・FOVをjsonに書き出す。ただcinema4dとthreejsは座標系が違う(左手・右手)ので書き出す際注意が必要。
Cinema4dのPythonのコードはこんな感じ
https://gist.github.com/kitasenjudesign/d739c6123e0b55bc77445d2db6f608d1
書き出したJSONはこんな感じ
"frames": [
{
"fov": 32.70611613573759,
"frame": 0,
"q": [
0.01175325347189373,
0.9667209890999054,
0.04514531549377907,
-0.25154381478281923
],
"x": -141.4472256273544,
"y": 68.24724022421263,
"z": -198.63611330979802
},...
これをthreejsに持っていき、映像の再生時間と合わせて、毎フレーム、PerspectiveCameraのパラメータを更新すれば良い。
※AfterEffectsでも同様のことができるようです。他の3Dソフトでもできると思う。
https://medium.com/@Jam3/mtchmv-a54624f6232#.jwdrxnan1
##Video再生
WebGLのキャンバスを透明にして下にVideoタグを敷くという方法もあるが、今回はポストプロセスもかけたかったのでVideoをCanvasにキャプチャしてthreejsの中の板ポリに貼り付けた。(やり方はググれば出てくる)
その際、板ポリはカメラに関係なくずっと正面を向いていてほしい。毎フレーム、板ポリをLookAtするという手段もあるが、めんどいので、以下のようにシェーダーを書いた。
geo = new THREE.PlaneBufferGeometry(2, 2, 1, 1);
mat = new THREE.ShaderMaterial({
vertexShader: _vertexShader,
fragmentShader: _fragmentShader,
uniforms: {
texture: { type: 't', value: _texture }
}
});
mesh = new THREE.Mesh(geo,mat);
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 hoge = vec4(position, 1.0);//マトリックス計算しない
hoge.z = 1.0;//最背面のz=1に。
gl_Position = hoge;
}
uniform sampler2D texture;
varying vec2 vUv;
void main()
{
//テクスチャを書き出してるだけ
gl_FragColor = texture2D(texture, vUv);
}
##影
影もつけたい。ShadowMaterialっていうのを使うと透明なPlaneに影だけ落としてくれる。ありがたい。
http://stackoverflow.com/questions/35710130/shadow-catcher-in-three-js-shadow-on-transparent-material
##クリッピング
地面から飛び出してくるような演出もしたい。3Dオブジェクトをクリッピングせねばならない。シェーダーを自分で書いても良い(たとえばy<0ならdiscardするとか)。けれど、めんどうなので、これもthreejsのクリッピング機能を使う。ありがたい。
https://threejs.org/examples/?q=clipp#webgl_clipping
##おわりに
Threejsはめんどいこともやってくれて素晴らしい。WebGLは手軽だし、VJみたいなことも十分できる。今回のように他のツールと組み合わせて、なんかやるのもいいのかもしれない。