Houdini シェーダによるテクスチャーの変調

以前、ラピュタに出てくるロボットをHoudiniでモデリングし
サブスタンスペインターでPBRテクスチャーを作成した。

Houdiniでポリゴンモデリング

その際、テクスチャーは金属層・ペイント層・腐食層の3つのレイヤーに分けて作成したが
今回はレンダリング時にシェーダでペイント層のテクスチャーをロボットごとに変化させ、
ロボットにカラーバリエーションを与えてみた。

以下はサブスタンスペインターで作成した金属層・ペイント層・腐食層のテクスチャー。

まず、サブスタンスペインターからテクスチャーをPSDファイルにエクスポートし
Photoshop内で腐食レイヤーのテクスチャーマスクを別ファイルとして保存。
これはシェーダ内から参照するためのサーフェイス上の錆(さび)の有無を示す情報になる。
今回はTGAファイルのアルファチャンネルに保存した。

次にHoudiniのSOP内でロボットごとにプリミティブに対してidアトリビュートを設定しておく。
これはCopyToPointsなどでポイントに対してロボットをコピーする際に
ターゲットポイントのidをもらってくるやり方で設定できる。(PointWrangleで@id = @ptnum;)
このidはロボットごとの識別番号となる。

idアトリビュートはプリミティブアトリビュートにプロモートしておく。
(後でシェーダ内のParameter VOPからこのidを参照するため)

そしてロボットに設定したPrincipledShaderのロックを外して中に入り、
さらに以下の図のノード(Surface Texturesカテゴリーのbasecolor)の中に入る。

上記の図の拡大(Surface Texturesカテゴリーのbasecolor)

中へ入ったら、元々接続されていたオレンジで示すラインを削除し、オレンジ枠内のVOPを新しく作成し接続。オレンジ枠内にはInline Code VOPとそれに対する入力となるParameter VOP、
テクスチャー読み込みのためのTexture VOPが作成されている。

Inline Code VOPはシェーダノードの中で唯一VEXを書けるノード。
Pameter VOPからの入力(各種テクスチャー、idアトリビュート)を取得し
最終的な色を計算する。VEX内の入力・出力には$記号を付けることに注意する。
ここで、腐食レイヤーのテクスチャーマスクを読み取り、
腐食している箇所の色はそのままにしておき、それ以外の箇所の色を変化させた。
乱数シード値をid(SOPで設定したロボットの識別番号)で固定させるのがポイント。

$color = $clr;// ベーステクスチャ
if($clr_2.w < 0.1) // 腐食テクスチャーのマスクをチェックし錆の有無を判定(閾値は適当)
{
    vector c = vector($color);// vector型へキャスト
    c = rgbtohsv(c);// HSV空間へ変換
    c.x += fit01(rand($id+100),-0.5,0.5);// 色相調整
    c.y += fit01(rand($id+200),-0.2,0.2);// 彩度調整
    c.z += fit01(rand($id+300),-0.2,0.2);// 明度調整
    c.x = clamp(c.x,0,1);// 0から1に制限
    c.y = clamp(c.y,0,1);
    c.z = clamp(c.z,0,1);
    $color = hsvtorgb(c);// RGB空間へ戻す
}
$color.w = 1;// アルファ