Max/MSP/Jitter実験記録#002.01 | パーティクルシステムを理解する

01 Max/MSP/Jitter

楽譜と音源を、視覚的に同期させた動画をつくりたいと思っています。
音が鳴った時にその音符が光るという動作をJitterで組むことを目標に、まずはパーティクルシステムというものについて勉強してみます。

映像を生成する場所をつくる

jit.matrix: 画像のデータを格納するためのマトリックスを生成する

前回では既存のビデオファイルを加工しましたが、今回はアニメーションを生成するために「マトリックス」を使います。

マトリックスとは「一つ一つに情報やデータを入れることのできるマス目の集合」です。
Jitterでは、マトリックスという記憶領域を使って、画像を生成したり処理したりします。
マス目はセル(cell)と呼ばれます。
一つのセルは複数のデータで構成されることがあり、データを種類ごとに分けたものをプレーン(plane)といいます。
プレーンは、ペイントソフトなどのレイヤーと同じように考えると理解しやすそうです。
より詳しい解説は、The JITTER Book (p.22) や Jitterによる映像表現 – yoppa.org がわかりやすいです。

このオブジェクトは、主に以下を定義することができます。


マトリックスの名前 … 自由に付けられます。
プレーン数 … 一つ一つのセルに何種類のデータが入るのかを、整数で表します。
データタイプ … char / long / float32 / float64 の4種類から選ぶことができ、後の方ほど扱える数字が多くなります。
次元 … ここでは、1000(列)×2(行)という2次元のマトリックスであることを定義しています。

また、bang を受け取ると、その時に格納されているマトリックスデータを出力します。

これらの数値が選ばれている理由には、後に続くオブジェクトに関係しているので、説明はまたのちほど。

パーティクルを使ったアニメーションのデータをつくる

jit.p.shiva: パーティクルの生成と削除を行う

ヒンドゥー教の神の名前を借りた、遊び心感じるオブジェクトです。
破壊と再生をつかさどるシヴァ神よろしく、パーティクルを出現させたり、削除したりを繰り返します。

jit.p.shiva に渡すマトリックスには、条件があります。

データタイプが float32 または float64 である
n×2の2次元である ( n に入る数値は、パーティクルの最大数になります)

そして、その渡されたマトリックスにはそれぞれ以下の情報が入れられます。

プレーン0 (レイヤー1枚目) ► パーティクルそれぞれのID
プレーン1 (レイヤー2枚目) ► パーティクルそれぞれの表示回数 ( age )

同じマトリックスを入口と出口に置いて接続することによって、マトリックス内の情報が交替され続ける(フィードバックする)ことになります。
プレーン1の数字は、そのフィードバックのたびに1ずつカウントが減っていきます。
そして、0に達したパーティクルは削除され、新たなパーティクルに置き換わります。

今回は以下のメッセージを使って、パーティクルの出現と消滅をコントロールします。

life ► 寿命
1つのパーティクルを何フレーム表示させるかを指定する。

life_var ► 寿命の変異性
lifeで指定した数値をランダムにゆらす範囲を指定する。

emit ► 放出量
1フレームでパーティクルをどのくらい放出するかを指定する。

emit_var ► 放出量の変異性
emitで指定した数値をランダムにゆらす範囲を指定する。

jit.p.vishnu: パーティクルの動きや分布をコントロールする

こちらは宇宙の維持をつかさどるヴィシュヌ神の名前を借りた、jit.p.shiva が生成したパーティクルの出現位置や動作をコントロールするオブジェクトです。

送られてきたマトリックスの、残っているプレーン2以降に情報を書き込みます。

プレーン数が5の場合
プレーン2 ► 3次元上の座標 x
プレーン3 ► 3次元上の座標 y
プレーン4 ► 3次元上の座標 z
プレーン数が8の場合
プレーン2〜4 ► 同上
プレーン5 ► xの方向性と速度 (velocity)
プレーン6 ► yの方向性と速度
プレーン7 ► zの方向性と速度

今回は以下のメッセージを使って、パーティクルの位置と動作をコントロールします。

pitch ► 傾斜
前後(上下)のアングルを指定する。

pitch_var ► 傾斜の変異性
pitchで指定した数値をランダムにゆらす範囲を指定する。

yaw ► 揺れ
左右のアングルを指定する。

yaw_var ► 揺れの変異性
yawで指定した数値をランダムにゆらす範囲を指定する。

speed ► 速さ
パーティクルが放出される速さを指定する。

speed_var ►
speedで指定した数値をランダムにゆらす範囲を指定する。

pos ► 位置
パーティクルが出現する3次元上の座標を指定する。

force ► 力
出現したパーティクルに、風や重力のようなふるまいを付加する。

pak: 入力を受けたらリストを出力する

たとえば今回の pak pos 0. 0. 0. は、上につながっている flonum のうちどれか一つの数値が変わったら
その都度メッセージ pos 指定された3つの数値(小数) が出力されます。

データを画像として描画し、映像に出力する

