53
Making of BODA-RIDE 2015.06.18 @GREE Tech Talk #08

Making of BODA-RIDE

Embed Size (px)

Citation preview

Making of BODA-RIDE2015.06.18 @GREE Tech Talk #08

自己紹介

岩渕智幸

株式会社バスキュールのフロントエンジニア集団「技術開発部」所属。

Flash Stage3D ・BLOODY TUBE ・… WebGL ・BODA-RIDE

@buccchi

2014年8月 SENSORS 番組プロジェクト始動2014年12月 BODA-RIDE サイト公開

2015年1月 テレビ連動版 BODA-RIDE 放送(マジすか学園コラボ)SENSORS IGNITION 2015 開催決定

2015年3月 BODA-RIDE LIVE 開催(SENSORS IGNITION内)

プロジェクト全体の流れ

2015年4月 NY ADC GOLD 受賞

2015年2月 FWA SITE OF THE MONTH 受賞

2014.8 SENSORS プロジェクト始動

動く人体をセンシング + アミダのアップデート

Kinect v2 キャプチャシステム映像に変換

WebGLで再現

Windows

BlackMagic Design社の映像機器映像出力

depth 情報

color 情報

1つの画像に

キャプチャシステム

MacChrome

WebGL

カラー情報をマッピング

Depth 情報から立体データを生成3D空間に再現

DEMO GPUで頂点を動かす

BufferGeometry

106

128

BufferGeometryを作って頂点を制御する

Depth 画像の 明度に応じて y座標を変更

212

256

BufferGeometryを作る

positions = new Float32Array( n * 3 * 3 )

# v0 positions[0] = 0 positions[1] = 100 positions[2] = 0 # v1 positions[3] = 0 positions[4] = 0 positions[5] = 0 # v2 positions[6] = 100 positions[7] = 0 positions[8] = 100 # v3 positions[9] = 100 positions[10] = 0 positions[11] = 0

addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ))

頂点を作る(頂点座標の設定)

x

z

v0 (0, 0, 100) v2 (100, 0, 100)

v1 (0, 0, 0) v3 (100, 0, 0)

面を張る(頂点インデックスの設定)

indices = new Uint32Array( n * 3 )

# 1枚目のポリゴン indices[0] = 0 indices[1] = 1 indices[2] = 2

addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ))

x

z

v0 v2

v1 v3

uvs = new Float32Array( n * 3 * 2 ) # v0 uvs[0] = 0 uvs[1] = 1 # v1 uvs[2] = 0 uvs[3] = 0.5 # v2 uvs[4] = 0.5 uvs[5] = 1 addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) )

面に色をつける(テクスチャの設定)

x

z v0 v2

v1 v3

0

+V

1.0

+U1.0

v0 (0, 1) v2 (0.5, 1)

v1 (0, 0.5)

UV

面のエッジを立てる

v0 v2

v1 v3

共有している頂点を分離 1つのポリゴンを 構成する3つの頂点すべてに

同じ uv 値を設定

v1 v5

v3

v4

v0 v2

v1 v5

v3

v4

v0 v2

これを必要な分だけ並べる

106

128

27,136 ポリゴン(81,408 頂点)

動画の色情報を拾って頂点座標を動かす

Depth情報 カラー情報256階調のグレースケール

Kinect のセンシングデータから生成した映像

256

212

512

映像の Depth エリアを Canvas に描画して色情報を取得

context.drawImage( image, sx, sy, sw, sh, dx, dy, dw, dh ) imagedata = context.getImageData( sx, sy, sw, sh ).data

[ r,g,b,a, r,g,b,a, r,g,b,a, … ]0 ~ 255 の範囲 → 0 ~ 1 の範囲に変換して保持

頂点座標の更新

attributes.position.array の中身

index = 0 skip = 3 * 3 for i in [0…n] # 1つのポリゴンの y座標を更新 attributes.position.array[ index +1 ] = v0のy座標 attributes.position.array[ index +4 ] = v1のy座標 attributes.position.array[ index +7 ] = v2のy座標 index += skip

# 頂点情報の更新を通知 attributes.position.needsUpdate = true

v1

v0 v2

v2

