Maxのパーティクルシステム その1: jit.p.shiva jit.p.vishnu jit.gen jit.gl.multiple #max6 #maxmsp #jitter #cycling74

スクリーンショット 2014-07-02 17.59.38

アニメのオープニング、特に芳文社系を見ているとタイトルが出現する辺りの画面遷移エフェクトとして、桜のパーティクルが多用されている事に気が付きました。さっそく桜パーティクルVJを行うべくjitterのパーティクルシステムを調査しました。

Jitter パーティクルシステム × jit.gl.multiple TIPS

  • jitter のデフォルトで付いてるパーティクルシステム jit.p.shiva / jit.p.vishnuでは、オブジェクトの回転処理が入っていないため、全部同じ向きに表示される。(トップの桜パーティクルは、全部同じ向きで残念な感じ。)
  • jit.gl.multiple に Rotate Array を指定できるので、jit.genなどで回転を考慮した処理を書けば、パーティクルを回転させら模様。
  • デフォルトのパーティクルシステムは、レファレンスを見る限り機能が少ない。ただしjit.p.shiva / jit.p.vishnu 自体は、32個までプレーンまで対応しているので、6プレーン以降に回転 / スケール / カラー などを保存してイジる処理を入れれば多機能なパーティクルシステムを実装できそう。
  • jit.gl.multiple を使って描画する場合には、寿命が無くなったパーティクルの描画をしないよう注意。
  • jit.gl.multiple & アルファチャンネル描画する場合は、オブジェクトの @depth_enable 0 @blend_enable 1 を設定。しないと、四角形の枠がでて酷い描画になる。

上記パッチを作るに辺り、ニコニ・コモンズのの素材を利用させて頂きました。今後、回転も考慮した桜パーティクルシステムを実装してみたいと思います。

パーティクルシステム テストパッチ

スクリーンショット 2014-07-02 18.30.10

jit.gen のコード (jit.p.vishnuに接続)

スクリーンショット 2014-07-02 18.26.11

jit.gl.multiple + アルファチャンネル無しのテクスチャ パーティクル

スクリーンショット 2014-07-02 16.59.29

透過を使わない場合は、depth_enable 1 で立体的なパーティクルが利用できる。画像は、NC帝國によるハンバーガーアイコン。1000個くらいが限界っぽい。

jit.gl.render によるプリミティブなパーティクル

スクリーンショット 2014-07-02 16.04.08

jit.gl.render のプリミティブな描画(Lines / strip) であれば、1万パーティクルで60fps近くで動作。


jit.gl.multiple と jit.gen を使って、 jit.gl オブジェクトを複数個描画 #maxmsp #jitter #gen

スクリーンショット 2014-06-21 5.32.03

jitterを使う上で避けては通れない、matrixとjit.gl.multiple(と、たぶん jit.meshも)を、そろそろ本腰入れて使って見ようと思いテストしてみました。jit.gl.videoplaneの動画をjit.genによるjit.matrixとjit.gl.multipleで大量に描画しています。

パッチ

スクリーンショット 2014-06-21 5.32.30

multiple の @targetname で複数個描画したいオブジェクト(今回は、jit.gl.videoplane)を名前で指定する必要があります。また、描画するオブジェクトのアトリビュートで @automatic 0 にしておかないと、コイツが別途描画されてしまいます。

jit.gen code

スクリーンショット 2014-06-21 5.32.33

メモ – jitterのパーティクルについて

jitterでパーティクル処理をするためには、個々のオブジェクトの状態をmatrixで保存するようですね。jit.genを使えばパーティクルを軽量かつ大量に描けるようです。ただjit.gen自体は、jit.gl.pixと違ってGPU処理では無く、CPU処理のコードにコンパイルされるので、jit.shivaなどのデフォルトのパーティクルオブジェクトと比較して、パフォーマンスがどうなのかは今度検証してみたいです。


jit.gl.pix を jit.gl.lua 内で利用する

スクリーンショット 2014-06-06 16.27.18


autowatch = 1
gc = 1

local mov = jit.new("jit.qt.movie",this.drawto)
mov.adapt = 1;
mov:read("bball.mov");

