カテゴリー: KATANA

CG, KATANA

GroupStack

作業をする際、多くの種類のマテリアルをアサインしたり、ショットシーンで大量のアセットを読み込んでそれぞれに Lookfile をアサインしたくなります。
これまでやっていたように、一つ一つ MaterialAssign ノードなどを作成してそれを繋げてもできるのですが、ノードグラフが無駄に長くなりますし、管理も煩雑になってしまいます。

このような問題に対応するため、GroupStack ノードが用意されています。

たとえば、下図のように複数の MaterialAssign が連なっているケースを例にしてみます。

これでも要求は満たしていますが、見た目も良くありませんし、MaterialAssign ノードを増減するために Node Graph を更新しなければいけないので管理も煩雑です。

そこで GroupStack ノードを作って MaterialAssign ノードを選択し、Shift+中ボタンクリックでドラッグアンドドロップします。


すると、GroupStack ノードに MaterialAssign ノードの情報が登録されました。GroupStack ノードを元々あった場所に繋げると、元と同じ状態になります。

GroupStack ノードは一つのノードに対して同じ種類のノードを複数登録できます。反面、異なる種類のノード(MaterialAssign と LookfileAssign とか)を一つのノード中に含めることはできないです。また、登録できるノードの種類は一入力一出力のものに限られます。このあたりは、ノードの性質を考えれば妥当な仕様ですね。

CG, KATANA, USD

USD for KATANA

USD のリポジトリには KATANA 用プラグインも含まれています。ビルドも難しくなく、KATANA プラグインビルド用のオプションを追加して USD をビルドするだけですんなりいけます。

ビルドができたら、KATANA が USD プラグインを認識できるように起動スクリプトに手を加えます。私はこのようにしました。

#!/bin/sh

export KATANA_ROOT=/opt/Katana3.0v6
export DEFAULT_RENDERER=arnold
export USD_INSTALL_ROOT=/opt/usd

export KTOA_ROOT=/opt/KtoA-2.2.1.0-kat3.0-linux
export "KATANTA_TAGLINE=With KtoA 2.2.1.0"

export KATANA_RESOURCES=$USD_INSTALL_ROOT/third_party/katana/plugin:$KTOA_ROOT
export KATANA_POST_PYTHONPATH=$USD_INSTALL_ROOT/third_party/katana/lib:$KATANA_POST_PYTHONPAT

export PATH=$KATANA_ROOT/bin:$KTOA_ROOT/bin:$PATH
export PYTHONPATH=${KTOA_ROOT}/python:$USD_INSTALL_ROOT/lib/python:$PYTHONPATH

$KATANA_ROOT/bin/katanaBin "$@"

KATANA を起動すると、PxrUsd から始まる名前のノードが選べるようになっています。

PxrUsdIn でサンプルシーンを読んでみました。
※ZUp なようなので、TransformEdit で X 軸に -90° 回転を加えています

これで、KATANA でも USD を使用することができるようになりました。

CG, KATANA

Live Render とオブジェクトの選択

KATANA では、膨大なデータを極力読み込まずに作業をすることでオペレーションを軽快におこなうことができるような造りになっています。

そのため、 Scene Graph を展開しても最後のジオメトリになるまでは Viewer 上でもバウンディングボックス表示のままになっていたりします。

ただ、これだと自分が操作したいオブジェクトがどこにあるかわかりません。それを知るためには結局全データを読み込んで確認しなければいけないんじゃ。。。?と思ってしまいそうですが、これに対する答えもきちんと用意されています。

その答えというのが、レンダリングした画像からオブジェクトをピックするという方法です。

まず、レンダリングしたいノード上で右クリック→ Live Render を選びます。

Live Render モードの時は、カメラやライト、カレントフレームなどを変更するとインタラクティブにレンダリング結果が更新されるモードになります。注意点として、変更全てに対して即座に反映されるわけではないことです。たとえばシェーダの値を更新したとしても Viewer には反映されません。

