Cycling74 Max で GLSL1.2 を使ったシェーディングをはじめよう #maxmsp #jitter #glsl

スクリーンショット 2014-08-04 16.08.30

シェーダがあるでは無いか!

Maxを使ったインタラクティブアプリケーションの開発は、音や音楽とのインタラクションや、Ableton Liveとの連携、コンパイルしないで変更を加え続けられるリアルタイム性など、他には無い独自なメリットが色々とあると思います。

しかし3Dの描画に関しては、OpenGLの対応バージョンが2.0止まりな事もあり、openFrameworksやUnity等の開発環境と比べると少し見劣りします。とはいえ、プログラマブルシェーダを利用する事ができるので、可能性としては例えばSIGGRAPHの論文を実装して最新のレンダリングもできるのではないかな・・・!?

そこで今回はMaxの3D描画を強化するべく、jitterに関するGLSL周辺の調査とサンプルプログラム試してみました。

Maxにおけるシェーダについて

  • JXSファイル:XML形式でMaxとやりとりを行うパラメーター等を記述するファイル。またGLSL等のシェーダをこのファイルに読込むか直接書く事でシェーダを利用する。.jxsファイルで保存したらjit.gl.shaderとjit.gl.slabでreadして使う。
  • シェーダの種類:Vertex Shader / Geometry Shader / Fragment Shader が利用可能
  • シェーダ言語:GLSL1.2 / CG / ARB
  • 豊富なサンプル:Mac版のフォルダパス→ /Applications/Max 6.1/Cycling ’74/jitter-shaders Geometry ShaderやGPGPU、Audio処理用のシェーダも。ジオメトリシェーダを使う際は、プリミティブの種類がシェーダと合ってないと利用できないので注意。
  • Cycling74 Forumでは、GLSL1.5(OpenGL3)そうとうのシェーダーが使えるという記述がありましたが、私の環境(Macbook Pro Retina / Mavericks)では利用できませんでした。
  • jit.gl.pix:フラグメントシェーダのみに特化したオブジェクト。jit.gl.slabと互換。

jit.gl.pixでは使えないバーテックスとジオメトリが鍵になりそうな気がしますね。今後の記事でサンプルファイルなどを紹介できればと思います。

JXS / GLSLサンプルコード

<jittershader name="mrr-test-simple">
	<description>
	test
	</description>

	<language name="glsl" version="1.2">
		<program name="vp" type="vertex">
