2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GLSL】ISFをTouchDesigner上で動かしてみた

Posted at

##■概要
この記事は**「ISF」がまとめられたサイトにあるシェーダーのプログラムコードを、「TouchDesigner」というVJソフトの「GLSL」にぶち込んで動かそう!**ということを書いてます。

ISFとは*「Interactive Shader Format」*の略で、僕も知ったばかりで詳しくないのでググってみたところ、**「GLSLベースのシェーダフォーマット」**らしいです。

TouchDesignerでGLSLを勉強していた時、TDSWのチュートリアル動画から「ISF」なるものを知りました。この動画では触れられていない他のシェーダーもいじってみよう!ということで学んだことを試しにやってみることにしました。

##■動作環境

MacOS:Big Sur ver.11.2.1
TouchDesigner:099 2020 27390

##■試してみる
うまくいくとこんな感じに動きます
ezgif-6-398df4cf8a0c.gif

(ちなみにこの画像は「MINAMI MIYAJIMA」というスクエアを延々と手書きで書きに書いてる人の作品です。いまJITSUZAISEIというただいまクラウドファンディングで60万以上資金調達してるプロジェクトに関わってるんですが,よければ興味持ってください笑 こそっと宣伝です。笑)

では進めていきまする。

###■ISF
まずは、ISFのサイトを開きます。

ISF (Dual Side Scroller And Flip.fs by VIDVOX)
https://editor.isf.video/shaders/5e7a7f767c113618206dde08

開くと、こういう画面が現れると思います。
スクリーンショット 2021-03-28 13.02.58.png

そしたら左側にある**” > ”**のマークを押してください。

するとコードが出てくると思います。これを全部コピーしてください。
コメントアウトの部分も含めてコピーしてください。
スクリーンショット 2021-03-28 13.03.16.png

###■TouchDesigner
タッチデザイナーの方も開いていきます!
開いたら、まずMovieFileinTOPを置きます。そこから右につないでglslTOPを置きます。

とりあえずは以下の画像のように各オペレーターを配置してください。
スクリーンショット 2021-03-28 22.13.35.png

glslTOPの下に出てきたglsl_pixel(DAT)のEditを押してください。

そこにさっきISFのサイトからコピーしたプログラムをコピペします。

// uniform float exampleUniform;

一旦、この辺にコピペ!!!!

out vec4 fragColor;

###●完成形!
ちなみに,最終的なコードは以下のようなものになります。

/*{
  "CREDIT": "VIDVOX",
  "DESCRIPTION": "Mirror slide the top, bottom, left and right sections of the input image. Based on side scroller and flip by Brian Chasalow.",
  "CATEGORIES": [
    "Geometry Adjustment"
  ],
  "INPUTS": [
    {
      "NAME": "inputImage",
      "TYPE": "image"
    },
    {
      "NAME": "slidetop",
      "TYPE": "float",
      "MIN": 0,
      "MAX": 2,
      "DEFAULT": 0
    },
    {
      "NAME": "slideleft",
      "TYPE": "float",
      "MIN": 0,
      "MAX": 2,
      "DEFAULT": 0
    },
    {
      "NAME": "mirrorHorizontaltop",
      "TYPE": "bool",
      "MIN": false,
      "MAX": true,
      "DEFAULT": true
    },
    {
      "NAME": "mirrorVerticaltop",
      "TYPE": "bool",
      "MIN": false,
      "MAX": true,
      "DEFAULT": true
    },
    {
      "NAME": "slidebot",
      "TYPE": "float",
      "MIN": 0,
      "MAX": 2,
      "DEFAULT": 0
    },
    {
      "NAME": "slideright",
      "TYPE": "float",
      "MIN": 0,
      "MAX": 2,
      "DEFAULT": 0
    },
    {
      "NAME": "mirrorHorizontalbot",
      "TYPE": "bool",
      "MIN": false,
      "MAX": true,
      "DEFAULT": true
    },
    {
      "NAME": "mirrorVerticalbot",
      "TYPE": "bool",
      "MIN": false,
      "MAX": true,
      "DEFAULT": true
    }
  ]
}*/