この Live Render モードの時、 Monitor には十字のカーソルが表示されます。このカーソルを移動すると、カーソル位置にあるオブジェクトの名前が表示されます。

ここで、オブジェクト名左の矢印アイコンをクリックして Select in Scene Graph を選びます。

すると、Scene Graph がそのオブジェクトまで展開されて選択されます。Scene Graph が展開されると、そのツリーのオブジェクトが Viewer にも表示されます。

このようにして、全てのデータを読み込まなくてもレンダリングした画像から自分が必要としているオブジェクトを選ぶことができます。

もちろん、このような方法を使わずにデータを全て読み込んでそこから選ぶ方法を取ることもできますが、想像力とツールの力を生かして操作をおこなうことで段違いの生産性を発揮することができるでしょう。

CG, KATANA

VariableSwitch

ショットの作成をする場合、異なるショット(カット)でも、一連の流れの中ではほとんど同じ設定で映像を構築します。このようなときにファイルをショット毎に分けて管理してしまうと、途中で設定を変更したときに全てのファイルを間違いなく更新するのはとても大変な作業になってしまいます。

KATANA では、大元になる設定を作ってからショット毎に調整が必要な部分だけ分岐することで、一つの .katana ファイル中で関連する複数のショットを作成することができるようになっています。

こうすることで、大元の設定が変わった場合でも一か所を変更するだけで対応でき、かつショット毎の細かい調整もおこなうことができます。

これを可能にするのが VariableSwitch ノードです。

まず、VariableSwitch ノードを作成して variableName を shot にし、patterns を三つ作成してそれぞれ 10, 20, 30 とします。

更に、カメラを三つ作成してそれぞれを VariableSwitch に接続します。

続いて、Project Settings タブ中の variables で先ほど作成したのと同名(shot)の変数を variables に追加します。

これで、shot 10, 20, 30 のカメラを一つのシーン中で切り替える準備ができました。

カメラを切り替えるには先ほどの Project Settings タブ中でもできますが、メインメニューにも値が表示されているため、ここで切り替えることもできます。

ここをクリックすると値をセットするための GUI が表示されます。最初は値の部分は空なので手で入力する必要がありますが、一度入力した値はプルダウンメニューから選ぶことができます。

このようにして作成したシーンで値を切り替えてみます。

このように、variable の shot の値を変えることで使用するカメラを切り替えることができます。

CG, KATANA

LiveGroup

Maya で言うリファレンスのように別に作成されたデータを読み込んでシーンを構築する方法が KATANA にもあります。これを LiveGroup と言います。

LiveGroup を使用するには、まずノードをグループ化します。グループ化したいノードを選んで ‘g’ キーを押すと Group が作成されます。

続いて、グループを LiveGroup 化します。これはグループ上で右クリック→Convert to LiveGroup でできます。

こうすると、アイコンに雷マークがつきます。この LiveGroup 化したノードをファイルに出力します。ノードの上で右クリック→Publish で出力できます。

この時出力されたファイルは .livegroup という拡張子になり、通常の .katana とは分けて考えられます。

このファイルを使用してシーンを構築します。LiveGroup の読み込みは File メニューから Import LiveGroup でおこなえます。

その他必要なノードを構築します。LiveGroup は Group とほとんど同じですが、中のノードがロックされています。

ここで、元のシーンに Teapot を追加して再度 Publish します。

そして、LiveGroup を読み込んでいるシーンで Reload をします。

無事に LiveGroup の内容が更新されました。

このように、アセット作成や Lookdev、アニメーション作成やライティングといった作業フェーズ毎にファイルを分け、成果物を .livegroup ファイルとして出力することで一つの最終シーンをあたかも複数人が同時に更新をおこなっているかのようなパイプラインを組むことができます。

CG, KATANA

XMLファイルを使ってショットシーンを構築する

Importomatic ノードで XML ファイル経由でアセットを読み込むことができたので、もう少し複雑なシーンも構築してみます。