<![CDATA[

#version 120 

void main(void)
{
	vec4 clipCoord = gl_ModelViewProjectionMatrix *gl_Vertex;
	gl_Position = clipCoord;
	gl_FrontColor = gl_Color;

	vec3 ndc =clipCoord.xyz / clipCoord.w;

	gl_FrontSecondaryColor = vec4((ndc *0.5) +0.5,1);

	//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
]]>
		</program>
		<program name="fp" type="fragment">
<![CDATA[

#version 120

void main()
{
	//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
	gl_FragColor =mix(gl_Color,vec4(vec3(gl_SecondaryColor),1.),1);
}
]]>
		</program>
	</language>
</jittershader>

上記画像は、jit.gl.shaderに上記JXSファイルを読み込ませて、jit.gl.gridshapeとjit.gl.multiple で作ったモデルに対してアタッチして生成した画像です。glsl部分は、外部ファイルを読込む事も可能です。

参考サイト


jit.gen vs jit.gl.pix Vetex Array 生成対決:#max6 #maxmsp #jitter #cycling74

スクリーンショット 2014-07-16 0.43.34

フォーラムに似たようなスレッドがありますがMaxにおけるGPUとCPUの対決です!球体のVertex Arrayをjit.gen / jit.gl.pix の両方で生成できるパッチをつくりました。それをjit.gl.meshへ入力し上記のような画像を生成します。

実装

スクリーンショット 2014-07-16 1.02.34
jit.gl.pixはGPU上の処理でVertexの配置を保持したテクスチャを生成しますが、そのままjit.gl.meshへの入力へは使えません。まずはjit.gl.pixの出力をjit.matrixに入力する事で、CPU側のメモリにGPU側のテクスチャを呼び戻します。jit.gl.pixはplane数が4に固定されています、ARGBですね。なので次にjit.genを使ってplane数を3に削減してjit.gl.meshに入力できるplane数に変更しています。ちなみにこのplane削減処理は、jit.unpackでも出来ますが、jit.genのswizを利用した方が多少早かったです。こうして、GPU計算したVertexをjit.gl.meshの描画に利用できます。

それではMaxにおけるCPU vs GPUの対決やいかに・・・!

結果

fps(@sync 0) : jit.gen 100fps / jit.gl.pix 70fps
CPU使用率 : jit.gen 140% / jit.gl.pix 60%
※アクティビティモニタで目測

jit.gl.pix(GPU)はfpsが伸びなかったです。代わりに、CPU使用率が下がっていますね。これはMSPと共存させるような方には良いかもしれません。ただ描画速度やパーティクル数を稼ぎたい場合は、jit.gen(CPU)を使う方が良いみたいです。というかjit.genは、シェーダーのように並列演算しやすい形で記述するので、裏でCPUの並列計算をするようになっているそうです。

TIPS

スクリーンショット 2014-07-16 0.45.17

  • jit.gl.pix dimの最大値 16384 か?それ以上の値になると表示がバグる
  • jit.gen / jit.gl.pix 内部で使えるプリミティブ(circle,sphere,torus等)楽しい

Sample Patch


----------begin_max5_patcher----------
2043.3oc6bssjahCD8Y6uBJp8wYmEIw08or09YLaJWXirsR3hWPdtjT40848
ab+RVcAvfMfkIXMdRlIULwR.p6S2p0oUqIec9LykYOiKLM9ciGLlM6qymMSz
DugYkeelYR3yqhCKD2l4prjDbJ07NYeT7yTQ6ehPueCN03wBCw+L99cjmM9q
zkuX7gDRddV9xrWpdpXRJdU19TwiBKajDIdQYK+zuhPU245rT55vUXdWnx1R
2mPRiwTg.AZbiEjuHtQn88VUMmuYIuIq5V1ERWskjtYQNdEUp4PeVuFPG9mH
fG+hK6AL93gALaOsZDsZLhogIhQz7OxIgwl7N91747OtSQ7jlsYSL1rCL.T0
nbrourCKEWSBG393PnQGJIJ.cuSkVBfA0W5QMO7pxYJIEmu.mFtLVHCViPQ6
yw4+9m+8O2FltAaT4B8aM7f5.Xf1lp5H.fWli.xCJvHaj.cbrD9E5xUX4dJM
KsKMF1qqvRFxc49BPeg4GU53eN0DLoJi0TqLHv0VYRwOwD89h40gRBb5UIYO
zhjPZN221v7LpaONyc45xPAlqKxVfBRG3APAX+dtMGCbdIpTBKrGfDieDmWP
XF2CB5Lyvc6Zz7rFOBGK+Tl3E4dWcSjTYSf5lxwORpddu5VCyYZJkol6ykB4
y9tlxNY1u4UOZsyfvw1U9okvWv1oALvrzaVkEKG6GXQCBtqwGf12Xb1pOiiZ
LQmYN2gSIo6xwErXYgzRwst6H75v8wzEca2Z2e0xZc1Ym1jYlaxIQYobgn0S
xatZ3dfE2RF8poxHtizvcc7vEL8XewxvbN7WFfGV0IMKKtcW0Vb1TlvTByUF
SIRgEZU+RII6xIx02qaSt9w1hU4YwwsdUxddridhXNEqvOQhnaaE8l2C61I6
pLAl0XTDYCtf1tMZ3lh1szh3SSu0lwBZ09PwDZGWn3IxWL3q2znyFAGbZ19I
wGpiHzaTgAhLzWzAGQHRG4zBmiiMz+p+Cs51rp3nkyEmdbjjZ.5ACAiECsFO
FJhl.rEK1X8VACYxSufns4UvSShRVRxzdJ.SVWLLcHrFOQhdlEKjMd+cieEY
6yWU4uTNqznsXxhvPIo0A4enFzN591RhhZGSUFFpfGTKplu7Ys0WpDCTThcl
HI13iyOzxzwfphLzojnPuVjnjjHcbFOIpIkwbvjS+Wleis80iw79jkLxicXT
cGLs16TRmt.KpU.2hVFO5rIzAGJo2I0Z2yDhcgelMW0pq8CnWbqGvBNZvR5W
bVvBLo.xFFqIlDA6ZBP+aER6o+kLNACAGco2.wzdnb4JTYtwiyIYhytruMAA
.GL13l3E72COmoqP7QXfUiMQ5mvrLAPWnH0R+2Sz78DMeESzbGatCdboHc2U
JUSnHHpmbanTg+O7FOUSG8mpoDCQtBLz98TMGBk.xB17iXplf2boZZeCjpYB
tnHbC9D9Tq2GGyhjiwoF+BnKVlNSBCaz4qznsmy8PGTfk6cF9Rm3.Mwxt2xM
Bcm1xMVponCZJT07Itx7p2YvVPuKDvaLoYacw9.LVhNsQFaAYRHXL9.usqVi
Sip0XKIQ6a8N2324FqHaD4bjd3b3qDmiNicI4bAsObtPfNJyrn5jNHTU8P8p
.GaTG+5j.aCRfUDaa3jAfimhlDIAR1YmVU5a0zA9L9kQkUU4VXd5kqRVBkfK
vpr3dNmEbsuMH.CUjNo+aNBvvol.b456EgOhiVvFAl0eQHklSVtmJMGMWu+6
cosyuz4EDuuSgXfAuuAkQAXYXbICm5msikUtJkm5IRZT1SFkW9v5BVr88rUi
Yl4OvkVNwEVp5rusLKOBma.32TXHu+127Koq5bm8A9CS7bJ2AWIsbGKuZxmN
.jVKyE24cOoCXv18Ry+5xUe.nLArC5OP45bvkbYk5DFZyIEV3tZq2UroSnAp
X8OlDmCjkvgvW.KHGM4VLbQPX4zusdJX3dZFiwKYEepFMOLsXcVdxBd5.TdS
EIYYzsKJ1FFwzO9TO9SrPra7E06PU6CgLpiok1eekeN3xweawwOE4KYb5Aq1
C0WaKPZFo.afLVGmERQPlKhE+ucEKCn8Z1aUR7Q37Bbc0ZzrK9jgFna7ozop
rlc9veRKYW.BJKtqy6Ur68ck31rhcAuNUrq7H6I8M9gnjcduVmNTuxvJuWxt
Ac0bQu0JYWvatSGpmhRbvs8oCkQ9OGmxyqth9eu4Qq8zngtxh24ZeKv4jZrT
7GbdXQWU3y6rvywWkuoIFyjaptm2YfLac.Y+cBllmYzU0fsGSw.giDT.xcx0
0Qqm3xdqEry0nTv.anZm1X8TEXVlrQR+748sE+i53VewldKmpeei0nou2MgS
C6AmmeiM4XD69VTd3SKRxhvl5ARf9WeLo5jWKO1bvytkrmBJjD0fCwKrMyHI
5bL+hRLZXlP8UEDqV2zIDJNkLwIFqoTb.1ZSb7UAczlz3ofz3qUoA8cJMIjn
cYrUgJcdCbj+eZP0usYUe4vnLoRO7bV1fKS78buG3x9wlK1vJl.H1O1c2D.I
oZFH1SOw2tBpp6s0bJGEDG8IM1JgN5aVksBhim1jFDPk.f.8IOpHN5yXAUZ4
J8AOP+aL4QkUrft5SdTYxNzQexiysUvGnJS2Czq3.NG7nO9W.UbeP2dhC31Q
bf5y6AnxjKH71RdzHOLfJKlBzWvvilH2i7nwoWJy8QSyuTPbFq0RtMBGUaet
fbTM8Opd9mVK+9piOab917+GE2s8X
-----------end_max5_patcher-----------

jit.gl.pix を使ったテクスチャパーティクルの描画:#jitter #max6 #cycling74

jit.gl.multiple が重いのでは?という仮定の元、jit.gl.pixを使ったパーティクルの描画を前回試してみました。今回は、その続きでテクスチャ付きの画像をjit.gl.pixで描画してみました。jit.genで生成したパーティクルの位置をテクスチャとしてjit.gl.pixに入力。ピクセルシェーダーが位置テクスチャを全捜査して、自分が描画対象だったら画像テクスチャからその色を取得し出力。位置テクスチャを全捜査しないで描画する方法があれば良いけど思いつかなかったです。 スクリーンショット 2014-07-15 1.35.50 パフォーマンス的には、解像度720×360 / パーティクル数500 / 20fps 程度という事で大した事無い気もします。アクティビティモニタでMaxを見るとCPU使用率が20%だったのですが、jit.gl.multipleとの比較はしてないので、そのうちやってみたいです。

Continue reading


jit.gl.pix でモルフォロジー処理を実装してみた : #max6 #jitter #cycling74

Before

スクリーンショット 2014-07-11 16.12.13

After

スクリーンショット 2014-07-11 16.12.10

モルフォロジー処理は、コバルト爆弾αΩのΔに教えてもらいました。ノイズを消すにはメディアンフィルターより良いとの事。エッジ抽出などにも使えるようです。アルゴリズムや使い道は、こちらが参考になりました。10個とか重ねて書けてもあまりfps落ちないので、シェーダー凄いっぽい。

CodeBox(モルフォロジー処理(収縮))


delta = 1/(dim+1);

outPix = in1;

for( i = 0 ; i < 9 ; i += 1) { x = ((i%3)-1) * delta.x; y = (floor(i/3) -1) * delta.y; pix = nearest(in1,vec( x,y ) + norm,boundmode="clamp"); outPix = switch(pix < 0.5, pix,outPix); } out1 = outPix;

pix < 0.5 を pix > 0.5 にすると膨張処理に変わります。

Max Patch

スクリーンショット 2014-07-11 16.22.09

Continue reading


jit.gl.pix でラプラシアンフィルターを実装してみた:#max6 #jitter #cycling74

Before-特大ゆっくり魔理沙(ニコニ・コモンズより)

スクリーンショット 2014-07-09 19.54.20

After ラプラシアンフィルターによるエッジ抽出

スクリーンショット 2014-07-09 19.54.12

メディアンフィルターに引き続き、ラプラシアンフィルターによるエッジ抽出をjit.gl.pix実装してみました。

jit.gl.pix – Codebox


//laplacian
filter = vec(0,1,0,1,-4,1,0,1,0);

//sharp
//filter = vec(0,-1,0,-1,5,-1,0,-1,0);

//mean
//filter = vec(1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9);

//mean2
//filter = vec(1/16,2/16,1/16,2/16,4/16,2/16,1/16,2/16,1/16);

//mean3
//filter = vec(1/3,0,0,0,1/3,0,0,0,1/3);

//sobel
//filter = vec(-1,0,1,-2,0,2,-1,0,1);

step = 1/(dim+1);

d = (vec( 0 % 3 , floor( 0 /3)) - 1) * step;
p0 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 1 % 3 , floor( 1 /3)) - 1) * step;
p1 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 2 % 3 , floor( 2 /3)) - 1) * step;
p2 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 3 % 3 , floor( 3 /3)) - 1)* step;
p3 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 4 % 3 , floor( 4 /3)) - 1) * step;
p4 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 5 % 3 , floor( 5 /3)) - 1) * step;
p5 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 6 % 3 , floor( 6 /3)) - 1)* step;
p6 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 7 % 3 , floor( 7 /3)) - 1)* step;
p7 = sample(in1,norm + d,boundmode="clamp");

