細野晴臣もハマった?
裸眼立体視というのがかれこれ20年くらい前に流行ったのをご存知だろうか。
昨年はアバター等の3D映画や対応テレビが発売され3D元年などと言われていました。
この流行、私だけでしょうか?若干コケた感がしますが、立体で映像を見たいという欲求は古今東西、少なからずあるようです。
さて、昨今のウェブ制作においてはHTML5やjavascriptに注目が置かれるようになって久しくなりました。中でもHTML5の新要素であるcanvas要素の利用についてはユーザビリティの向上などリッチなユーザーエクスペリエンス(って書くと大変胡散臭いですが)に直結する為、注目です。このcanvas要素上で簡単に様々なデータ視覚化、メディアアート、インタラクティブアニメーション等が実現できるライブラリがprocessing.jsです。
おお、これだ。これで3Dやってみよう!それも肉眼のみをつかった根性と共に。
努力して得た立体画像はお仕着せの立体画像より感動的な筈だ。
Processingについて
Processingは元々Javaのライブラリで、メディアアートや視覚化を実現できるデザイン言語(中間言語?)でもあるのがウリです。これを元にjQueryでお馴染みのJohn Resigが作ったのが
processing.jsとなります。Processingと互換性が高い言語が用意されており、映像コンテンツそのものを作る事に注力できます。
ランダムドット裸眼立体視について
普通に考えて左右の目に対して個別の画像を用意するところをランダムドット絵ではなんと一枚の絵に収め、これを何の器具も使わず肉眼のみで立体に見せてしまう所が画期的です。実はこの題材については、現在は休刊のパソコン雑誌Oh!X 1992年12月号の丹明彦氏の特集記事を元にしています。詳しくはそちらを、と言いたいところですが21世紀の現在では、オークション等で手にいれるしかありません(国会図書館にはあるかもしれないけど)。
簡単にアルゴリズムを説明すると、
まず、乱数を使って画面幅の1/5分の基本パターンを作りこれを左端のテクスチャにします。
これとは別にモノトーンの元絵を用意しておきます。元絵のモノトーンの色情報は便宜的に高さ成分とみなします。
用意した左端のテクスチャを右へ右へ繰り返し4回コピーします。
もちろん、ただ繰り返すだけでは立体になりませんので、この画面1/5ブロック単位内で、
ピクセル単位のループを行い、その際に加工を施します。
とりあえず立体に見せるには意図的に両眼視差(つまりは差分だけ)を発生させれば良いので、
テクスチャと対応する元絵の座標から色成分(つまり便宜上の高さ)に比例した分だけ右にある座標の色情報を持ってきます。
そうすると、
n=0 | 1周目の左目画像 | |
n=1 | 2周目の左目画像 | 1周目の右目画像 |
n=2 | 3周目の左目画像 | 2周目の右目画像 |
n=3 | 4周目の左目画像 | 3周目の右目画像 |
n=4 | 4周目の右目画像 |
となり、破綻せずに一枚の絵に立体像を保存できます。
なぜ5分割が妥当(環境によって異なると思うけど)なのかは両眼の距離に関係してると思いますが、お詳しい方に説明を譲ります。
特集記事では簡単な3D図形を用意していましたが、今回は手っ取り早く
文字を浮き彫りにしてみようかと思います。しかも面倒なので無限遠か手前にあるかの二値です。白(255)なら3px右にあるドットを貰う。黒(0)ならそのままコピーという実装になっています。
何分初めてでしたのでオフスクリーン描画はprocessingだとどうやるの?とかハマりましたが、
結構簡単につくれました。
ファイルの構成としては、実際には若干異なりますが基本次のとおり、これだけです。
./index.html | canvas要素のあるhtml |
./ragan.pjs | ランダムドット絵を描画する為のprocessing.js用ソース |
./processingjs/processing.js | processingjsのライブラリ |
肝心のprocessing部分のソースはこちらです。
このうち、
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | void setup(){ frameRate(20); size(g_width,g_height); } void draw() { if(g_old_msg != msg) { drawAll(); g_old_msg = msg; } } |
についてはイベントハンドラとなっていて、フレームワーク側から呼び出されるメソッドです。
setup()で初期化をします。draw()はframeRateで指定された間隔毎に繰り返し呼び出されます。
draw()内でhtmlファイルに記載したjavascript側のmsg変数(INPUTタグと対応)の変化をチェックし、変更があればdrawAllを呼び出しています。
(このように通常のjavascriptの変数もprocessing.js側から参照できます。)
なお、drawAll()から更に関数を呼びだしており、
drawText()では元絵(黒地に白の文字列のイメージ)を作成し、
drawRandomDot()で前述の処理を行い、
drawMark()でドット以外の立体視の目安となるライン等描画しています。
出来上がったアプリはこちらです。(html手抜き感抜群なのをなんとかしたい。)
裸眼立体視はコツがいる、且つ、口笛のように説明が難しい?ので頑張ってください。
ウケを狙ってツィートボタンとかつけて見ましたが、そんなに公衆に耐えれる仕様では無い気がしています。あと申し訳ないですがIEは対象外です。IE9はいけるのかな?
このように拍子抜けするほど簡単な記述で立体視のアプリケーションができました。
ただ、processingの醍醐味としてはアニメーションにあると思いますので、
このような静止画であれば、サーバサイドで生成してクライアント側に画像を送りつける
というアプローチと見た目上変わりなくprocessing.jsの凄さはわかりにくい例だったかもしれません。しかしながら、サーバサイドにはhtmlファイルとjsファイル、及びprocessingの言語ファイルであるpjsファイルのみで、全てブラウザ単独で稼働している点が凄いです。
Flashも要りません。
次回、processing.jsを題材にする際は
アニメーションするコンテンツを扱ってみたいと思います。
コメントを残す