uniform float slidetop;
uniform float slideleft;
uniform bool mirrorHorizontaltop;
uniform bool mirrorVerticaltop;
uniform float slidebot;
uniform float slideright;
uniform bool mirrorHorizontalbot;
uniform bool mirrorVerticalbot;






out vec4 fragColor;
void main()
{
	// vec4 color = vec4(1.0);

	vec2 pt = vUV.st;
	float slide = (vUV.y > 0.5) ? slidetop : slidebot;
	float shift = (vUV.x < 0.5) ? slideleft : slideright;

	bool mirrorHorizontal = (vUV.y > 0.5) ? mirrorHorizontaltop : mirrorHorizontalbot;
	bool mirrorVertical = (vUV.x < 0.5) ? mirrorVerticaltop : mirrorVerticalbot;
	pt.x += slide;
	pt.y += shift;
	vec2 moddedRetard = mod(pt,1.0);
	
	if(mirrorHorizontal && pt.x >= 1.0 && pt.x <= 2.0)
		moddedRetard = vec2(1.0-moddedRetard.x, moddedRetard.y);
	if(mirrorVertical && pt.y >= 1.0 && pt.y <= 2.0)
		moddedRetard = vec2(moddedRetard.x, 1.0-moddedRetard.y);
	
	vec4 pixel = texture(sTD2DInputs[0], moddedRetard);
	fragColor = pixel;

	// fragColor = TDOutputSwizzle(color);
}

###●置き換えるコードは?
*ここからはたぶんこの記事の肝になります。

isfからコピペしたコメントアウトのコード下にある**「void main(void){}」の中のプログラム**を,タッチのデフォルトで書かれてた

out vec4 fragColor;
void main()
{
	// vec4 color = texture(sTD2DInputs[0], vUV.st);
	vec4 color = vec4(1.0);
	fragColor = TDOutputSwizzle(color);

→→→この辺にコピペ!!!

}

→→→この辺にコピペ!!!にコピペしときましょう

###●Uniform
タッチのglslでは,uniform変数を使っていろいろできるっぽいです。

GLSLにはユニフォーム変数という概念があります。通常GLSLコードの中で定義された変数を変更するとGLSLプログラムは再度コンパイルしないと有効になりませんが、uniform 指定子をつけた変数に関してはGLSLプログラム外部から動的にパラメーターを変更できるようにする、という仕組みです。TouchDesignerでももちろんこの機能が使えます。

ってことらしいです。笑

ここではisfからコピペしてきたコメントアウト部分を参考に**"NAME"Uniform変数**に割り当てていきます。

たとえば,

{
      "NAME": "slidetop",
      "TYPE": "float",
      "MIN": 0,
      "MAX": 2,
      "DEFAULT": 0
    },

これだと,"TYPE":"float""NAME":"slidetop" なので,

uniform float slidetop;

に置き換えられます。
("DEFAULT"の値はまた後で使います)

この作業をすると,

uniform float slidetop;
uniform float slideleft;
uniform bool mirrorHorizontaltop;
uniform bool mirrorVerticaltop;
uniform float slidebot;
uniform float slideright;
uniform bool mirrorHorizontalbot;
uniform bool mirrorVerticalbot;

が出来上がって,glsl_infoに出ていたエラーもだいぶ減ったと思います。
(エラーが着実に減ってくとほっとするよね。)

他の置き換え部分は,
「isf_FragNormCoord」「vUV」
「IMG_NORM_PIXEL」「texture」
「inputImage」「sTD2DInputs[0]」
「gl_FragColor」「fragColor」

です!!!笑

え?なんでそれを置き換えるってわかるの?

となった私なので,これらを少し解説していきます。

**「isf_FragNormCoord」**は,

これは便利な変数であり、現在のフラグメントの正規化された座標を表します([0,0]は左下、[1,1]は右上)

で,**「vUV」**は,

uvは、画像の左下が (0, 0)、右上が (1, 1) になるような2次元の数字で、今どのピクセルを処理しているのかをシェーダー側で知ることのできる情報です。

ってことで**[0,0][1,1]**って表記からわかるように,置き換えれそうですね!笑

**「IMG_NORM_PIXEL」**は,

