連日の『TouchDesigner』で『GLSL』を使ってみる動画のメモになります。
前回の記事
今回は『ShaderToys』からのコードを持ってくる方法が紹介されていました。
動画はこちら。
TouchDesignerでShaderToysを使う方法 ShaderToysの説明
『base COMP』作成して shadertoy と命名し中へ。
まずはShaderToysの案内。
- ShaderToys・・本格的なフラグメントシェーダでつくった映像盛りだくさんなサイト(とにかく重い
ライセンスをチェック。ライセンスは守りましょう。
Creative Commonにもいろいろあるよ。
的な内容で。
今回コード引用するのはこのページ。
marbleで検索するとでてきます。
コードをplaying_marble.glslというファイル名で保存しつつ、
- 『text DAT』生成。playing_marble.glslを選択
- Loat on Start でPulseボタンを押す
- コードが表示される。
コードはこちら。
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. // Created by S. Guillitte 2015 float zoom=1.; vec2 cmul( vec2 a, vec2 b ) { return vec2( a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x ); } vec2 csqr( vec2 a ) { return vec2( a.x*a.x - a.y*a.y, 2.*a.x*a.y ); } mat2 rot(float a) { return mat2(cos(a),sin(a),-sin(a),cos(a)); } vec2 iSphere( in vec3 ro, in vec3 rd, in vec4 sph )//from iq { vec3 oc = ro - sph.xyz; float b = dot( oc, rd ); float c = dot( oc, oc ) - sph.w*sph.w; float h = b*b - c; if( h<0.0 ) return vec2(-1.0); h = sqrt(h); return vec2(-b-h, -b+h ); } float map(in vec3 p) { float res = 0.; vec3 c = p; for (int i = 0; i < 10; ++i) { p =.7*abs(p)/dot(p,p) -.7; p.yz= csqr(p.yz); p=p.zxy; res += exp(-19. * abs(dot(p,c))); } return res/2.; } vec3 raymarch( in vec3 ro, vec3 rd, vec2 tminmax ) { float t = tminmax.x; float dt = .02; //float dt = .2 - .195*cos(iTime*.05);//animated vec3 col= vec3(0.); float c = 0.; for( int i=0; i<64; i++ ) { t+=dt*exp(-2.*c); if(t>tminmax.y)break; vec3 pos = ro+t*rd; c = map(ro+t*rd); col = .99*col+ .08*vec3(c*c, c, c*c*c);//green //col = .99*col+ .08*vec3(c*c*c, c*c, c);//blue } return col; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { float time = iTime; vec2 q = fragCoord.xy / iResolution.xy; vec2 p = -1.0 + 2.0 * q; p.x *= iResolution.x/iResolution.y; vec2 m = vec2(0.); if( iMouse.z>0.0 )m = iMouse.xy/iResolution.xy*3.14; m-=.5; // camera vec3 ro = zoom*vec3(4.); ro.yz*=rot(m.y); ro.xz*=rot(m.x+ 0.1*time); vec3 ta = vec3( 0.0 , 0.0, 0.0 ); vec3 ww = normalize( ta - ro ); vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0) ) ); vec3 vv = normalize( cross(uu,ww)); vec3 rd = normalize( p.x*uu + p.y*vv + 4.0*ww ); vec2 tmm = iSphere( ro, rd, vec4(0.,0.,0.,2.) ); // raymarch vec3 col = raymarch(ro,rd,tmm); if (tmm.x<0.)col = texture(iChannel0, rd).rgb; else { vec3 nor=(ro+tmm.x*rd)/2.; nor = reflect(rd, nor); float fre = pow(.5+ clamp(dot(nor,rd),0.0,1.0), 3. )*1.3; col += texture(iChannel0, nor).rgb * fre; } // shade col = .5 *(log(1.+col)); col = clamp(col,0.,1.); fragColor = vec4( col, 1.0 ); }
『GLSL TOP』追加。
『GLSL TOP』→pixel shader に、作成した『Text DAT』をドラッグドロップ。
コードをコピーしただけだとglsl_infoにエラー発生。
TouchDesignerでShadertoyを使う方法 変数を定義
shadertoyのページの中のShader Inputsを押すと、
最初から定義されている変数が見れます。
glsl_infoで発生しているエラーを見つつ、変数を定義していきます。
uniform float iTime; uniform vec2 iResolution; uniform vec3 iMouse;
iChannel0だけエラーが消えません。
コードを見るとtextureとして使われているので、
if (tmm.x<0.)col = texture(iChannel0, rd).rgb;
『Movie File In CHOP』で代用します。
マクロを追加します。
- マクロ・・#defineで定義する定数
#define iChannel0 sTD2DInputs[0]
『sTD2DInputs』は『TouchDesigner』組み込み変数で、インプット用に使います。
が、まだエラーがでてる・・・
コードを見ると、rdはvec3で定義されている。
iChannel0はvec2か。
vec3 rd = normalize( p.x*uu + p.y*vv + 4.0*ww ); vec2 tmm = iSphere( ro, rd, vec4(0.,0.,0.,2.) ); // raymarch vec3 col = raymarch(ro,rd,tmm); if (tmm.x<0.)col = texture(iChannel0, rd).rgb;
Shadertoyで見ると、『Cubemaps』というものが使われているよう。
TouchDesignerでShadertoyを使う方法 sTDCubeInputs
ヘルプから 『TouchDesigner』のマニュアルでの中の『Write a GLSL TOP』をみてみます。
cubeで検索すると、どうやらcubeの場合は、
『sTD2DInputs』ではなく、『sTDCubeInputs』 を使うよう。
どうやってcubeをつくるかというと、
『Movie File IN CHOP』で、『PalaceOfFineArts-360Designs.io.jpg』画像ファイルを選択します。
『Projection TOP』を追加します。
『Movie File In』 -> 『Projection』 とつないで、
『Projection』のInput/Outputを下記に変更します。
- Input・・Equirectangular
- Output・・Cube Map
と思い調べてみると、
地図投影法の一種であり、『正距円筒図法(せいきょえんとうずほう)』のこと。
360度で撮影された画像を、Cubeの形にして、貼り付けようってことかなと。
infoを見ると確かに 『cube map texture』 になっとります。
cube mapになった『projection』を『GLSL TOP』に繋げると、別のエラー発生。
あらためて、
『sTD2DInputs』 を 『sTDCubeInputs』 に変更します。
#define iChannel0 sTDCubeInputs[0]
また別のエラー発生・・・
TouchDesignerでShadertoyを使う方法 mainImage関数の書き換え
『ShaderToys』は『mainImage』関数になっているので、これを書き換えます。
『mainImage』関数を 『main』 に置き換えます。
//void mainImage( out vec4 fragColor, in vec2 fragCoord ) void main()
『fragColor』, 『fragCoord』も再度定義します。
out vec4 fragColor; void main() { vec4 fragCoord = gl_FragCoord;
『GLSL TOP』で『Load Uniform Names』のLoadボタンを押すと、定義していたuniformが反映されます。
ここでセーブすると、動画とは違うエラー発生しました。(バージョンによってちょっとエラーが違いそう)
『vUV』が読み込まれていないということで、コードを変更します。。
//void mainImage( out vec4 fragColor, in vec2 fragCoord ) out vec4 fragColor; void main() { vec2 fragCoord = vec2(vUV.s*iResolution.x, vUV.t*iResolution.y);
ようやく、キューブが表示されました。
TouchDesignerでShaderToyを使う方法 マウスチョップ Mouse CHOP
マウスで動かせるように、『Mouse In CHOP』を追加します。
お約束の『Null CHOP』も追加してつなげます。
『Null CHOP』の右下の+ボタンを押した後に、
『GLSL TOP』->Vectors1->iMouse の箇所にドラッグドラップします。
『Export CHOP』を選ぶと、
マウス座標が『GLSL TOP』に反映されるようになります。
あとで画像はる
動画内では『Math CHOP』で倍加しているようです。
ここまでで、動画47分中19分40秒。。
TouchDesignerでShaderToysを使う方法をやってみた感想
さらっと『ShaderToys』コード組み込めるかと思いきや、
『Cube』なり使っているコードによって対応が変わるようで、
なかなか一筋縄にはいかないようです。
とはいえ使いこなせるようになると
先人たちのかっこういい映像をもりもり使える可能性が広がるので、
ムリない範囲で少しずつ知識アップしていきたいと思います。
次の記事
誠意執筆中!
最初の記事
アオキのツイッターアカウント。
この記事へのコメントはありません。