マトリックスにはパーティクルの十分なデータが格納されましたが、まだ映像として見ることができていません。
ここからは、実際に画像として表示する段階になります。

jit.window: ウィンドウを表示させる

実験記録#001.01では jit.pwindow を使いましたが、今回はパッチの外にウィンドウを開くこのオブジェクトを使います。
@size の後に続く2つの数値は、ウィンドウのサイズを指定しています。
ここでは “field” という名前が付いた960×540のサイズのウィンドウを表示させることを定義しています。

jit.gl.render: OpenGLのグラフィックスを描画する

3次元の画像を扱うことになるので、レンダリングのためのオブジェクトを使います。
最初のアーギュメントは出力された画像の行き先を表しており、ここでは先ほど名付けたウィンドウ “field” に送られることになります。

bang を受けると新しく画像を描画し、erase を受けると画像を削除 (デフォルトでは灰色で塗りつぶし)します。
また、接続されている erase_color とそれに続く4つの数値はそれぞれ、ディスプレイでの色の表現におけるR(赤)/G(緑)/B(青)/A(透明度)にあたり、何の色で塗りつぶすかを指定できます。
たとえばRGBを “0. 0. 0.” とすることで色は黒になり、Aを1より小さくすることでコマの残像が残るようになります。

また以下のメッセージを入れると、描画プリミティブと呼ばれる、いわゆる描画のモードを切り替えることができます。
ここでは、パーティクルの見え方がわかりやすく変わった4つのメッセージを紹介します。
(正直なところ、下2つに関する定義はあまり理解できていません…!)

points ► 点

lines ► 線

tri_grid ► 三角形のかたちになる面

quad_grid ► 四角形のかたちになる面

jit.matrix (再): 新しいマトリックスを生成する

これまで使ってきた”particle”と名付けたマトリックスですが、実はこのままでは jit.gl.render につなげても画像として出力してくれません。
そのため、”particle”を再解釈するための新しいマトリックス(“translate”)を生成します。
“particle”と異なり、プレーン数は3になります。

レンダリングに必要なのは、”particle”のプレーン2〜4に格納されているデータです。
@planemap を使うことによって、このデータは”translate”にコピーされます。
これで、マトリックスの情報は jit.gl.render によって解釈され、描画されるようになりました。

qmetro: 指定された時間間隔でbangを出力する

メトロノームのように、指定された時間(ミリ秒)の間隔ごとにbangの命令を出力します。
1 ( = toggle のON ) を受け取ると動作を開始、0 ( = toggle のOFF ) を受け取ると停止します。

よく似たものに metro というオブジェクトがありますが、こちらは例外なく毎回bangを送り続けるのに対し、
qmetrobangの受け取り先の処理がまだ完了していない場合、そのbang命令をスキップするという役割が追加されているようです。

t (trigger): 受け取ったデータを複数の出力先に送る

trigger でも t でも同じ役割のオブジェクトになります。
t の後に、文字列や数字などのアーギュメントを空白で分けて並べると、その数に従ってアウトレットの数が増減します。

ここでは t b s erase となっていますが、それぞれ以下のデータが順に出力されることになります。
注意: 出力は右から左へ行われます。

① erase … メッセージ “erase”
② s (または l ) … マトリックスのデータ群
③ b … メッセージ “bang”

これにより、後に接続されている jit.gl.render は、画像を消す → マトリックス”translate”のデータを受け取る → 受け取ったデータによる画像を描画する という動作を30ミリ秒ごとに繰り返すことになります。

まとめ

Jitterにおけるパーティクルの基本的な機能のひとつを無事、動かしてみることができました。
これをさらに、色や大きさを変えたり、光らせたりなどしたいですね。

参考文献

Jitter チュートリアル
Jitter チュートリアル
第5回:Jitterによる映像表現
SSAW11の最終課題は「音響楽器」だけとは限りません。センサーからの入力や自作のインタフェイスを使用して映像を奏でるような「映像楽器」といった応用も考えられます。今回は、Max/MSPの環境で映像を扱うためのオブジェクト群であるJitterについて学んでいきます。 サンプルパッチ5月31日 (Google Docsに...
Jitter Particle tips 01 | RHYSHAFT
簡易なパーティクル表示 | akalogue
MAX/MSP+Jitter勉強中: FLASH+α
Karappo Interaction Lab. » #017 : qmetroとmetroの違い
インタラクティブ
Maxのパーティクルシステム その1: jit.p.shiva jit.p.vishnu jit.gen jit.gl.multiple #max6 #maxmsp #jitter #cycling74
Maxのパーティクルシステム その2: jit.p.shiva jit.p.vishnu jit.gen jit.gl.multiple #max6 #maxmsp #jitter #cycling74
jit.gl.pix を使ったパーティクルシステム: #max6 #jitter #cycling74
jit.gl.pix を使ったParticle生成と描画:#max6 #jitter #cycling74
Amazing Max/Msp Tutorial 02 – How to Build a Particle System in Max (ENG)
350K Particle System in a Box – Max/Jitter (Patch download)
GPU Particle System with Billboarded Particles in Max/MSP

コメント