TouchDesigner GLSL メモ
随時更新されていきます
更新日2023/11/26/1:37
TouchDesignerとGLSLのメモです。
何もかも忘れっぽいのでメモします。
間違っていることや情報があればぜひ教えて下さい。
gl_FragCoord と vUV.st
下の二個のコードで同じ画像が生成される。
//UV画像が見れる
color = vec4(vUV.st, 0.0, 1.0);
//UV画像が見れる
color = vec4(gl_FragCoord.x / uResolution.x, gl_FragCoord.y / uResolution.y, 0.0, 1.0);
つまり、
・vUVは[0-1]の範囲に正規化されたx,y座標が入っている
・gl_FragCoordは[1280, 720]など生の解像度の値が入っている。
out vec4 fragColor と TDOutputSwizzle()
ここに最終的に値を入れると画像が生成される。
fragColor = TDOutputSwizzle(color);
と初期設定でなっている。
これは、Windowsとmac版での色の差異を補ってくれる関数のようなので、
入れとくと良い。
TOPの入力(texture)とGLSL
ここのinputの3つに好きなテクスチャとしてGLSLに送れる。
![画像1](https://assets.st-note.com/production/uploads/images/41094778/picture_pc_bc023d12336dd108abbe425839b91a7d.png)
GLSL上ではsTD2DInputs[0-2]でsampler型(sampler2D?)で受け取れる
texture(sTD2DInputs[0], vUV.st);
//vUV.stの場所の引数には0-1までのテクスチャ座標を入れる
//テクスチャを正規化した座標上で対応する点のカラーが返ってくる
一般に、GLSLでは、texture()関数では
` fc = texture(image, gl_FragCoord.xy);`みたいな感じで、gl_FragCoord.xyで帰ってくる、ピクセル座標をそのまま参照してそれに相当するテクセルを返してくるということになっているが、
TouchDesignerでは、sTD2DInputs[index]が、uv形式で[0-1]のvec2での座標をいれることによって、テクセルが返ってくるように事前に処理されていることに注意。
単純にもう既に用意されている、vUV.stみたいなものを使うか、
‘vec2 uv = (gl_FragCoord.xy) / resolution.xy;`みたいな正規化を行ってUVを作るなどをしなくてはならない。(resolution.xyはuniform変数として用意しなくてはならない。)
vec2 p = (gl_FragCoord.xy * 2.0 - uResolution.xy) / min(uResolution.x, uResolution.y);
//中央を原点にする。
vec4 color = vec4(1.0);
color.rgb = texture(sTD2DInputs[0], p).rgb;
![画像2](https://assets.st-note.com/production/uploads/images/41094839/picture_pc_c6295c7b6e59ee5eb2fd87698728bc12.png)
uResolution = [1280, 720]
texture解像度が[720, 720]だとすると、
こうすると、[0,0]が真ん中になるため、真ん中が画像の左下となる上記のような画像ができる。
Uniform変数
Uniform変数は簡単に作って渡せる。
GLSL内でuniformの宣言を行って普通に書く。
uniform vec2 uResoltuion;
void main(){
vec2 p = (gl_FragCoord.xy * 2.0 - uResolution.xy) / min(uResolution.x, uResolution.y);
fragColor = TDOutputSwizzle(vec4(p, 0.0, 1.0));
}
などと、最後のfragColorまでの出力までにどこかで使われているように書くと、
GLSL TOPのGLSLの項目でLoad Uniform NamesのLoadを押すと
![画像3](https://assets.st-note.com/production/uploads/images/41095001/picture_pc_f5f98ede728e3ce46d1959713202a1b3.png)
GLSL TOPのVectorsの項目等に勝手に追加される
値も他のオペレーターからのReferenceを利用して自由に遅れるので便利。
![画像4](https://assets.st-note.com/production/uploads/images/41095008/picture_pc_28a4efa40d8f4e31c5bcf5ca477e9671.png)
GLSL TOP Extend Mode
GLSL TOPのGLSLタブの中の、Input Extend Mode UVを押すと、
描画範囲外の処理の扱いを簡単に行ってくれる。
Holdにすると伸びるような画像になり、
Repeat , Mirror , Zeroが用意されている。
![画像5](https://assets.st-note.com/production/uploads/images/41095119/picture_pc_3d77cccc3ee880d2f72423bc43e9a020.png)
GLSL と Pixel Format
GLSLでは基本的に[0-1]の範囲の値しか取り出せないが、
![画像6](https://assets.st-note.com/production/uploads/images/41095267/picture_pc_526af5251a1d7bb0512e8ca1a0f16477.png)
※これは単なるsin wave
![画像7](https://assets.st-note.com/production/uploads/images/41095275/picture_pc_d9c47fe17bc1c8ab83ccda6bcf58c678.png)
Pixel Formatの値を変更することで出力範囲を変えれる。
![画像8](https://assets.st-note.com/production/uploads/images/41095282/picture_pc_a1b20d58abb9a1ae2c9fbe40bd3dcac4.png)
初期設定 8bit fixed(RGBA)だと[0-1]の範囲でクリッピングされる
![画像9](https://assets.st-note.com/production/uploads/images/41095315/picture_pc_bd4dd7dcc870751530d5f51604408e06.png)
16bit float rgbaとかだと
マイナス領域に広がるかつ、範囲がデカくなる
どこまで広がっているのかは調べてないのでわからない。
パッと見結構広い
![画像10](https://assets.st-note.com/production/uploads/images/41095320/picture_pc_ca7924110d9ab3eb634cebd4c34e1e28.png)
![画像11](https://assets.st-note.com/production/uploads/images/41095328/picture_pc_c36d7fe2aeafb9deeae420eaf2901187.png)
GLSL TOP と Frame Buffer
フレームバッファを取り出せる。
layout(location = 0) out vec4 color_uv;
layout(location = 1) out vec4 color_1;
layout(location = 2) out vec4 color_2;
void main(){
..............
color_uv = TDOutputSwizzle(colorUV);
color_1 = TDOutputSwizzle(color1);
color_2 = TDOutputSwizzle(color2);
}
layout(location = bufferの番号) out vec4 任意の名前
で宣言し、void mainの中で何かしらを与える。
![画像12](https://assets.st-note.com/production/uploads/images/41095704/picture_pc_251a7f82533418c832a1cab295717e4e.png)
GLSL TOPのGLSLタブの一番下 # of color buffersの値が初期値1になっている
これは1枚のバッファを扱うことができることを意味していて、上記の例で行くと3枚扱いたいので3にする
![画像13](https://assets.st-note.com/production/uploads/images/41095720/picture_pc_e37512b5cd02dbc30b408e3f5fa2d96a.png)
render select TOPを作り、TOPにglsl TOPを選択する。
![画像14](https://assets.st-note.com/production/uploads/images/41095727/picture_pc_868dc16d97216686b0876af57e1a14ef.png)
color buffer indexの値を変えることによって、バッファを選択できる。
ここはインデックスなので0スタート。
分かりやすい説明。
GLSL TOPのビルドイン
GLSL TOPのビルドイン関数とかはここに書かれている。
Noiseとかも用意されているらしい。
uTD2DInfos[0].resは
The components are defined as:
vec4 res; // contains (1.0 / width, 1.0 / height, width, height)
uTDOutputInfo.res
MAT to GLSL MAT
Phong MATやPBR MATからGLSL MATに変換することができる。
output shader..というところからoutputを選択し、ウィンドウのokを押すと生成される。
![画像15](https://assets.st-note.com/production/uploads/images/41098417/picture_pc_390641911e87c96d03b98fa15e96dccc.png)
![画像16](https://assets.st-note.com/production/uploads/images/41098510/picture_pc_fcd8c1a41128fea42335a9d3d9e15dd8.png?width=800)
TDDeform()とTDWorldToProj()
TouchDesignerで用意してる変換行列
TDDeform・・モデル・ビュー座標変換用の関数
TDWorldToProj()・・プロジェクション座標変換用の関数
MVP変換について
vec3 newP = P;
newP += TDDeform(newP).y;
~~~~~
![画像33](https://assets.st-note.com/production/uploads/images/41785002/picture_pc_46805e0407ef21d00298be9d5b3a0a23.png)
GLSL MATとSampler2D
GLSL TOPと違って、textureをGLSLに送るにはノードをつなぐのではなく
タブ内のSamplersからTOPを選ぶ
![画像17](https://assets.st-note.com/production/uploads/images/41098672/picture_pc_b81a3c144f6308b870ae400667ac1a26.png)
受け取りは以下のようにして受け取れる。
uniform sampler2D uNoise;
Sampler2DのサイズもuTD2DInfos[]という変数名で取得可能
UVじゃなくても、
これでもカラー値を手に入れることができる。
vec3 color = texelFetch(uNoise, ivec2(w, h), 0).rgb;
GLSL MATとUV座標
GLSL MATではuv座標を取得するのには、uv[0].xyのようにすると使うことができる
texture(uNoise, uv[0].xy);
int id = gl_VertexID;
vec2 res = textureSize(uPosMap, 0);
vec2 uv = vec2(float(id % int(res.x)), float(floor(id / int(res.x))) ) / res;
vec2 texCoord0 = uv + (1.0 / res) * 0.5;
まず int id = gl_VertexID; で0から65535までの頂点のユニークなIDを取得します。
これを使ってuPosMap上の対応した座標のpixelの色情報を取りたい。
なので vec2 res = textureSize(uPosMap,0); でuPosMapの縦横の解像度を取得し、 vec2 uv = vec2(float(id % int(res.x)), float(floor(id / int(res.x)))) / res; でuPosMap上のuv座標に変換しています。ぱっと見見慣れないかもしれませんが、よく画像のpixelを舐めるときにfor文で書いてるアレです。
ただ、これだとpixelの左上端を見てしまうので、真ん中に持ってくるために vec2 texCoord0 = uv + (1.0 / res) * 0.5; の処理をします。
[引用] https://qiita.com/ToyoshiMorioka/items/91c4e1427c2b4296c2a4
Vertex Shader Attribute変数
ビルドインされている、Attribute変数についてはこちらら参照できる。
layout(location = 0) in vec3 P; // Vertex position
layout(location = 1) in vec3 N; // normal
layout(location = 2) in vec4 Cd; // color
layout(location = 3) in vec3 uv[8]; // texture coordinate layers
Pはvertex positionとして割り当てられている。
pointとAttribute
Attribute変数を自分で追加できる。
glsl MATにつながっているジオメトリーのオブジェクトが
point SOPを経由している場合
customのタブからattribute変数を追加することができる。
![画像25](https://assets.st-note.com/production/uploads/images/41723431/picture_pc_60e67921ecc5cd6586ce03cbc6eeefb0.png)
別ノートにpythonとTscriptについてのビルドインが乗っている。
https://note.com/omakazu/n/nb4b3177ee6e3#FBCVq
上の場合、
vertex shaderとかで、
in float PT;
で読み込むことができる。
GeometryとAttribute
geometry compのinstance3タブにChopとかTOPとかをCustom Attrib OPに入れると下記の方法でAttributeを作れる
XYZWの4chanの値を入れれる
![画像34](https://assets.st-note.com/production/uploads/images/41791227/picture_pc_6ac89116e685b7061ddb031a2fe8e4cf.png)
TDInstanceCustomAttrib0()でGETできる。
Custom instance attributes can be retrieved using these functions:
vec4 TDInstanceCustomAttrib0();
vec4 TDInstanceCustomAttrib0(int instanceIndex);
vec4 TDInstanceCustomAttrib1();
vec4 TDInstanceCustomAttrib1int instanceIndex);
vec4 TDInstanceCustomAttrib2();
vec4 TDInstanceCustomAttrib2(int instanceIndex);
vec4 TDInstanceCustomAttrib3();
vec4 TDInstanceCustomAttrib3(int instanceIndex);
[引用] https://docs.derivative.ca/Write_a_GLSL_Material
これで受け取れる
newP *= TDInstanceCustomAttrib0().x;
gl_InstanceID
インスタインシングしているときのインスタンスオブジェクトに対するIndexをもらうことができる。
gl_VertexID
vertexごとに変化を加えたいときに使える。
vertexのindexが入ってくる
TDInstanceTexCoord()
// To calculate the texture coordinates for your instance (if used in the Geometry COMP's parameters), use these functions
// For texture coordinates the passed in variable 't' is the current texture coordinate to be modified/replaced
vec3 TDInstanceTexCoord(int instanceID, vec3 t);
vec3 TDInstanceTexCoord(vec3 t);
Attribute Functions
When modifying the texture coordinates, these functions do the texture coordinate modifications per instance. t is the texture coordinate to modify. The version without instanceIndex will use the current value for gl_InstanceID automatically.
vec3 TDInstanceTexCoord(int instanceIndex, vec3 t);
vec3 TDInstanceTexCoord(vec3 t);
[引用] https://docs.derivative.ca/Write_a_GLSL_Material
https://forum.derivative.ca/t/why-does-touchdesigner-use-tdinstancetexcoord-in-vertex-shader/109813
TDInstanceTranslate()
おそらく、InstanceのTranslateの値がそれぞれGETできる
つまり、Instance元のPointの個数だけ
![画像26](https://assets.st-note.com/production/uploads/images/41770285/picture_pc_22547ae96dab730265cbd97a87f56186.png)
![画像27](https://assets.st-note.com/production/uploads/images/41770335/picture_pc_f93acc559151cd00f7d508de371f3cc8.png)
newP = P;//このPは(今回で言えばTubeの)pointのpositionが入ってくる。
newP.x += TDInstanceTranslate().y;
//TDIsntaceTranslate()は元なっている、(今回で言えばboxの)ポイントのpositionが入ってくる。
![画像29](https://assets.st-note.com/production/uploads/images/41770629/picture_pc_d80bef43e3e0154082089dae22fec97b.png)
![画像28](https://assets.st-note.com/production/uploads/images/41770609/picture_pc_67804bdfd0667f58c11c72fed7dbfa22.png)
TDInstanceRotate()
Rotateのところを扱える?
![画像30](https://assets.st-note.com/production/uploads/images/41770682/picture_pc_2f3cbb5ed65b0095eb66a49ab8bb2149.png)
TDInstanceColor
同様にinstanceのcolorを手にれれる。
TDInstanceColor(Cd)とすれば、instanceのpoint事のカラーを設定できる。
TDRotateX(), TDRotateY(), TDRotateZ(), TDScale() TDTranslate()
変換行列
引数の中に値を入れると使える。
TDRotateは引数にradianを入れると正しい挙動。
newP*= TDRotateX(newP.y);
![画像31](https://assets.st-note.com/production/uploads/images/41784480/picture_pc_3646f436b54c07aedad26f89cd617b9e.png)
newP*= TDRotateX(newP.y);
newP *= TDRotateX(TDInstanceTranslate().y);//
![画像32](https://assets.st-note.com/production/uploads/images/41784606/picture_pc_79ef5ccd45dd92c67f52c375d7cebb20.png)
GLSL TOPとCompute Shader
GLSL TOPのみComputeShaderが扱える。
GLSL TOPの右下赤矢印を押すことで、ComputeShaderようのDATがでてくる。
![画像18](https://assets.st-note.com/production/uploads/images/41234894/picture_pc_310e20a35c3d65a5410ae0827d90dfcd.png)
![画像19](https://assets.st-note.com/production/uploads/images/41234902/picture_pc_4499525a269cc9da3e889b0200b7b8e1.png)
GLSL Versionは4.3以降から使うことができる。
ModeをCompute Shaderに切り替える必要がある。
![画像20](https://assets.st-note.com/production/uploads/images/41235014/picture_pc_9e6ceb393b8e8b4755679e887f2f3ea1.png)
gl_GlobalInvocationID
Compute Shaderはピクセルごとに処理が行われる。
グローバル変数 in uvec3 gl_GlobalInvocationIDでピクセル単位のインデックスが得られる。つまり、値は整数のピクセル座標が得られる。
UV画像を作りたいなら
uniform ivec2 res;
void main(){
//floatでキャストしないと整数値になっていしまう。
color = vec4(float(gl_GlobalInvocationID.x) / res.x, float(gl_GlobalInvocationID.y) / res.y, 0.0, 1.0);
imageStore(mTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.xy), TDOutputSwizzle(color));
}
![画像21](https://assets.st-note.com/production/uploads/images/41235273/picture_pc_d43d5446881e64aae217790975369e21.png)
Compute Shaderとバッファ
Compute Shaderではバッファに対して読み書きができる。
Output accessをread-writeにするとバッファに対して読み書きができるようになる。
![画像22](https://assets.st-note.com/production/uploads/images/41235374/picture_pc_febaf7567241271089e7a34c7220a8f3.png)
書き込みに関して
void imageStore(gimage2D image, ivec2 P, gvec4 data)で
第一引数に書き込みたいバッファオブジェクト
第二引数に二次元のピクセル座標(整数値)(UVではない。)
第三引数にピクセルのカラーの値
で書き出すことができる。
読み込みに関しては
gvec4 imageLoad(gimage2D image, ivec2 P);
第一引数に書き込みたいバッファオブジェクト
第二引数に二次元のピクセル座標(整数値)(UVではない。)
で該当する部分のピクセルのカラー値が得られる。
sTDComuputeOutputsとmTDComputeOutputs
sTDComuputeOutputsはmTDComputeOutputsに変更された。
これらは出力のColor Buffer(フレームバッファ)とが入っている。
The sTDComputeOutputs[] uniform will be sized equal to the number of color buffers being output.
こうすることで、1フレーム前のバッファを読み込むことができる。
//一フレーム前のバッファを参照
layout (local_size_x = 8, local_size_y = 8) in;
void main()
{
vec4 color;
color = imageLoad(mTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.xy));
color.rgb += vec3(0.01, 0.03, 0.04);
color.rgb = fract(color.rgb);
color.a = 1.0;
imageStore(mTDComputeOutputs[0], ivec2(gl_GlobalInvocationID.xy), TDOutputSwizzle(color));
}
GLSL TOPのClear OutputsをOffにしとかないと、
フレームバッファが毎回リセットされてしまうので、注意。
![画像23](https://assets.st-note.com/production/uploads/images/41236979/picture_pc_8b319c5049ce6c8136c7ff1ad468141f.png)
GLSLTopとArrays
texture bufferとしてArrraysのタブからCHOPの値を送ることができる。
![画像24](https://assets.st-note.com/production/uploads/images/41239221/picture_pc_7618641b6764eab46a7a74016b95ff1b.png)
texture bufferとして送られたものは、
uniform samplerBuffer uniform名;
で受け取れる。
これは、texture()関数ではなくて、
texelFetch()関数を用いて値を取り出せる。
texelFetch(textureBuffer, Pixel_position)
第一引数にはtextureBuffer
第二引数にはピクセル座標(UVではない)
CHOPからの値を受け取れる方法として便利
uTDOutputInfo.res.xy holds (1.0 / width, 1.0 / height)
Cheat Sheet
Inigo Quilez :: fractals, computer graphics, mathematics, shaders, demoscene and more
Primitiveの作り方
The Book of Shaders
Shaderific - GLSL Functions
GLSL Build in Function
過去のGLSLのノート
References
この記事が気に入ったらサポートをしてみませんか?