使用するネタは CGWorld.jp の記事で使用したシーンです。この時は USD 形式でき出力しましたが、やることはまあ同じなので何となくパラメータを読み替えつつ XML ファイルで出力するようにします。


xml_tmpl = r'''
<scenegraphXml name="Zombie_OnFire" version="0.1.0">
  <!-- channelData startFrame="1" endFrame="10" 
      ref="/tmp/myChannelData" / -->
  <instanceList>
    %s
  </instanceList>
</scenegraphXml>
'''

instance_tmpl = r'''
    <instance type="reference" name="%(name)s" refType="abc" refFile="%(path)s">
      <xform value="%(xform)s"/>
    </instance>
'''

import maya.cmds as cmds

nodes = []
for r in cmds.ls(type='reference'):
    if r == 'sharedReferenceNode':
        continue

    fn = cmds.referenceQuery(r, filename=True)
    ns = cmds.referenceQuery(r, namespace=True)[1:]
    path = cmds.referenceQuery(r, filename=True, withoutCopyNumber=True)
    root = cmds.ls('%s:*_root' % ns)
    xform = cmds.getAttr('%s.worldMatrix' % root[0])
    nodes.append(instance_tmpl % {'name' : ns,
                                  'path' : path,
                                  'xform' : str(xform)[1:-1]})

fp = open(r'/home/chiyama/Documents/katanta/scene_build/layout.xml', 'w')
fp.write(xml_tmpl % '\n'.join(nodes))
fp.close()

このようにして出力したファイルを KATANA で読むと、Maya 上でレイアウトしたシーンを再現することができました。

※そのままでは見た目がよくわからなかったので、全てのオブジェクトにグレーなマテリアルを割り当てています

CG, KATANA

Importomatic ノードでアセットを読み込む(2)

昨日はアセット用 .abc ファイルと、それに使用する .klf ファイルを一つづつ選んでシーンを構築してみました。

が。

そんなことを実際のシーンでやっていたらめんどくさくて禿げちゃいます。アセット100個、名前を指定しながら読み込むとか無理デスヨネー。
しかも、Maya など前段階の作業でアセットの読み込みはしているため、どのアセットが必要なのか既にわかっているはずです。その情報をそのまま使いたいというのが人情です。

そんな時には XML ファイルを使用して Importomatic ノードでアセットを読み込むことができます。

まず、シーン構築用の XML ファイルを用意します。


<scenegraphXml name="Zombie_OnFire" version="0.1.0">
  <instanceList>
    <instance type="reference" name="zombie" refType="abc"
              refFile="/home/chiyama/Documents/katanta/scene_build/Zombie_OnFire_2B.abc">
      <xform value="1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"/>
      <lookFile ref="/home/chiyama/Documents/katanta/scene_build/zombie_on_fire.klf" />
    </instance>
  </instanceList>
</scenegraphXml>

そして、これを Importomatic ノードで読み込みます。

無事にアセットは読み込まれたのですが、マテリアルがついてきていません。これは Scene Graph の階層構造が変わってしまってるためでしょう。この辺りは何度か手戻りを繰り返しながら良い感じになるように Lookdev 用ファイルを作り直したり XML ファイルをみなおして調整する必要があります。

まだちょっと調整が必要ではあるものの、これでレイアウトやアニメーションの時に作成した情報を元にアセットを集めてシーンを構築するためのメドがついたことになります。

CG, KATANA

Importomatic ノードでアセットを読み込む

ショットシーン構築のためにアセットを読み込む方法を試行錯誤していたところ、KATANA 警察の方から Importomatic というのがあるよッ!!というのを教えていただきました。どうやらこのノードをパイプラインに合わせてゴリゴリいじれば良さそうです。

ということで複数の .abc ファイルを読んでみました。

なるほどこれは簡単。そして、Look File のアサインもここでおこなうことができるようです。

アセットの読み込みと Look File のアサインの方法がわかったのでやってみます。

