TouchDesignerでGLSL sandboxやShaderToyのコードを流用したりするためにも知らなきゃいけないコト

投稿日:2018-06-02



ナカジ(@cp_nakajun)です。

今回は【TouchDesignerでGLSLを使うために「最低限」知らなきゃいけない「超基礎」
の続きです。

「超基礎」を覚えたらどんどんGLSLを使っていきたくなるのが向上心。

GLSLの習熟度が高い人は今回のTouchDesignerのGLSL Topの感じがつかめればかなり使っていけるように思います。

また、僕のようにガリガリGLSLを書けるわけじゃない人はGLSL sandboxやShaderToyのコードを流用することから始めると思いますが

それをする為にもいくつか「知らなきゃいけないこと」があります。

今回はそれ

今回のポイント

ポイントは次の3つです。

  • 時間と解像度
  • 処理中ピクセル座標と出力宣言
  • シェーダー内座標の正規化

時間(time)と解像度(Resolution)

GLSL sandboxのコードを見ると最初の「変数宣言」に以下のような記述があると思います。

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

とりあえず「mouse」は置いておいて

「time」と「resolution」はGLSL sandboxのデフォルト変数です。

それぞれ

  • 現在の時間 : time
  • 出力画像のピクセル解像度 : resolution

です。

時間的変化や動きのあるものを作る際には重要で必要になります。

ShaderToyをみるとコード内でわざわざ宣言しなくても良いみたいですが

  • 現在の時間 : iGlobalTime
  • 出力画像のピクセル解像度 : iResolution

がデフォルト変数として使えます。

TouchDesignerの「時間」と「解像度」を取得し変数に格納することで使います。

方法は「GLSL TOP」のパラメータ、「Vector1」の「uniform name」に設定する変数名とコードの「uniform」で宣言する名前を一致させればオッケーです。



「value」に設定する値は

  • 時間(time,iGlobalTime):absTime.seconds
  • 解像度(resolution,iResolution):me.par.resolutionw

を下の画像のように入力することで

absTime.seconds=秒

解像度のX軸に「me.par.resolutionw」Y軸に「me.par.resolutionh」とすることで
GLSL Topのcommonタブで設定した解像度を取得することができます。


処理中ピクセル座標と出力宣言

これはなにも考えずに記述しましょう。

vec2 fragCoord = vec2(vUV.s*resolution.x, vUV.t*resolution.y);
out vec4 fragColor;

これで最終的にfragColorの情報が出力されます。

シェーダー内座標の正規化

main関数の中に

vec2 p = (fragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);

と書くコトで座標の指定を「0.0〜1.0」の範囲に統一することができます。

こうしておかないと「解像度」を変更した際に「描画座標」に関わる全てのコードを変更しなければならなくなるからです。

GLSL sandboxのコードをTouchDesignerに移植



試しにGLSL sandboxのコードをTouchDesignerに移植してみました。

今回試したコードは
http://glslsandbox.com/e#41905.0

このコードは上記に書いたことをすることで動かすことができました。

TouchDesigner用に変更したコードは以下です。

precision mediump float;
uniform float time;
uniform vec2 resolution;

vec2 fragCoord = vec2(vUV.s*resolution.x, vUV.t*resolution.y);
out vec4 fragColor;

float starFunc(vec3 p)
{
	float a = 2.0;
	float fp = .7550;
	const int n =15;
	float pa = 0.;

	for(int i = 0; i < n; ++i)
	{
		p=abs(p)/dot(p,p)-fp;
		a+=abs(length(p)-pa);
		pa=length(p);
	}

	a /= float(n);
	return pow(a,6.)*.225;
}

vec3 galaxy(vec3 start, vec3 dir)
{
    	vec3 p = start+dir*40.0;
    	vec3 c = vec3(starFunc(p)) * vec3(1.7,1.4,2.0);

	p = start+dir*1.0;
 	c += vec3(starFunc(p)) * vec3(1.2,0.8,3.0);

	p = start+dir*.1;
    	c += vec3(starFunc(p)) * vec3(1.7,1.2,1.4);

	return c*0.462;
}


void main() {

	vec2 p = (fragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);// -1.0~1.0

	float an = 1.5+0.03*time;

	float a2 = 3333.9;
	float a3 = -2.9;

	mat2 rot_a2 = mat2(cos(a2),sin(a2),-sin(a2),cos(a2));
	mat2 rot_a3 = mat2(cos(a3),sin(a3),-sin(a3),cos(a3));

	vec3 ro = vec3( 1.0*cos(an),  2.0*cos(an) ,5.);
	ro.xz *= rot_a2;
	ro.yz *= rot_a3;

	vec3 rd = vec3(p.x*cos(an) + p.y*sin(an),p.x *(-tan(sin(an))) + p.y*cos(an), 0.1 - sin(time*0.003));

	rd.xz *= rot_a2;
	rd.yz *= rot_a3;


	vec3 bckg = galaxy(ro,rd);

	vec3 col = bckg;

	col = pow(col,vec3(0.5));

	vec4 outcolor = vec4(col,1.0);

	fragColor = TDOutputSwizzle(outcolor);
}


まとめ

とりあえず、また小さな一歩を踏み出せたかなぁ、と

まだまだ細部を語れるほどの理解はできてないですが、また理解と知識を深めたら共有していきます。

TouchDesignerでGLSLを使うために「最低限」知らなきゃいけない「超基礎」


サポート募集中

この記事はお役に立てましたか。
よかったら、コーヒー ☕ をご馳走いただけたら励みになります。



TouchDesigner学習におすすめ



おすすめのクリエイティブ・コーディング関連カテゴリー

クリエイティブコーディング系 講座


ウェブツール

機能はシンプルなものですが、p5.jsやTone.jsで描画したり音が出たりするので遊んでみてください。
・【Midi Number Tools】:MIDIナンバーから音名と周波数を判定します
・【Delay Time Calculator】:テンポに応じた音符の長さを判定します