[x,y,z, x,y,z, x,y,z, …]v1v0

BufferGeometry の中身を書き換え

DEMO フラットメッシュで頂点を動かす

課題・せっかく身体をスキャンしているのだから  それをもっと活かせないか

横線を排除してスピードレースに

曲線の表現

THREE.Spline( points )与えられた頂点データに対してスプライン補間を行う

v0

spline.getPoint( 0.083 )

spline.getPoint( 1 )

spline.getPoint( 0 )

v1

v2

v3

v4

スプライン補間された曲線基順点 各頂点の座標を取得

コースラインの表現

THREE.Line( geometry, material, type )

update:()-> ... # 頂点座標変更処理 ... # 頂点カラー変更処理

line.geometry.verticesNeedUpdate = true line.geometry.colorsNeedUpdate = true

頂点、色を更新

線オブジェクトを生成16本の線を 1オブジェクトで扱いたいので type は LinePieces

DEMO グラビアアイドル

・体(面)をもっと見せたいという意見 ・線だけですべてを表現したいという意見 ・スピード感がまったくない

課題

面の上を一定間隔で走る光の線(スキャンライン)を追加

2014.12 BODA-RIDE サイト公開

BODA-RIDE LIVE

会場スクリーン

I L E A J C K GA H B F N D M

H B F C B E J IA E P F C A G

Mac

・ライブイベントで映える演出の追加

ブラウザ版は自分が選択した1機だけが光ればよかったが LIVE版では複数人が同時に参加するため16機すべてを光らせる必要があった

LIVE版とブラウザ版との違い

・16機すべてにライトが必要

パーティーの場でより盛り上がるような演出が必要

・面につけてた陰を捨てる

16機すべてにライトが必要

距離から算出する簡易版に・機体のスポットライトを簡易版に

カラー映像に撮影時の影(陰)が入ってるのでそれを活かしたほうがクオリティがあがる

法線を反映するが 1機体のみ 法線を使わずに16機体すべて

ライブイベントで映える演出の追加

・BufferGeometry の分割数を増加

・パーティクル演出の追加スキャンラインが通過した場所からパーティクルを発生させる

より高解像度なモデルの表示

258

212

106

130

27,560 ポリゴン(82,680 頂点)

BufferGeometry の分割数を増加

109,392 ポリゴン(328,176 頂点)

パーティクル演出の追加

THREE.PointCloud( geometry, material )

カスタムシェーダーTHREE.ShaderMaterial( 頂点シェーダー, フラグメントシェーダー, uniforms, attributes )

スキャンラインが通過した場所からパーティクルを発生させる

uniforms全頂点の共通パラメータ

attributes個々の頂点情報

time texture

initPosition initTime dotColor lifeTime moveVolume scale

: vec3 # 設定時の位置座標 : float # 設定時の経過時間 : vec3 # パーティクルの色 : float # 生存時間(乱数) : vec3 # 移動量(乱数) : float # パーティクルの大きさ(乱数)

: float # 経過時間 : sampler2D # パーティクルのテクスチャ(png)

THREE.ShaderMaterial

: float # 経過時間 : sampler2D # パーティクルのテクスチャ(png)

: vec3 # 設定時の位置座標 : float # 設定時の経過時間 : vec3 # パーティクルの色 : float # 生存時間(乱数) : vec3 # 移動量(乱数) : float # パーティクルの大きさ(乱数)

毎フレーム更新

スキャンラインが 通過したタイミングで 通過した頂点分だけ更新

THREE.ShaderMaterial

uniforms全頂点の共通パラメータ

attributes個々の頂点情報

time texture

initPosition initTime dotColor lifeTime moveVolume scale

まずは25,000 個の頂点を用意

このスキャンラインが…

次のフレームではこの位置

このエリア内で y 座標が一定値を超えた頂点分だけ、 attributes の各パラメータを再設定する(初期座標、再設定時の経過時間、パーティクルの色)

初期座標、再設定時の経過時間、パーティクルの色 を再設定したのがこれ

uniforms.time(経過時間)が更新されると 頂点シェーダーによってそれぞれの方向へ移動する

DEMO BODA-RIDE LIVE