d = (vec( 8 % 3 , floor( 8 /3)) - 1)* step;
p8 = sample(in1,norm + d,boundmode="clamp");

sum = p0 * swiz(filter,0)
     + p1 * swiz(filter,1)
     + p2 * swiz(filter,2)
     + p3 * swiz(filter,3)
     + p4 * swiz(filter,4)
     + p5 * swiz(filter,5)
     + p6 * swiz(filter,6)
     + p7 * swiz(filter,7)
     + p8 * swiz(filter,8);

out1 = sum;

一番上のfilterの初期値を変える事で、いくつかのフィルターを試せるようにしてあります。

おまけ – jit.gl.pix の困ってるポイント

  • sample / nearest を function や for 文で、取得する位置を変更しながら繰り返し利用するとコンパイル通らない。
  • sample / nearest から取得した pixcel から swizしようとすると(例 : swiz(vec,0) ) コンパイルが通らない。
  • function と Param を同時に定義するとコンパイル出来ない事がある。

jit.gl.pix でメディアンフィルターを実装してみた:#max6 #jitter #cycling74

Before

lena noise

After – 3×3 メディアンフィルターで処理

lena median

ノイズが載った画像を綺麗にする必要が出てきたので、jit.gl.pix のシェーダーを使ってメディアンフィルター(Median Filter)を実装してみました。下の画像は、上記のノイズ画像をメディアンフィルターで処理した結果です。結構凄い!

