SOP Workshop @TouchDesigner Study Weekend vol.010
TouchDesigner Study Weekend vol.010 で開催された、TouchDesigner SOP中級者向けワークショップの記事です。
プロジェクトファイルはこちら -> toe
SOPの基本要素
/project1/POINTS_VERTICES_PRIMITIVES
を参照
SOP
を理解する上で避けては通れないのが、Point
、Primitive
、Vertex
というデータ構造です。
- Point
- 3Dの位置情報を持った点
- Vertex
Point
が、どういうふうに接続されてPrimitive
を構成しているか、という情報- Primitive
- ポリゴンやメッシュ、ベジェやNURBSで構成された曲線/曲面、円や球などのシンプルなプリミティブ、
メタボールやパーティクル等、ポイントのあつまり + それらがどういう風にレンダリングされるべきかの情報を持たせた単位
これらの情報は、オペレータービューを選択した状態で p
キー、または右クリックメニューから、Display Options
でビジュアライズできます。
ジオメトリを数値指定で作る
/project1/MAKE_BASIC_GEOM1
を参照
script1
のDATの中は以下のようになっています。
def onCook(scriptOp):
scriptOp.clear()
new_point = scriptOp.appendPoint()
new_point.P = (0.5, 0.5, 0.5)
急にPythonが出てきて申し訳ないのですが、オペレーターのパラメタで説明するよりもシンプルに説明できそうだったので取り上げているだけで、皆さんは今これをいじる必要はありません! とにかく scriptOp.appendPoint()
の部分がポイントを追加している部分です。接続されている Info CHOP
の num_points
にも 1 と出ています。オペレーターを中ボタンクリックをして出てくるインフォメーションでもポイントは1と表示されているはずです。
では次に、script2
のDATを見てみましょう
def onCook(scriptOp):
scriptOp.clear()
new_point1 = scriptOp.appendPoint()
new_point1.P = (0, 0, 0)
new_point2 = scriptOp.appendPoint()
new_point2.P = (0.5, 0, 0)
new_point3 = scriptOp.appendPoint()
new_point3.P = (0.5, 0.5, 0)
今度は scriptOp.appendPoint()
が3回出てきました。なので、ポイントは3つ生成されています。最初のほうで Point
は3Dの位置座標を持った点 というふうに紹介しましたので、とくに難しい事はなく、scriptOp.appendPoint()
を呼んだ分だけポイントが生成されることになります。
次、script3
のDATです。
def onCook(scriptOp):
scriptOp.clear()
new_point1 = scriptOp.appendPoint()
new_point1.P = (0, 0, 0)
new_point2 = scriptOp.appendPoint()
new_point2.P = (0.5, 0, 0)
new_point3 = scriptOp.appendPoint()
new_point3.P = (0.5, 0.5, 0)
poly = scriptOp.appendPoly(3, closed=False, addPoints=False)
poly[0].point = new_point1
poly[1].point = new_point2
poly[2].point = new_point3
さきほどの script2
のDATに比べると、後半部分の scriptOp.appendPoly(3, closed=False, addPoints=False)
以下の部分が追加されています。SOPのビューワーで見てもわかるように、ポイントをつなぐ線が追加されているので、そこ以降の操作で、点同士を繋いで線にする という処理をしています。
実際には、scriptOp.appendPoly(3, closed=False, addPoints=False)
で、頂点数が3つの Poly
プリミティブを作成して、その下に続く poly[0].point = new_point1
で、頂点がどのように接続されるべきかを指定しています。
つまり、SOPのデータ構造は、
- 複数の
Point
があり - それらがどういう順番で繋っているかの
Vertex
を指定し - どういった形でレンダリングされるべきかの
Primitive
がある
という流れのまとまりになっています。
↑ と同様の処理を Add SOP
で作った例が /project1/MAKE_BASIC_GEOM2
にあります。頂点の数が十数個までの場合だと Add SOP
を使ったほうが便利です。
プリミティブの種類
/project1/PRIMITIVE_TYPES
を参照
プリミテイブと一口に言っても、用途に応じていくつかのタイプにわかれてます。
- Primitive
Sphere SOP
,Circle SOP
,Tube SOP
などには、原点、半径、高さなど最低限のパラメタしか持っていない単純な形状があります。それぞれのSOPのPrimitive Type
からPrimitive
を選ぶと作れますが、ここだけの話何に使えるかはかなり謎でたまに選ばれちゃっててハマるぐらいなので、逆にPrimitive
が指定されていないかをチェックするようにしましょう- Polygon
- ほとんどのケースでは
Polygon
を使う事になるはずです。これは、点を3つごと、三角形のポリゴンになるように接続した形です。GPUの中でジオメトリは最終的に三角形のポリゴンに変換されて描画されるので、描画効率の点でアドバンテージがあります。 - Mesh
Polygon
と似ていますが、Meshの場合は点を4つごと結んだ四角形ポリゴンを扱います。Polygon
と比べて違う点は、四角形を敷き詰めたような形状になるため、ジオメトリに2次元の画像を貼るテクスチャ処理と相性がいい点です。また、Carve SOP
など、ジオメトリのuv座標系を考慮して動作するオペレーターではPolygon
では動作しないものがあります。- NURBS, Bezier
- 点や面を直線的に繋ぐのではなく、点や面をコントロール要素として、数学的に算出されたカーブでなめらかな表面を描画します。描画的には綺麗なのですが、やや直感的でない所があったり、計算負荷の高いケースがあったりするので慣れが必要です。
- Metaball
Metaball SOP
を使って作成されます。磁力的な何かや表面張力のような質感のジオメトリが作れます。- Particle
Particle SOP
、Convert SOP
などで作成されます。粒子のシミュレーションや、ポイントクラウドの描画などで使われます。
また、プリミティブに関する詳しい情報は Primitive - Derivative にもまとまっています。
まとめ
という訳で、SOPの基本の概念についてをすこし説明してきました。とくにプリミティブのタイプの違いについては、僕が一番最初に学習した時ハマった部分でもあります。経験からいくと、とりあえずハマった時のワークアラウンドとしては、ジオメトリ操作系のSOPで何かうまくいかないなと思ったら
- 中ボタンクリックでインフォメーションウィンドウを表示 → 凝視
- とりあえず入力を
Convert SOP
でConvert to
>Polygon
にしてみる (入力にPolygonしかとれないSOPがチョイチョイある) - UV座標系が必要なものであれば
Convert SOP
でConvert to
>Mesh
かNURBS
にしてみる - ものすごい簡単なネットワークを新しく作って、複雑度を最小化しながらテストする
- 詳しい人に聞く
- バグレポートを出す
あたりでしょうか…
あんまり基礎の部分を長々とやっていても面白くないと思うので、ほどほどにして、早速実践のほうに移っていこうと思います
プロシージャルモデリング基礎1
まずはやってみよう
セクションの最初に、簡単なサンプルを使ってプロシージャルモデリングエッセンスをお伝えできればと思います。
CHOPのパラメーターのリンクの仕方などは大丈夫… ですよね…? → 微妙な方はこちら
/project1/PROCEDURAL_MODELING1
を参照
「大きさが変わっても床の上に居座るキューブ」です。Noise CHOP
でキューブのサイズを動かしていますが、ここでの本質はそこではなく、キューブのサイズが変わると、変わった分だけキューブの中心座標を動かして必ず底面が設置するようにパラメーターを調整するエクスプレッション です。
実際には全然難しい事はなく、キューブの高さ * 0.5
を Center
の Y座標に入れればいいだけなので、↓ のようになります。
念のため、動画も貼っておきます。自分でやったのが思い通りに動くとメチャクチャ楽しいので、みなさんも作ってみてください!
練習問題1
現状だと一個問題があって、Box SOP
の Scale
の値が1でないと狙った通りの挙動になりません。
エクスプレッションを改良して、Scale
の値が1でない状態でもボックスが接地できるようにしてみてください!
正解は /project1/PROCEDURAL_MODELING1/exercises1
プロシージャルって何?
簡単な例題をやってみました。ところでプロシージャルですが、字面からの意味ですと「手続き型の」という約になるようです。。手続き型… わからん…
「プロシージャ」というのは文字ベースな言語で言う所の、「関数呼出し」にあたると思っています。「ブラックボックス化可能な」「思考的に抽象化可能な」と言い替えてもいいかもしれません。
なので、個人的な肌感覚だとさき程の例は実は「プロシージャルモデリング」ではなく、「パラメトリックモデリング」の一種なのではないかと思います。では、プロシージャルモデリングとはどういう事なのでしょうか?
/project1/PROCEDURAL_MODELING2
を参照
さきほどからの変更点は Box SOP
の後の Transform SOP
にあります。
Transform SOP
の ty
に -me.inputs[0].min.y
が指定されています。これは、「1番目に入力されているSOPの最小のyの値に -1 を掛けたもの」という意味になります。
要するに、さきほどはキューブの大きさから求めていたY軸のオフセットを、「入力されたジオメトリ全体のポイントのうち、一番下にあるポイント」を基準にオフセットを決める という風になりました。これによって、どんなSOPを入れても床を基準にしたオフセットがかかるようになる → 床に接地した状態になるようになります。
本当にそうなるか、色々なSOPを接続して試してみてください!
まとめ
このセクションでは、「プロシージャルモデリング」と、「パラメトリックモデリング」について紹介しました。両方を比べてみるとプロシージャルモデリングのほうがなんか強そうだという印象を持たれたかもしれませんが、実際の所は両者に明確な違いはないように思います。
というのも、さきほどの例にもあった「床に接地するようにオフセットをかけるTransform SOP
」のような処理を一度通した後ならば、パラメトリック的な手法でさらに複数の処理をかけるといったことが簡単にできるからです。
言い換えると、ある処理をするにあたっての必須の要件を満たすように前処理をする、ノーマライズするといった事がプロシージャルにモデリングをする事の出発点になるかもしれません。前処理をしたあとであればより自由で簡単にさまざまな手法でモデルを操作できます。
なので、何かジオメトリを操作する時、なるべく入力のジオメトリを変更しても同じような結果にできないか を意識してネットワークを組んでいると、煮詰った時簡単に違う入力に差し替えて試してみる事ができます。非常にオススメです 👍
プロシージャルモデリング基礎2
色々なアプローチ
練習問題2
/project1/PROCEDURAL_MODELING3
を参照
「幅、高さが1ユニットの、XY平面に広がる四角形」を、できるだけ色々なアプローチで書いてみましょう!
こちらでもいくつか作ってみました。 /project1/PROCEDURAL_MODELING3/exercises1
にあります
練習問題3
/project1/PROCEDURAL_MODELING4
を参照
同様にして、「中心に穴のあいた、ドーナッツのような円」を、できるだけ色々なアプローチで書いてみましょう!
これも、いくつか作ってみました。 /project1/PROCEDURAL_MODELING4/exercises1
にあります
まとめ
どうだったでしょうか?SOPを使ったモデリングでは、同じような形状を作るのにも色々なアプローチがあります。
それぞれのオペレーター自体には違った機能があるが、結果として同じような事ができるものがあります。ニッパーやペンチといった工具のようなものとして考えてしまってもいいかもしれません。違う工具を使っても同じ結果にたどり着く事はできます。違うのは、その処理に対して最適になるように設計して作られているかどうかです。
そして、仮に最適でない筋道を辿ることになっても、その後に続けたいエフェクトやアニメーションの処理によっては最適化されたオペレーターを使わないほうが結果的に最良の手になる時もあります。
これは語学におけるボキャブラリーにも似たような事が言えると思います。言い回しのバリエーションが増えるとより直接的な言い方、より遠回しで優雅な言い方など、豊富な表現ができるようになります。
Help
> Operator Snippets
には、さまざまなオペレーターの簡単な使い方がわかりやすくリストされています。オペレーターの使い方のボキャブラリーを増やすために、時間がある時にじっくりと観察してみるといいかもです 👍👍
頻出SOPの解説
このセクションでは、よく使うSOPのオペレーターをいくつか紹介していきたいと思います。
Group SOP
/project1/EDIT_GEOMETRY1
を参照
TouchDesignerのSOPでは、レイヤー的な仕組みがないため Merge SOP
などを使って一個のジオメトリにしてしまうと後から任意のポイントやプリミティブを編集するのが難しくなってしまいます。Group SOP
はそういったケースのために、Point, Vertex, Primitive に対してグループを設定するオペレーターです。
一度グループに指定すると、各SOPの Group
テキストボックスの中でターゲットとなるグループが選択できるようになります。特に各頂点の移動は、動かしたい頂点を一旦ポイントグループに追加してから Transform SOP
で移動させる、といった方法でないと(多分) 移動できないです。
また、Group
テキストボックスにはプリミティブのIDを入れることで、グループを作成しないでも同様の効果が得られるものがあります
Convert SOP
/project1/EDIT_GEOMETRY2
を参照
Convert SOP
はプリミティブのタイプを相互変換します。なのですが、経験上あまりちゃんとは動かない時が多いので
- MeshをPolygonに変換する
- PolygonのラインをNURBSやBezierに変換する
- PolygonをParticlesに変換する
あたりの時だけ使っています。困った時にとりあえずかましてみる、といった使い方が多いです
Facet SOP
/project1/EDIT_GEOMETRY3
を参照
Facet SOP
は頂点の分割、結合をしたり、法線の再計算をしたりします。ポリゴンそれぞれのスケールを変化させたい時や、法線の方向を調整してフラットシェーディングにしたい時などに使います。
SOPを使ったシーンの構築
/project1/CREATE_SOP_SCENE1
を参照
では、実際にこれまでやってきたSOPのノウハウをどういう風にして使っているかをハンズオン形式で解説したいと思います!
流れとしては、
- ソースとなるジオメトリを作る -> A
- ソースのジオメトリと同じポイント数の円を作る -> B
- AとBのポイントを
Add SOP
のDelete Geometry, Keep Points
でポイントだけにする Add SOP
に入れて、ポリゴンのラインプリミティブを作るResample SOP
で分割して1ラインあたり3点になるようにする- 新しく追加したポイントを
Group SOP
のGroup by Range
でグループ化する - グループに対して
Transform SOP
で位置を調整して、Convert SOP
で NURBS カーブに変換する
という感じになります。ラインに中点を追加してオフセット → NURBSに変換 のあたりが一番のポイントで、線のたるみのようなディテールが入ると急に「何かよくわからないけど物理的なもの」といった印象になります
インスタンシング
最後に、インスタンシングの幅を広げるTIPSを紹介したいと思います。
TouchDesignerは標準の機能でかなり簡単にGPUインスタンシングができますが、実はSOPとVertex Shader
だけでもだいぶ似たことができます。
さらにはSOPレベルでジオメトリを前処理することで、ただ数を増やすだけでなく、インスタンスごとに違うキャラクターになるようにジオメトリを変形することも可能です
通常のインスタンシング
/project1/INSTANCING1
を参照
こちらは通常のインスタンシングです。特に変わった事はなく、Y軸方向のスケールをそれぞれ Noise CHOP
からコントロールしています
静的インスタンシング
/project1/INSTANCING2
を参照
こちらはテクスチャの色情報を使って Vertex Shader
上でデフォームをしようというものです。なのですが、SOPレベルでUVの持ち方を工夫するだけで、Copy SOP
で増やしたジオメトリに対して全く同じシェーダーでアニメーションをつけることができます。
SOPレベルのアトリビュートを使ったGPUデフォーム
/project1/INSTANCING3
を参照
さらに、Point SOP
で定義したカスタムアトリビュートは GLSL MAT
のシェーダーの中で使うことができます。これによって Copy SOP
に入力するジオメトリの特定の部分にだけ影響を与えたり、任意のパラメーターを渡したりすることができます
おわりに
今回はSOPを中心に紹介してきましたが、なるべくSOPだけを使って… という風に考えてサンプルを作っていると、普段どれだけCHOPやTOPと連携させてSOPを使っていたかというのが切実に実感できました。。。
例えばオーディオビジュアルやモーショングラフィックを作る時だと、CHOPはエモーショナルな部分、SOPは形、シルエット、TOPは細かなディテール、というふうな使い方をすることが多いと思います。
ですが、TouchDesignerの一番のアドバンテージは、各種オペレータータイプをガシガシ変換しながら制作をしていける所だと思っています。なので、あえて今自分が苦手だなと感じるオペレーターも頑張って使い方を覚えることで他のオペレータでの作業も全体的にレベルが上がっていくのではないかと思います。
また、SOPに関して言うと TouchDesigner よりも Houdini のほうが圧倒的に学習のリソースが多いです。このワークショップに参加してSOPをもっと掘り下げたい!という人がいればHoudiniのほうも手を出してみるととてもいいと思います!
Tkanks! 🙌🙌🙌