local frame = jit.matrix();
local plane = jit.new("jit.gl.videoplane",this.drawto);
local pix = jit.new("jit.gl.pix",this.drawto)
pix.gen = "aer.line.genjit"; -- readでは無く、genでファイルを読み込みます。
 

function draw()

    mov:matrixcalc(frame.name,frame.name)

    pix:jit_matrix({frame.name})
    pix:draw()

    plane:jit_gl_texture(pix.out_name)
    plane:draw();

end


jit.gl.lua で jit.gl.slab シェーダーをかけるサンプル:#jitter #max6

スクリーンショット 2014-05-28 22.31.18

jit.gl.luaの内部で、シェーダーをかけるサンプルを書いてみました。


autowatch = 1
gc = 1

local mov = jit.new("jit.qt.movie",this.drawto)
mov.adapt = 1;
mov:read("bball.mov");

local frame = jit.matrix()

local plane = jit.new("jit.gl.videoplane",this.drawto);
plane.scale = 0.8
plane.automatic = 1;

local slab = jit.new("jit.gl.slab",this.drawto)
slab.file = "td.kaleido.jxs";
slab:param("div",4)

function draw()

mov:matrixcalc(frame.name,frame.name)

slab:jit_matrix({frame.name,frame.name})
slab:draw()

plane:jit_gl_texture(slab.out_name)
plane:draw();

end

ちなみに初めは、jit.gl.pixを使おうと思ったのですが、.genjitを読みこませようとすると

jit_xml_document: error reading file at byte offset 0 / not well-formed (invalid token)

というエラーがでてしまい、上手く読み込ませる事ができなかったです。


jit.gl.lua 内の jit.gl.videoplane へ jit_matrix の入力からテクスチャを貼る : #max6 #maxmsp #jitter

スクリーンショット 2014-05-14 3.17.17

解説

function jit_matrix(name)

    plane:jit_matrix(name);

end

緑線(jit_matrix)をjit.gl.luaにそのまま繋げる場合のコード。

function tex(...)

    local jit_matrix = {...}
    plane:jit_matrix(jit_matrix[2])

end

texをprependして,tex関数をコールした場合のコード。可変長配列で受け取ると2番めの要素にjit_matrixの名前が入っています。

緑線(jit_matrix)は、単に{ “jit_matrix” , jit_matrix の 名前 } のリストを送ってるだけなんですね。

コード


autogarbage = 1
autowatch = 1
gc = 1

local plane = jit.new("jit.gl.videoplane",this.drawto);
plane.blend_enable = 1;
plane.blend = "alphablend";

--1
function jit_matrix(name)

    plane:jit_matrix(name);

end

--2
function tex(...)

    local jit_matrix = {...}
     plane:jit_matrix(jit_matrix[2])

end


jit.gl.lua 内でjit.qt.mov + jit.gl.videoplane を使ってテクスチャを描画 : #maxmsp #jitter #max6

スクリーンショット 2014-05-12 17.55.48

 

Lua内でJitterのオブジェクトを使ってテクスチャ描画しよう!Lua以外は、jit.gl.* 系 で使ういつものパターンです。

結果

スクリーンショット 2014-05-12 17.54.52

解説


local mov = jit.new("jit.qt.movie");
local plane = jit.new("jit.gl.videoplane",this.drawto)

jitterのオブジェクトをインスタンス化します。jit.qt.movieは、pngを読み込みテクスチャに変換できます。jit.gl.videoplaneは、テクスチャを使って描画をしてくれます。


mov.adapt = 1
mov:read("cobalt_logo_sun.png")

ここではファイル名を指定して画像を読み込んでいます。luaにおけるオブジェクトのメソッド呼び出しは、 :(コロン)でプロパティは.(ドット)のようです。

 


local frame = jit.matrix(4,"char");
mov:matrixcalc(frame.name, frame.name)

plane:jit_matrix(frame.name);