jit.gl.pix で実装する上でのポイント

メディアンフィルターのアルゴリズムは、こちらにある通り、近傍の画素値を拾ってきて、並び替えた上で中央値を採用するという単純なものです。例えば、3×3で行うと中央のピクセルに対して周辺と自分を含めた9つの画素値を、明るさで並べ替えて、4番目の値を出力すればOK。

しかしjit.gl.pixでは実装に問題がありました。for文を使って近傍画素を取得し配列へ保存したいのですが、配列が使えないです。そのため変数(m0 ~ m8)を9つ用意し、愚直にベタ書きをしました。また並べ替えに関しても同様の問題がありバブルソートをベタ書きしています。

この問題点は、jit.gl.pixの仕様なのか、シェーダーの仕様なのかはわからないですが、非線形な処理を書こうとすると苦労しそうです。もし、簡単・軽量・カッコよく実装する方法があれば、是非教えてください!

jit.gl.pix Codebox – 3×3 Median Filter


sort(x,y){

return min(x,y),max(x,y);
};

xmin = 1/(dim.x - 1);
ymin = 1/(dim.y - 1);

//近傍画素の取得
//0
x = (-1) * xmin;
y = (-1) * ymin;
m0 = sample(in1,norm + vec(x,y),boundmode="clamp");