。。。。と、その前に。Importomatic を使用してシーンを構築する場合、Look File 作成時にも Importomatic を使用してアセットを読み込んでおいた方が良いようです。もしかしたら、ちゃんとやれば Alembic_In で読んでいてもいいのかもしれないですが私のケースでは Importomatic で読んだアセットに対して Look File を作らないとマテリアルが再現されませんでした。Attribute も確認したのですが、違いを見つけることができなかったので何故こうしなければいけないのかは謎です。

このようにして作成した .klf ファイルを使ってマテリアルをアサインし、レンダリングしてみました。無事に再現されています。

CG, KATANA

OpScript を使ってアセットを読み込む

昨日の記事ではゴリゴリと Node Graph を編集する形でアセットを読み込む方向で進めてみたんですが、私のゴーストがこっちじゃないと囁くんでもうちょっとスマートな方法を調べてみることにします。

多分、KATANA 的にはショットシーンの雛形もあんまりゴリゴリ自動生成しないで、メタデータなりなんなりを読み込んで最初のシーンを構築するんじゃないかと思います。多分。

これには、OpScript で複数の .abc ファイルを読み込みつつ Scene Graph を構築する方法が確立できればいいんじゃないかということでチョチョッと調べます。

とりあえず .abc ファイルを一つだけ読み込むには

local argsGb = GroupBuilder()
abcFile = "/home/chiyama/Documents/usdtest/assets/Zombie_OnFire_2B.abc"
argsGb:set('fileName', StringAttribute(abcFile))
Interface.ExecOp('AlembicIn', argsGb:build())

こんなことをすればいいようです。

ExecOp で AlembicIn ノードを作ってデータを読み込んでいるっぽいことはわかったので、引数で良い感じにファイルを読み込む Scene Graph のパスを指定すれば複数のアセットを読み込むことができるんじゃないかとおもいます。

ちょっと謎なのが、KATANA でのノードの Alembic_In とは必要な引数名が異なるので、どのように読み替えればいいのかがわからないところです。

この部分が解決すればやりたいことはできるんでしょうが、生憎今日はここまでで閉店ガラガラ~。

CG, KATANA

アセット読み込みテンプレートの作成

※エイヤッと記事にはしたものの、どうもこの方法でショットシーンを作ることは無さそうです。まあテクニックの一つとしてこんなこともできるんだ的な感じということで;;;

ショットシーンを構築する際、一つ一つ手でアセット読み込み用のノードグラフを作ってファイルを読んで。。。とやっていたら大変すぎます。そこで、アセット読み込み用のテンプレートを用意し、スクリプトを使ってアセットの読み込みをできるようにします。

KATANA の場合、Alembic ファイルを読み込んだり LookFile をアサインするといった定例処理をノードとして組むので、CG ソフトのように Export Selection と Import や Merge をやる方法では対応できなさそうです。このあたりは 3DCG ツールというよりも Nuke のようなコンポジットソフトに感覚が近いです。

さてどうするかな。。。。と調べていたら、ノードの情報を XML 形式で入出力できるようです。これがきちんと動くなら、使えそうです。

まずは元になるノードグラフを作成します。今回はターンテーブル作成に使用したものを使います。

この、Alembic_In, LookFileAssign, LookFileResolve を使用します。

Python タブで以下のコードを実行すると、/home/chiyama/Documents/katanta/scene_build/template.xml に上記三つのノード情報が格納されたファイルが作成されます。

from Katana import NodegraphAPI
nodes = [NodegraphAPI.GetNode('Alembic_In'),
         NodegraphAPI.GetNode('LookFileAssign'),
         NodegraphAPI.GetNode('LookFileResolve')]

xmlNode = NodegraphAPI.BuildNodesXmlIO(nodes)

fp = open('/home/chiyama/Documents/katanta/scene_build/template.xml', 'w')
fp.write(xmlNode.writeString())
fp.close()

試しにこのファイルをそのまま使ってシーンにノードを作ってみます。空のシーンで

fp = open('/home/chiyama/Documents/katanta/scene_build/template.xml', 'r')
xmlData = fp.read()
fp.close()

