第18回: GLSL MAT

今回のプロジェクトファイル

成績をつけないといけないので課題を出します!

のいずれかを作ってください!

期限: 2020/1/24の授業が始まるまで

授業中に講評をしていこうと思います
それにともなって、来週17日の授業は質問 & 制作タイムとします

GLSL MAT

今回の授業では、前回にもすこしお話した GLSL MAT について触れていきます。

GLSL TOP でもシェーダーを書いていましたが、実はGLSLシェーダーの中にもいくつかの種類があります。

OpenGLの世界ではポリゴンなどの図形をを書く時には

といったような工程があります。↓ の図を参照

Image OpenGL - Drawing polygons

この中で、GLSL TOP で使っていたものが Fragment Shader の部分に相当します。Pixel Shader と呼ばれることもあり、TouchDesignerでは Pixel Shader の名前で呼ぶのが普通なようです。

GLSL MAT ではさらにポイントの座標を操作する Vertex Shader と、ポイントの数をレンダリング時に増減することのできる Geometry Shader が使えるようになります。

GLSL MAT を新しく作ると ↓ の図のように vertex pixel と名前のつけられた Text DAT も同時に作られます。GLSL MAT では主にこれらをいじっていくことになります。

Image

Vertex Shader

/project1/GLSL_MAT を参照

一番最初の状態では、Vertex Shaderはこういうコードになっています。

// Example Vertex Shader

void main() 
{
	vec4 worldSpacePos = TDDeform(P);
	gl_Position = TDWorldToProj(worldSpacePos);
}

… 色々書かれていますが、主にいじり甲斐のあるのはTDDeformの括弧の中にある P との部分です。Pvec3 型の値で、TouchDesigner側で定義されています。たとえば、コードを以下のように書き換えるとトーラスが上に移動します。変更したのは P + vec3(0, 1, 0) の部分です。

// Example Vertex Shader

void main() 
{
	vec4 worldSpacePos = TDDeform(P + vec3(0, 1, 0)); // P + vec3(0, 1, 0) に変更
	gl_Position = TDWorldToProj(worldSpacePos);
}

ユニフォーム変数

GLSL TOP と同じように GLSL MAT にもユニフォーム変数を設定して、TouchDesignerのオペレーターから値を渡すことができます。Vectors 1 のタブ以下で設定します。

Image

変数を設定したら、 uniform vec3 uPosition; のような記述をすることで Vertex Shader 内で使えるようになります。

// Example Vertex Shader

uniform vec3 uPosition;

void main() 
{
	vec4 worldSpacePos = TDDeform(P + uPosition);
	gl_Position = TDWorldToProj(worldSpacePos);
}

シェーダー間で値を渡す

/project1/VERTEX_TO_PIXEL を参照

Vertex Shaderの ソースコードの上のほうに out をつけた変数を定義するとその値を Pixel Shader に渡すことができます。

// Example Vertex Shader

out vec4 vColor; // added

void main() 
{
	vec4 worldSpacePos = TDDeform(P);
	gl_Position = TDWorldToProj(worldSpacePos);

	vColor = vec4(1, 0, 0, 1); // pass `vColor` to Pixel Shader
}

Pixel Shader 側でそれを使う時は、in をつけた同じ名前の変数を定義します。変数の名前はvから始まるものにすることが多いようです。

// Example Pixel Shader

// uniform vec4 exampleUniform;

in vec4 vColor; // added

out vec4 fragColor;
void main()
{
	TDCheckDiscard();
    vec4 color = vColor; // change `vec4(1.0)` to `vColor`
    TDAlphaTest(color.a);
    fragColor = TDOutputSwizzle(color);
}

この例では、Vertex Shader で指定した赤の数値が Pixel Shader に渡っていって、最終的に fragColor の数値として使われたのでマテリアルの表示も赤になっています。

テクスチャを使う

/project1/TEXTURE を参照

テクスチャを使う方法を解説します。

テクスチャを使うには UV座標 を使いますという話を前回にしました。GLSL MAT の中では uv[0].xy とするとUV座標を使うことができます。
↓ は試しにuv座標の色をそのまま表示してみる例です。基本的な仕組みはさきほどの色の表示と同じものです。

// Example Vertex Shader

out vec2 vUV; // added

void main() 
{
	vec4 worldSpacePos = TDDeform(P);
	gl_Position = TDWorldToProj(worldSpacePos);

	vUV = uv[0].xy;
}
// Example Pixel Shader

// uniform vec4 exampleUniform;

in vec2 vUV; // added

out vec4 fragColor;
void main()
{
	TDCheckDiscard();
    vec4 color = vec4(vUV, 0, 1);
    TDAlphaTest(color.a);
    fragColor = TDOutputSwizzle(color);
}

サンプラー変数を指定する

次に、ユニフォーム変数と同じような感じで Sampler 1 のタブから サンプラー変数 を指定します。

Image

シェーダーコードにも sampler2D uBananaTexture; のような形で Sampler Name に指定したものと同じ名前の定義をします。
定義したサンプラーを texture 関数に渡せばテクスチャの色が取得できるようになります。

// Example Pixel Shader

// uniform vec4 exampleUniform;

sampler2D uBananaTexture; // added
in vec2 vUV; // added

out vec4 fragColor;
void main()
{
	TDCheckDiscard();
    vec4 color = texture(uBananaTexture, vUV); // use texture color
    TDAlphaTest(color.a);
    fragColor = TDOutputSwizzle(color);
}

標準のMATを変換する

/project1/CONVERT_MAT を参照

これまで GLSL MAT の基本的な使い方を見てきましたが、TouchDesignerに標準でついてくるマテリアルから GLSL MAT を作ることもできます。

Image

Phong MATPBR MATRBB > Output Shader のボタンを押すと今の時点での設定が GLSL MAT として書き出されます。
GLSL MAT でいちからライティング等のコードを書いていくのはなかなか大変なので、最初のうちはこういったマテリアルを変換したものをいじっていくのがいいと思います。

テクスチャの色で頂点を動かす

ここまでやったことを組み合わせると、/project1/TEXTURE_DEFORM でやっているようなテクスチャの色で頂点を移動させるようなシェーダーを作ることができます。

Image

つかれてきたので詳細は口頭で…