こんにちわ。エンジニアのビジュアル担当、渡邊(@_nabe)です。
今回はバスキュールとは全く関係ないんですが、趣味で北千住デザインという名義で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
おわりに
世にある大概のマッチムーブは実写とCGの合成が違和感ないように、なじむ方向に作るのだけれど、今回のように実写としょぼいCGを組み合わせてみたら、それはそれで違和感が生まれて面白い。3Dトラッキングの精度はそれなりに必要だと思うけど。
今後もよいネタあれば、発信していきます。
あと今エンジニアを募集してますーー。 www.bascule.co.jp