11
5

More than 3 years have passed since last update.

TouchDesignerでトゥーンシェーディング風の表現

Last updated at Posted at 2019-12-19

TouchDesigner Advent Calendar 2019 19日目の記事にしました。

はじめに

初のQiita投稿です。お手柔らかにお願いします。

今回はTouchDesignerでできるトゥーンシェーディング風の表現を3つ紹介したいと思います。
【サンプルファイルはこちら

方法その① GLSL MAT小技

1つ目はシェーダーを一行も書かないGLSL MAT小技です。

  1. phong MATを出す
  2. phong MAT→RGBタブの最下部にある"Output Shader..."のところをクリック→OKをクリック
  3. 新しくできたphongGLSLのvectors1タブのuShininessの値を100から0に変更

TouchDesigner 2019.19930_ C__Users_doray_Desktop_NewProject.1.toe_ 2019-12-18 20-30-29_3.gif

通常のphong MATだとShininessを1より小さい値に下げることができないので、一度GLSL MATに変換するのが肝です。

一応断っておきますが、これはバグ(?)的な挙動で、まったくもってトゥーンシェーディングではないです・・・(なぜこうなるのかは、この辺ですこし書かれてました。)

ただ使いどころによってそれっぽく見えなくもないというのと、何より早くて簡単というので最初にこの方法を紹介しました。質感の品質的に高いとは言えないので、一発芸にでもどうぞ。

方法その② TOPを用いた方法

2つ目はこちらのビデオチュートリアルで紹介されていた、TOPを用いた方法です。

Threshold TOPでピクセルの色をしきい値によって0/1に振り分け、そのしきい値の段階に応じて色をベタ塗りして最後にComposite TOPのoverで合わせてます。

top.png

このピクセルの色をしきい値によって0/1に振り分け、その段階に応じて色をベタ塗りというのは本来のトゥーンシェーディングのやり方と基本的には同じなので、かなりそれに近い表現になっていると思います。

加えてこちらの方法もコードを書かなくていいので、初心者でもかなりとっつきやすいかなと思います。

方法その③ ちゃんとシェーダー書く

glsl_toonshading.png

3つ目はトゥーンシェーディング風というより、GLSL MATでコードを書く普通のトゥーンシェーディングです。
諦めてコードを書きましょう。

pixelshader.glsl

in vec3 worldSpaceNorm;
in vec4 worldSpacePos;

uniform vec3 Kd; // ディフューズ反射率
uniform vec3 Ka; // アンビエント反射率
uniform float dimmer;

int level = 3; //diffuseの計算で使う階調の数。方法その2でいうとThreshold TOPで分けた数
float scaleFactor = 1.0 / level; //diffueの計算で使う階調の値

out vec4 fragColor;
vec3 toonShade()
{
    vec3 viewVec = uTDMats[0].camInverse[3].xyz; //カメラの位置取得
    vec3 lightVec = uTDLights[0].position.xyz; //ライトの位置取得

    vec3 s = normalize(lightVec - worldSpacePos.xyz); //光源方向のベクトルsを計算
    float cosine = max(0.0,dot(s,worldSpaceNorm)); //dot関数でsとノーマル(法線)の内積を計算し、max関数で負の値を取り除く
    vec3 diffuse = Kd * floor( cosine * level ) * scaleFactor; //floor関数でcosineとlevelを乗算したものを整数に切り捨て。その後scaleFactorを乗算して再び0~1の値にする。その結果にdiffuse反射率(Kd)を乗算

    return vec3(dimmer) * (Ka + diffuse); //アンビエントとdiffuseを合わせたものを、dimmerに乗算してフラグメントの最終的な色を取得
}

void main()
{   
   fragColor = TDOutputSwizzle(vec4(toonShade(), 1.0));
}

・コメントを多めに書いたのでわからない方は参考にしてみてください

今回のこちらのコードは『OpenGL 4.0 シェーディング言語』で紹介されていたトゥーンシェーディングのサンプルをTouchDesigner用に移植したものです。

その他にもTouchDesigner上でのトゥーンシェーディングはこちらのブログでも紹介されてました。ほぼほぼ同じですが、微妙に異なるところもあるので今回紹介したコードと見比べてみるのもいいかもしれないです。

まとめ

ここまでトゥーンシェーディング的な表現方法を3つ紹介してきました。
出力結果を比較するとこんな感じです。
※輪郭線は別途Edge TOPで追加しました。

方法その①
sample1.jpg

方法その②
amend2.jpg

方法その③
sample3.jpg

微妙に質感の異なるトゥーンシェーディング的な表現が3つできました。方法その②と③で見た目的にほとんど違いがないだけに、方法その①のなんちゃって感が目立ちますね。

このようにTouchDesignerなどの自由度や柔軟性が高い環境では、何か一つの表現をとっても、そこに至る方法は複数存在します。
やりたい(表現したい)ことや状況に応じて、それに合わせた最適な方法をとっていけたらいいなと思いました。

11
5
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
11
5