xmlNode, result = NodegraphAPI.LoadElementsFromString(xmlData)
newNode = KatanaFile.Paste(xmlNode, NodegraphAPI.GetRootNode())[0]

と実行すると、見事にノードグラフが再現されました。

ここまでくればもう好きにやりたい放題です。

今回は以下のようなテンプレートファイルにしました。


<katana release="3.0v6" version="3.0.1.000002">
  <node name="__SAVE_exportedNodes" type="Group">
    <node baseType="Alembic_In" name="%(NAMESPACE)s_Alembic_In" selected="true" type="Alembic_In" x="413.984309" y="-302.346567">
      <port name="out" type="out"/>
      <group_parameter name="%(NAMESPACE)s_Alembic_In">
        <string_parameter name="name" useNodeDefault="false" value="/root/world/geo/%(NAMESPACE)s"/>
        <string_parameter name="abcAsset" useNodeDefault="false" value="%(ABC_FILE)s"/>
        <number_parameter name="addForceExpand" value="1"/>
        <string_parameter name="addBounds" value="root"/>
        <number_parameter name="fps" value="24"/>
        <number_parameter name="addToCameraList" value="0"/>
        <group_parameter name="timing">
          <string_parameter name="mode" value="Current Frame"/>
          <number_parameter expression="globals.inTime" isexpression="true" name="holdTime"/>
          <number_parameter expression="globals.inTime" isexpression="true" name="inTime"/>
          <number_parameter expression="globals.outTime" isexpression="true" name="outTime"/>
        </group_parameter>
        <group_parameter name="advanced">
          <number_parameter name="useOnlyShutterOpenCloseTimes" value="0"/>
        </group_parameter>
      </group_parameter>
    </node>
    <node baseType="GenericAssign" name="%(NAMESPACE)s_LookFileAssign" selected="true" type="LookFileAssign" x="413.084537" y="-370.293177">
      <port name="input" source="%(NAMESPACE)s_Alembic_In.out" type="in"/>
      <port name="out" type="out"/>
      <group_parameter name="LookFileAssign">
        <string_parameter name="CEL" value="(/root/world/geo/%(NAMESPACE)s)"/>
        <string_parameter name="location" value=""/>
        <group_parameter name="args">
          <group_parameter name="lookfile">
            <group_parameter name="asset">
              <number_parameter name="enable" value="1"/>
              <string_parameter name="value" value="%(KLF_FILE)s"/>
              <string_parameter name="default" value=""/>
              <string_parameter name="type" value="StringAttr"/>
            </group_parameter>
          </group_parameter>
        </group_parameter>
      </group_parameter>
    </node>
    <node baseType="LookFileResolve" name="%(NAMESPACE)s_LookFileResolve" selected="true" type="LookFileResolve" x="413.084529" y="-420.346567">
      <port name="A" source="%(NAMESPACE)s_LookFileAssign.out" type="in"/>
      <port name="out" type="out"/>
      <group_parameter name="LookFileResolve">
        <string_parameter name="passName" value=""/>
      </group_parameter>
    </node>
  </node>
</katana>

そして、以下のコードを実行します。

fp = open('/home/chiyama/Documents/katanta/scene_build/template.xml', 'r')
xmlTemplate = fp.read()
fp.close()

xmlData = xmlTemplate % {'NAMESPACE' : 'foobar',
                         'ABC_FILE' : '/home/chiyama/Documents/usdtest/assets/Zombie_OnFire_2B.abc',
                         'KLF_FILE' : '/home/chiyama/Documents/katanta/lookdev/zombie_on_fire.klf'}

xmlNode, result = NodegraphAPI.LoadElementsFromString(xmlData)
newNode = KatanaFile.Paste(xmlNode, NodegraphAPI.GetRootNode())[0]

できたノードグラフはこちら。

これで、ネームスペースと .abc ファイル、.klf ファイルを指定してアセットを読み込むことができるようになりました。これを使えば Katana 上でショットシーンを自動生成することはできそうです(これが一般的な方法かはわからないのですが)。