jit.gl.videoplane へ jit.qt.movieのテクスチャの流し込み方になります。直接テクスチャを渡せれば良かったのですが出来なくて、一旦、jit.matrixへテクスチャを描画 (mov:matrixcalc(frame.name,frame.name)し、それをplaneへマッピングしています。jitter系のオブジェクトの受け渡しは、名前でやってるのが理解できます。(内部的にはポインタ渡してるのかな?)

コード

autogarbage = 1
autowatch = 1
gc = 1

local mov = jit.new("jit.qt.movie");
local plane = jit.new("jit.gl.videoplane",this.drawto)

function scriptload()

 mov.adapt = 1
 mov:read("cobalt_logo_sun.png"); 

 local frame = jit.matrix(4,"char");
 mov:matrixcalc(frame.name, frame.name)

 plane:jit_matrix(frame.name);
 plane.blend_enable = 1;
 plane.blend = "alphablend";

end

local rotate = 0;

function draw()

 plane.rotate = {rotate,0,0,1};
 rotate = rotate + 2;

end

jit.gl.lua の勉強は参考文献が少なくて中々はかどりませんが、jitterオブジェクトをガンガン使えるようになると、また世界が広がりそうです。(テキストのコーディングが増えたら、oFとかUnity使ったら良いんじゃないかという話にもなりそうw)


jit.qt.movie & jit.gl.videoplane で透過PNG/MOVを扱う時のメモ : #maxmsp #max6 #jitter

スクリーンショット 2014-05-09 23.01.50

jit.qt.movie

  • jit.gl.videoplane へ マトリクスを送るときに @adapt 1 としておくと元の解像度で出る

jit.gl.videoplane

  • @blend_enable 1 @blend alphablend  @depth_enable 0 :鉄板の設定
  • @automatic 0 : jit.gl.*は描画順が謎なので、bangで直接指定する。

透過MOV

  • Hapというコーデックがアツいらしい

jit.gl.lua の出力に jit.gl.pix をかける : #maxmsp #max6 #jitter

スクリーンショット 2014-05-08 23.44.12

jit.gl オブジェクトのTIPSです。表題の通り、jit.gl.luaの出力にjit.gl.pixのエフェクトをかけたかったので、やってみました。jit.gl.luaのテクスチャ出力をゲットするのが少し難しかったです。

やり方

  1. 一旦 jit.gl.node へ jit.gl.luaを描画。※ jit.gl.luaの出力から青線( gpu上のtexture? ) を直接取得できなかったためです。他にやり方はありそうですが・・・
  2. jit.gl.node のアトリビュート @capture 1 にしておくと、第1outletからtexture出力(青い線)
  3. jit.gl.pix でテクスチャに画像処理
  4. jit.gl.videoplane にテクスチャを貼り付け
  5. jit.gl.render で jit.gl.window へ描画

補足 – Syphonを使う場合

jit.gl.*の描画をSyphonへ送る場合も、テクスチャかマトリクスをjit.gl.syphonserver送る必要があるため、上記の方法でluaで描画したtexture取得すると良さそうでした。jit.gl.renderから直接@matrixout 1 / @capture 1などしてマトリクスかテクスチャ取得出来た気がするけど、何故か上手くいかなかったです。


jit.gl.videoplane 透過PNGを扱ってみる

スクリーンショット 2014-03-19 12.35.26

Jitter の  jit.gl.videoplaneで透過PNGを使うときのポイントです。上図では、2つのjit.gl.videoplaneを利用し同一平面上に透過PNGを重ねて表示しています。

ポイント

  • blend_enableをチェック。チェックをしないと透過されない。またblend は alpha blend に設定。
  • 透過PNG同士を重ねたりしたい場合は、depth_clear をチェック。

blend_enabled 例

スクリーンショット 2014-03-19 12.35.36

左側は blend_enabled をチェック。右側はblend_enableをOFFにしています。右側は透過処理が出来ていない事が確認できます。

depth_clear 例

スクリーンショット 2014-03-19 12.43.32

depth_clear をオフにした状態です。上手く重なり部分の表示が出来ていない事が確認できます。重なり合う2つのjit.gl.videoplaneに対して depth_clearを指定して置いた方が良さそう。

サンプルパッチ

スクリーンショット 2014-03-19 12.35.41

このような設定はOpenGLが分かって人にとっては基本的な事のようですが、いきなりJitterのglから入ると謎すぎる!jit.gl系扱う時はOpenGL1.0~2.0のテキストで一旦 OpenGLのお作法を学習した方が理解が早そうです。