//1
x = (0) * xmin;
y = (-1) * ymin;
m1 = sample(in1,norm + vec(x,y),boundmode="clamp");

//2
x = (1) * xmin;
y = (-1) * ymin;
m2 = sample(in1,norm + vec(x,y),boundmode="clamp");

//3
x = (-1) * xmin;
y = (0) * ymin;
m3 = sample(in1,norm + vec(x,y),boundmode="clamp");

//4
x = (0) * xmin;
y = (0) * ymin;
m4 = sample(in1,norm + vec(x,y),boundmode="clamp");

//5
x = (1) * xmin;
y = (0) * ymin;
m5 = sample(in1,norm + vec(x,y),boundmode="clamp");

//6
x = (-1) * xmin;
y = (1) * ymin;
m6 = sample(in1,norm + vec(x,y),boundmode="clamp");

//7
x = (0) * xmin;
y = (1) * ymin;
m7 = sample(in1,norm + vec(x,y),boundmode="clamp");

//8
x = (1) * xmin;
y = (1) * ymin;
m8 = sample(in1,norm + vec(x,y),boundmode="clamp");

//バブルソート
m0,m1 = sort(m0,m1);
m0,m2 = sort(m0,m2);
m0,m3 = sort(m0,m3);
m0,m4 = sort(m0,m4);
m0,m5 = sort(m0,m5);
m0,m6 = sort(m0,m6);
m0,m7 = sort(m0,m7);
m0,m8 = sort(m0,m8);

m1,m2 = sort(m1,m2);
m1,m3 = sort(m1,m3);
m1,m4 = sort(m1,m4);
m1,m5 = sort(m1,m5);
m1,m6 = sort(m1,m6);
m1,m7 = sort(m1,m7);
m1,m8 = sort(m1,m8);

m2,m3 = sort(m2,m3);
m2,m4 = sort(m2,m4);
m2,m5 = sort(m2,m5);
m2,m6 = sort(m2,m6);
m2,m7 = sort(m2,m7);
m2,m8 = sort(m2,m8);

m3,m4 = sort(m3,m4);
m3,m5 = sort(m3,m5);
m3,m6 = sort(m3,m6);
m3,m7 = sort(m3,m7);
m3,m8 = sort(m3,m8);

m4,m5 = sort(m4,m5);
m4,m6 = sort(m4,m6);
m4,m7 = sort(m4,m7);
m4,m8 = sort(m4,m8);

m5,m6 = sort(m5,m6);
m5,m7 = sort(m5,m7);
m5,m8 = sort(m5,m8);

