はじめに
Houdini 20.5からベータ版として新たな画像処理フレームワークCopernicusが追加されましたね
実用性があるかはさておき、勉強がてらMantraやKarmaを使わずCopernicusのみで簡単なトゥーンレンダリングを行ってみました
まだ私もCopernicusを触り始めたばかりなので何かおかしい点があるかもしれません。気付いた点があればご指摘いただけると幸いです。
本記事で使用しているHoudiniのバージョンは20.5.278です
本記事で作成したHIPファイルはこちらです

ベースシーンの作成
カメラがラバートイのまわりを旋回する簡単なシーンを用意しました。ライトの種類はDistantです


ジオメトリのラスタライズ

このセクションではジオメトリの情報をレイヤ(画像のPlane)としてラスタライズします。
一番はじめの手順にして今回のCopernicus解説のなかで一番面白い機能です。
まずCOP Networkを作り、SOP ImportでジオメトリをCOPに持ってきます。

Rasterize Setupはジオメトリの座標を調整したり、法線やDepthを作成したりするノードです。
今回のラバートイには法線アトリビュートが無かったので、ここで作成します。

Camera ImportでカメラをCOPに持ってきます。
ディスプレイフラグをONにすると、カメラがある位置に黒い平面が表示されます。

Rasterize Geometryはあるカメラから見たジオメトリの情報をレイヤにラスタライズするノードです。
Quick Setups↓をクリックするとラスタライズする情報の一例が選択できます。ジオメトリに存在するアトリビュートであればここに無いアトリビュートもラスタライズできます。

今回はQuick SetupsからN Alpha Depth from eyeを選択しました。
NがAttirbutesの一番上にあるのでレイヤにカメラから見たラバートイの法線が表示されていることがわかります。
これまでもSOPでpointを作ってrayを飛ばしてprimuvでアトリビュートを参照して...みたいなことで似たことはできましたが、COPだけでその処理が行えるのは便利ですね。

Match Cameraは、あるレイヤを他のカメラ空間に変換するノードですが、二番目のcamera_ref入力に何も指定しないとXY平面に戻されます。
これですべてのレイヤをXY平面に戻します。

(ちなみにこの変換をレイヤごとではなく一括で行う方法ってあるんでしょうか...ご存じの方がいれば教えて下さい)
シェーディングと着色
ライト方向ベクトルの定義
シェーディングを計算するためにはライト方向ベクトルが必要なのですが、Copernicusではライトの情報は取得できないようです。普通にConstantで特定の向きのライトを定義してやってもいいのですが、直感的じゃないし調整もしづらいので、obj階層のライトの回転を参照することにします。
まず普通にobj階層でdistantライトをTransform無しで作成すると、ライトは(0,0,-1)の方向を向いていることが分かります。

ライト方向ベクトルは光子が光源から進む方向ではなく、照らされる面から光源に向けたベクトルなので、Constantでライトの向きに-1を掛けた(0,0,1)を入力します

Vector Transformでライト方向ベクトルを回転させます。このときRotateチャンネルでobj階層のライトの回転を参照することで、回転が連動するようになります

つまりCOPのカメラ方向ベクトルをハンドルで制御できることになります

内積の計算
Dot Productで法線とライトの内積を計算します。これで光源と同じ向きの面は1、正反対の面は-1の値が返されます。


(画像引用元:【連載】Unity時代の3D入門 – 第5回「拡散反射ライティング」)
Lambert shadingの説明はggればいくらでも出てくるので、詳しく知りたい方は調べてみてください。
色の調整
色を調整しやすくするために色のレンジを(-1,1)から(0,1)にRemapします

Rampで色のグラデーションを変えます。今日は猛暑日だったので涼しげな色にしてみました

Rampパラメータの右上に並んでるアイコン達の一番左のアイコンをクリックすると補間モードが変えられます

背景色の合成
BlendのModeをOverにして前景レイヤーを背景レイヤーに重ねます。
maskにはジオメトリのラスタライズのときに作ったAlphaを接続します。

エッジの作成
Copernicusでエッジを作成するにあたり、複数のノードがあるようです。
今回はとりあえず無難にDepthから作成することにします。

DepthをEdge Detect by Depthに接続するとエッジが出ます。

エッジのところは真っ白にしたかったのでremapでホワイトレベルを下げます。

Blendノードを使い、エッジをシェーディングしたラバートイに重ねたら出来上がり!

おわりに
今後の正式版実装が楽しみなフレームワークです![]()
従来のCOPよりも遊びがいがありそうです。
OpenCLノードもあるのでゴリゴリコードを書くのも楽しそうですね。