シェーダーでのtexture2D()またはtexture2DRect()の呼び出しは、それぞれIMG_NORM_PIXEL()またはIMG_PIXEL()に置き換える必要があります。

**「texture」**は

外部からの入力のテクスチャも簡単に扱えるようになっています。デフォルトで生成されるコードの vec4 color = texture(sTD2DInputs[0], vUV.st); の部分のコメントアウトを外せば1番目に接続されたテクスチャをそのまま表示する動作になります。

ってところから,ともにテクスチャを扱うときのコードなんですかね?笑

**「sTD2DInputs[0]」**は,glslTOPのオペレーターを繋ぐところ(今回ならmoviefileinTOPと繋がっている)が関係していて,3口あるので[0]〜[2]までできます。

このそれぞれの置き換えについて,記事にする身としてはちゃんと調べようと思って,この記事がすごく参考になりましたのでリンク共有しときます。

映像音響処理概説 2018 第十七回 GLSLについて
http://satoruhiga.com/TDWS2018/day17/

ISF Variables Reference | ISF Documentation
https://docs.isf.video/ref_variables.html#automatically-declared-variables
https://docs.isf.video/ref_converting.html

これ一読するだけでもGLSLを理解しやすくなると思います!

あとはデフォルトでタッチの方にあった

// vec4 color = texture(sTD2DInputs[0], vUV.st);
vec4 color = vec4(1.0);
fragColor = TDOutputSwizzle(color);

はここではもう使わないので,コメントアウトするなり消すなりしておきましょう。

最初はエラーを吐きまくっていたと思うのですが、
最終的にはこのようにglsl_info(DAT)でエラーがなくなれば成功です!
スクリーンショット 2021-03-28 22.22.46.png

####●glslTOP
あともう一踏ん張りです!
スクリーンショット 2021-03-28 13.07.31.png
glslTOP/Load Umiform NamesのLoad(この画像の真ん中ら辺にあるボタン)を押してあげると,

スクリーンショット 2021-03-28 13.07.24.png
こんな感じで,Uniform変数がずらっと出てくるはずです。
あとはあの"DEFAULT"の値を,Vectors/Value/value xに入れていけばOK!
(名前が似ててややこしいから気をつけてね)

 "NAME": "DEFAULT":
"slidetop"  0
"slideleft"  0
"mirrorHorizontaltop" true(1)
"mirrorVerticaltop" true(1)
"slidebot" 0
"slideright" 0
"mirrorHorizontalbot" true(1)
"mirrorVerticalbot" true(1)

(trueは1,falseは0なので,それで対応した数字を入れてます。)

#ここまでお疲れ様でした!🎉
無事にプログラムを実行できたことを祈っています!

あとは自由に,TOPとかで画像を加工したり,LFO CHOPで動きを自動にしたり,画像を差し替てみたり,コードいじってみたり,違うISFのコードを試してみたり,いろいろ遊んでみてください!

##■まとめ
基本的にはエラーを読んで置き換えていく流れになると思います。

こういうプログラム言語の翻訳みたいなことって,**「四角を書きたい」**という本質に対して「javaだったらこう書く」「htmlならこう書く」「glslならこう書く」みたいな感覚ってのがありますよね。

以前にGoogleのColab上でTensorFlowを使って機械学習かじってた時に,これTouchDesigner上で動かせたら楽しそうだな,と思って試してみてたところ,NVIDIAのGPUじゃないと動かなかったり,なんでかわかんないけどライブラリが読み込めなかったり,今回やったようなプログラム言語の翻訳みたいなことが全然できなくてうまくいかなかった経験があったので,今回はその翻訳がうまくいってよかった。求めていれば,違う形で叶うことがあるって感じがした。

それも,師匠や正しい先生のような,今回ならTDSWのチュートリアル動画で解説されていた原田康さんがいてくれたこそできたことだなと痛感した。**こういったことを学ぼうと思うと、わりと図書館とか大学とかが必要だったのに,今ではそれが大きく変わったように思う。**解説とかチュートリアルって本当にありがたい。だからこそ自分も少しでもこう言った記事を通じてオープンサイエンスに貢献できればなと思う。

twitter:https://twitter.com/jp_dummy
twitter:https://twitter.com/JITSUZAISEI

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?