The Next Level Shading in TouchDesigner
この記事では主に最近作っているTouchDesigner用のシェーダー便利ツールである ShaderBuilder について解説します。
ShaderBuilderには2つの大きなポイントがあります。1つ目は、物理ベースレンダリング(PBR)マテリアル、もう1つは、再利用可能なコンポーネントベースのシェーダー実装プラットフォームとしての点です。
PBRマテリアル
最近のモダンなレンダラーは大抵 物理ベースレンダリング(PBR) と呼ばれる手法によってレンダリングをしています。それ以前はDiffuseシェーディングや、Phongシェーディングといったコンピューターで処理しやすい近似の式によってレンダリングを行っていましたが、そういったシェーディングでは照明条件によって見た目がだいぶ変わっていってしまうので、写実的なルックを上げていくのはCGアーティストの経験や裏技的な技法によってなされていました。
一方、物理ベースのシェーディングでは、基本色、メタリック、粗さ、などの数少ないパラメーターしか持たないにもかかわらず、ライトからの光の反射のふるまいに物理法則に基いたモデルを使うことで照明条件が変わってもリアルな一定の質感が出るように実装されています。
つまりは、使い方は今までのものとそんなにかわらないのにレンダリングの結果がリアルになる、ということです。ShaderBuilderもこの物理ベースのシェーディングを内部で実装しています。
PBRについての詳しい情報は↓のスライドが大変よくまとまっています。
単純なルックの向上以外にもPBRを使う利点はまだあります。先も述べたように、最近のモダンなレンダラーは大抵PBRを採用しています。ということは、物理世界を基盤にしているという点で、ShaderBuilderのマテリアルは、Blender や Cinema 4D、Houdini などのDCCツール。Substance Painter、Mariといったテクスチャリングツールなどと似たようなルックを持っていることになります。
ということは、3DCGのツール群でアセットをブラッシュアップすれば同じワークフロー上に乗るTouchDesignerのルックも同時に上がっていく、ということになります。3DCGのツール群はもちろんそういった作業向けに作られているので、色々と便利な機能がたくさんあります。それらをまるっと使えるということです。
ちなみに、TouchDesignerにも標準でPBR MATが入っていますが、ほかのレンダラーと出力を比較してみるとだいぶ違った結果になってしまうのがこれを作りはじめた動機としてありました。ShaderBuilderはBlenderのEeveeのレンダリング結果をリファレンスしながら、google/filament の実装を拝借して作っています。
ちなみにちなみに、FilamentのPBR実装に関するドキュメントはかなり充実していて大変勉強になります。。大オススメ Physically Based Rendering in Filament
基本的な使い方
satoruhiga/TouchDesigner-ShaderBuilder からダウンロードしてきて、ShaderBuilder.tox
をプロジェクトに追加します。二重に追加してしまうとエラーが出るので注意してください。配置する場所はどこでもいいのですが基本的にはトップレベルに置くといいと思います。
Ctrl(Cmd) + Shift + A
か Ctrl(Cmd) + Shift + B
でノード生成用のダイアログが開くので、作りたいノードをネットワークエディターにドラッグ&ドロップすると生成されます。
Principal
/project1/PRINCIPAL
を参照
Principal
はShaderBuilderのを使う上で一番基本的なオペレーターです。
一般的にPBRマテリアルと呼ばれるものの機能がこのオペレーターに入っており、パラメーターやテクスチャによって色々な質感を表現できます。
以下、パラメーターの説明です:
- Base Color
- マテリアルの基本となる色です。Albedoと呼ばれることもあります
- Metallic
- 材質が金属かそうでないかを指定します。0が非金属、1が金属です。基本的には0か1を指定して、中間の値は使わないほうがいいと言われています
- Roughness
- 材質の粗さのパラメーターです。0がツルツル、1がマットな質感を表現します
- Reflectance
- 材質の反射の強さのパラメーターです。基本的には0.5でいいですが、反射を強調したい時や抑えたくなった時に変更します。
- Emission
- 発光のパラメーターです。ライトの光があたっている/いないにかかわらず色がのるようになります
- Bump Scale
- ノーマルマップを貼った時のでこぼこの強さを指定できます
TOPの入力も上記パラメーターと同じような感じのものになっています。
ライティング
/project1/LIGHTING
を参照
ShaderBuilderのPBRマテリアルでは、Light COMP
による直接光と Environment Light COMP
による環境光の両方のライトを扱うことができます。
物理的な反射モデルを使っているので、ライトの明るさを変更しても陰影のつきかたが自然に見えます (まだ勉強が足りず怪しい部分もありますが…) シェーディングがちゃんとしているとライティングも楽しくなります!
ちなみに、ライティングの基礎を勉強するにはこの動画が滅茶苦茶いいです。解説しているのはBlenderでの話ですが、Blenderも物理ベースのレンダラーを採用しているので基本的な所は同じです。
ライティングも奥深い世界なので極めるには一生かかりそうな気配を感じますが、この動画で人生で一番ライティングが上手くなる40分間をすごせます!
シェーダーコンポーネント
PBRマテリアルはアーティスティックな方面のものでしたが、もう一点のシェーダーコンポーネントはもうすこしテクニカルな内容になります。
TouchDesignerの Phone MAT
や PBR MAT
には、現在の状態を GLSL MAT
へ変換する機能がついており、それによってマテリアルのおおまかなルックを決めた後で GLSL MAT
に書き出し、GLSLレベルで頂点情報や色情報などをいじることができます。ですが、その変換は1方向のみで、一旦 GLSL MAT
にしてしまった後で再度元のMATに戻してパラメーターを変更したりテクスチャを追加するといったことはできません。
以前にやったプロジェクトで、GLSLレベルでの頂点操作は必須なんだけどルックはMATでいじりたいという事がありました。その時は「PBR MAT
をGLSL MAT
に変換し、その後シェーダーコードをあらかじめ用意していたコードに置換する」といった処理をPythonで書いて対応したのですが、ここのあたりもっと便利にしたいよな~ という思いが強くあったので作った機能です。
BuildingBlock
/project1/BUILDINGBLOCKS
を参照
Ctrl(Cmd) + Shift + A
か Ctrl(Cmd) + Shift + B
で開くダイアログに BuildingBlock
というカテゴリがあります。ここに入っているものがシェーダーを構成する基本要素となっており、それらを組み合わせてマテリアルを作っていきます。BuildingBlockの各要素はそれぞれDATのワイアで接続されており、その中身はjsonのデータです。
たとえば、Generator
は入力されたjsonからGLSLコードを合成してマテリアルを作るコンポーネントです。入力された内容に不備があればこのコンポーネントのViewerにGLSLのエラーが表示されます。また、パラメーターウィンドウの View Vertex Shader
や View Pixel Shader
のボタンを押すと今の状態の合成されたシェーダーを見ることができます。
ClodeBlock
はGLSLコードを直接記述したり、テンプレート処理でコードを合成したりするコンポーネントです。Section
パラメーターを変更することで、生成されるGLSLコードのどの部分にコードを挿入するかを決めることができます。
以下、その他のコンポーネントの簡単な説明です
- Sampler
- シェーダーの中でテクスチャを使う用のサンプラーを定義します
- Uniform
- Uniform変数を定義します
- CustomAttribute
- SOPのアトリビュートのうち、シェーダー内で使いたいものの名前を入れると使えるようになります
- Merge
- 複数のBuildingBlockをまとめます
- Deform
- ボーンアニメーションに関する設定をします
- Settings
- ワイアフレーム、カリング、ポリゴンオフセットなど
MAT
のCommon
タブにある雑多なものを設定できます
各コンポーネントは最終的に Generator
で合成されてマテリアルになると書きました。ということは、独立した機能単位を切り出せれば再利用可能な機能のまとまりを作ることができます。
ShaderOP
/project1/SHADER_OP
を参照
BuildingBlock
を組み合わせたより高度な機能のカテゴリが ShaderOP
です。最初に使った Principal
もこのカテゴリのものです。
以下、その他のコンポーネントの簡単な説明です
- Principal
- 標準のPBRマテリアルです。一番下のインプットにはにBuildingBlockを入れることができます。
- Blending
- ブレンドモードを変更できます
- NormalMap
- ノーマルマップを定義できます。たぶん複数のノーマルマップも貼れる
- VertexDisplacement
- テクスチャによって頂点の位置を変位させます。ノーマルも更新するようにしたのがポイント
- DeformCacheTexture
- ボーンアニメーションをテクスチャにベイクして、その情報をもとにボーンアニメーションを動かせます。コンポーネントベースのものよりだいぶ早く、またインスタンシングで大量に描画できます
特にDeformCacheTexture
は取り扱いも難解でまだバグも多いですが、とにかく見た目の破壊力があります。。(現状、Mixamoの人のジョイントのメッシュがなぜか違う所にいってしまう問題を発見しました。。)
まとめ
ShaderBuilderの機能について解説してきました。まだまだ不具合や足りてない機能などありますが、とりあえずはだましだまし実用レベルで使えております。
今後の展開としては:
- UV座標のプロジェクションタイプを選べるようにしたい(Texture SOP相当の機能)
- Experimentalの2019.33020にてライトの減衰(TDAttenuateLight) が実装されたようなのでStableになり次第対応
- IBLのライティングが微妙にあやしいのでどうにかしたい
- 半透明オブジェクトのDraw Priorityを自動で調整する仕組みが欲しい
- Geometry Shaderを使えるようにしたい
- 同じワークフローで
GLSL TOP
のほうもコンポーネントベースで使えるようにしたい
などなどを考えています。
もし使ってみて気付いた点、バグ報告などがあればGitHubのissueにてお気軽にお知らせください!