m6,m7 = sort(m6,m7);
m6,m8 = sort(m6,m8);

m7,m8 = sort(m7,m8);

//中央値の出力
out1 = m4;

参考

上記画像は、画像処理の分野で良く使われているLenaという女性の画像です。


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

※編集中 スクリーンショット 2014-07-07 21.25.02

Rotate planeの追加

パーティクルに回転処理を加えたいという事で、前回調べた結果パーティクルを格納するmatrixに対して、rotate の値を管理するplaneを実装する必要がありました。 plane数を6にして、6番目の要素をrotateとする事にします。ただし、受け付けられるplaneがjit.p.shiva は 5か8 jit.p.vishnuが5と限られているため、拡張したmatrixを単純にjit.p.vishnuに突っ込めないです。そのためにはjit.matrixのplane数を調整するために jit.unpack / jit.pack を駆使して、分割したMatrixに対して処理を書く必要があります。

jit.p.shivaの初期化タイミングを取得する

回転の初期化をするのも問題がありました。初めは回転の初期化をするタイミングをLifeの値を見ることで、取得しようとしました。

jit.p.shivaでパーティクルが生まれた瞬間Lifeの値が0以外の数値に埋められるのですが、この値が何故かmatrix row 1 の pre  の要素も初期値が入れられてしまって、preのnowの要素を比較してパーティクルが生まれた瞬間を取得できません。(クソい)

解決方法としては、jit.p.vishnuに指定するアトリビュートであるlifeを、回転処理をするjit.genにも与えて、lifeが最大値の時を初期化タイミングと見なして、回転の初期化をするようにしました。 そうしてめでたくRotateの初期値にバラつきをもった状態ができるようになりました。

Maxのパーティクルシステム面倒くさすぎて、貧弱すぎじゃないかと思ったり・・・。 スクリーンショット 2014-07-07 21.03.03 加えて前回のパッチでは、パーティクルの描画オブジェクトである jit.gl.multiple に matrix row 1 (row 1 には、パーティクルの1フレーム前の状態が含まれている)も与えていたため、2重に描画してしまっていました。今回は、jit.scissors により row 1 を切って row 0 のみ渡しておりパフォーマンスがUPしました。といっても1000パーティクルでフレームレートが30fps程度でした。

NC帝國によるシンリャク君ロゴ

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

いきいきナードコア感謝祭’14

スクリーンショット 2014-07-07 21.09.59 VJで参加させて頂いた いきいきナードコア感謝祭’14 ナードコアの開祖・神々のプレーを拝めて、非常に興奮しました。コバルト爆弾αΩなんかは、とてもナードコアに影響を受けているので、今後の活動を考える上でも良かった。VJ的には、カッカのアニメVJにアニメ的なエフェクトを載せてみようということで集中線や♡等を散らしました。今後もうちょっと演出を詰めていくとアニメ的な演出を解体・再構築したようなVJが出来そうで、個人的に面白くなりそうでした。


ロジスティクス写像を使ったジェネレ−ティブVJ : #max6 #jitter #cycling74

ジェネレ−ティブなVJの方々って、どうやってノイズと関数の中間みたいな画像を次々につくりだしてるのか。時々疑問に思っていました。ふと、ロジスティクス写像なんかの変数をちょっといじると値の収束する場所が次々に変わるような、カオス理論の本などで出てくる数式を使ってるのかなと思い、簡単そうだったので実装してみました。

結果、単なるrandom乱数だと難しそうな値を取得できていると思います。割りと似たような画像が良くでてきちゃったり、あまり音との連動性が良くないので、もう少し工夫が必要そうですが。

jit.gen コード
スクリーンショット 2014-07-05 8.53.01

ロジスティクス写像の数式は、Wikiのカオス理論に載って要る通り、とても簡単です。

再帰呼び出しをして実装しようとしたのですが、jit.genではコンパイルが通らなかったのでfor文にしています。jit.gen のエラーコードは、glslとluaのエラー(っぽいの)が生で出てくるので原因が全然分からない。Param aの値に音量をぶち込んで音との連動を試みています。実装間違っていたら教えて下さい(笑)

カオス理論で使われる数式は、他にも色々式があるみたいです。次はローレンツ方程式を試してみたいです。


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)

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