jit.pix内部のfaderという変数をイジれるようになってる。
jit.pixの中身
gen subpatcherはgen @gen *** で指定。またパラメーターをイジる場合は、setparamを使用する。ちなみにparamは外部公開する変数。
gen subpatcherの中身
外部からイジるパラメーターはparamで指定。
あのタグで待ってるをMax7に対応させようと改良しています。Max7化のポイントは、jit.movieから直接GPUに動画テクスチャを送る機能を使ったパフォーマンスアップです。
ただし、問題がありました。jit.gl.pixの解像度が、第一インレットに入力される解像度に固定されてしまうという点です。これの何が問題かと言うと、VJソフトは16:9や4:3等の異なるアスペクト比や、HDやSD画質など異なる解像度を持つ動画を次々に切り替えて再生するので、そのままでは最終出力の解像度やアスペクト比も次々に変わってしまいます。横長の間延びした動画になってしまったり、SD解像度にHD画質の動画がひっぱられて解像度が落ちてしまったり。
そこで今回は、上記の画像のように16:9の画面に4:3の動画を、指定した解像度で出すのが目的となります。
ポイントは、jit.gl.pixの第一インレットに解像度を指定するMatrixを入力する所です。これを使ってjit.gl.pixの出力を常に同じ解像度に固定します。また第二インレットに jit.movie @output_texture 1 で取得した動画テクスチャを入れます。この動画テクスチャのアスペクト比を保持するために、解像度を別途jit.gl.pixに入力してあげる必要があります。なぜならjit.gl.pixでは、in2に入力したテクスチャから直接dimを取得できないためです。param dim2 としてパラメーターを与えています。
ちなみに動画テクスチャの解像度をjit.movieから取り出す際に、dimメッセージで取得すると正しい値が取れないので、getmoviedimを使いました。
in1に入れたマトリクスは、全く利用しません。あくまで解像度を固定するために入力しています。テクスチャのアスペクト比の調整は、右側のコードで行って、最終的にin2の動画テクスチャをsampleオブジェクトで取り出します。
指定した解像度とアスペクト比にする事は出来ましたが、まだ問題があります。上記画像を見ると、左右領域にゴミが残ってしまっています。本来ここの領域は真っ黒にしたいのです。この原因はjit.gl.pixの内部でsampleのオプションを@boundmode clampにしているためです。@boundmodeはいくつか指定があるのですが、他のwrapやmirrorでももちろん駄目でした。指定した領域にテクスチャが無い場合に単純に黒くするオプションが欲しい所・・・。自分で黒く塗るプログラムを追加するのが解決策になりそうですが。
動画の縁まで色が付いていると、こんな感じになってしまいます。
size = 10;
offset = floor(size/2);
scale = 1/(dim+1);
pix = 0;
for(x = 0 ; x < size ; x = x + 1){
for(y = 0 ; y < size ; y = y+1){
delta = (vec(x,y) - offset) * scale;
pix = pix + sample(in1,norm + delta,boundmode="clamp")/(size*size);
}
}
out1 = pix;
jit.mgraphicsで描画したSVGに透過色を持たせたい場合には、jit.gl.pixで特定の色を透過させる処理を書くと良さそうです。上の画像は、カメラのキャプチャにSVGの描画を載せたサンプル。棚がとっ散らかってますが、お気にせず・・・
svgでピンクの丸を描画してます。ちなみにillustratorでSVGをつくりました。(左側に、ちょっと、余分なコードも入ってますがお気にせず。)
厳密に言うと、黒に近いほど透過されるコードに成ってますが、とりあえず目的に適うのでオッケーです。
----------begin_max5_patcher----------
757.3oc0WssahCCD84juBK+LKxNAnj8s86.UgLItgoqwNxwbYaU+2WamKjvF
pnkVDqPJANy3wGe73gwuFFfWoNvKwnehVfBBdMLHvC4.Bp+c.dC6PpfU5cCK
46UqdFOpxjgev3geFLiyEiKfCn8fLSsuwimTRSI7B24EMZLoFVs0H3FyeJ3U
StK.KyEKcAbqliGgvXzi0NK2tAjV28LfdDrJHdznZzBlIcMHyWp4olpPGSlZ
mVTzL+qjI9ePFSZCuihR1FOSv+RCLQC4gLOlcA+C5Lb2ofqq0nZQxFEPv2w0
kfR1glAXVQQG3fNCworOq7AZ1nVHPVAQagz7cPy3SZQYZ6B0XWkN4xwxCymg
qL9VXyjeTEhnIN0GQmG6E.5CtWwSiNJD1s97TknZ5WfHiSF04AsuiBU5u4d4
gz.pJ3RPVn4kbogYpYbq4L9SrsByxgyH5a+IVJ+rCdv8p.btFxTRGI5MRGby
zs.Q8IAtmGWLdOjrhAFboccrsbES61AVI3cR0rI+Jknuo1Mc6YHlD1vLbCTQ
1HRaPgMEZPZ5MQbIyFi0koZkPzKTUV1MfkLadQJeOjYV6iUWoz5NTzrEfa0n
LHmWZ5iYX4k8Q5UTnaBa2hC8veuhD8KTTtGdAoyW003YxHFrNQaUgyVYXfpC
csLPEBJweXHwexX5zSKP79EINsPQTDtA+svvluL5qWI2.G9FDw3OqHNm30sI
d4axrqTDo2HQTvk41iO2eIizod8bR7UJjjajPtimhHUe9FTyIeV0Lt5zL0Kl
O7v0IlzjajXBRD8aPEIeVUzVYbpsYApukAxUJh2HMzt5tXQ7BO4RtjJfwj49
WWYt1jgjoi8rH.449KZOyb1GV+JUa0oMIK0+gksEudrz1+fAjssvsnsVxoNt
Fxx52xTUWFktdVp5N7h1s+nbldoTN5+OJ6bjdWP4nKkySteT4jOhLeev4ANW
8NbN5KfynGCOh3eVWa4zaq5n8I2R8jan9u2N8b2L0NOuE9W.Vv2VrA
-----------end_max5_patcher-----------
こういう微妙なコードをBlogに書いとくと、後で再利用しやすいのが良いですね。Max7だと、コードスニペット機能が充実するそうなので、楽しみですな〜。
jit.gl.pixにて@genによるシェーダの切り替えを行うと一瞬画面が止まってしまう事案が発生いたしました。この原因は2つ考えられるかなと思いまして
検証はできてないですが、1の方が原因としては重たそう。というのも、jit.qt.movieでreadするとファイル読み込みで画面が止まってしまう現象と同じなためです。jit.qt.movieではasyncread使うことで再生中の動画を止めずに切り替える事が可能ですね。ただ、実はこれも問題があり、大量のjit.qt.movieに対してasyncreadを指示すると画面止まります。内部的にどうやってるかコード読んでみたい。(関係ないけど、Windows版のMaxの非同期読込もサポートしてほしいな・・・。)余談はさておき、jit.gl.pixには非同期読み込みをするメッセージを送れません!
パッチをロードしたタイミングで使いたいシェーダの数だけjit.gl.pixをインスタンス化しておく。使おうと思った時にはメモリ上に載っているので画面が止まる事は無さそうです。スマートなやり方ではないですが、この方法しかないかな・・・?使いたいシェーダの数が増えるとメンテナンスが大変になりそうなので、jsオブジェクトなどを使ってメタプログラミングでオブジェクトの自動生成をすれば、メンテナンスも楽そうです。やりすぎるとGPUのメモリが足りなくなる事案も発生しそうですが。
ちなみに上記画像は遠藤一郎氏のライブペインティングでプログラムしたときに使ったパッチのキャプチャです。音声ファイルを400個近く読み込む必要があって、ライブ中にファイル読込で止まるのが嫌だったので、起動時に全部メモリ上にロードしておくプログラムをjavascriptで書きました。
あのタグの次期バージョンに入れるトランジションエフェクトを開発しています。例えば、中央から丸が出てきて画面全体に広がるようなエフェクトをつくろうとすると、丸を書いて2つのテクスチャを割当るだけで簡単そうです。しかし、単純につくるとエッジがギザギザしてしまいます。そこでjit.gl.pix(フラグメントシェーダ)におけるアンチエイリアスを実装してみます。
中央の円のエッジがギザギザしており、VJなどで大画面に表示するともっと気になるかなと思います。
現在のピクセルの半径rと、トランジションする円の半径rとの距離をとって、その距離が短い場合に(0~0.005の距離)smoothstepで補間をしています。補完した値でmixする事でエッジをなだらかに繋ぐ事が可能です。ここを単純に書くと大なり小なりで比較して、0 or 1ピクセルの色を指定して、switchやif文でピクセル値を切り替えて出力したくなりますが、それではエッジがギザギザになってしまいます。