記事の目次

    みなさんこんにちは。8月はSIGGRAPH 2018があったため、大きなニュースもモリモリ発表されてきました。最も大きなニュースだと感じたのは Academy Software Foundation(ASWF)発足のニュースです。企業を超えてオープンソースソフトウェアの開発・運営を行うことを後押しする団体ができるというのはすごいことです。このニュースに関してはTechCrunch日本語の記事にもなっています。われわれもこの流れに乗ることで大きな恩恵を受けられますが、そのためには流れに乗るための技術を日々磨いていかなければいけません。皆さんがんばりましょう!!

    TEXT_痴山紘史 / Hiroshi Chiyama(日本CGサービス
    EDIT_尾形美幸 / Miyuki Ogata(CGWORLD)

    USD環境の更新

    8月の頭にUSDがバージョンアップし、v18.09になりました。一気に正式版っぽいバージョンになったのと、前回docker-usdで構築した環境ではAlembicを正常に扱うことができないとわかったのでUSD環境を更新します。

    docker-usdから変更する点は以下の2つです。

    • ・USD_VERSIONを18.09に書き換え
    • ・USDのビルド方法を標準の手順に置き換え

    また、8/12時点でIntel TBBの4.4.6がWebサイトから消えてしまっており、ビルドに失敗するようになっていたので、代わりに4.4.5を使用するようにもします。

    USD_VERSIONの書き換えは前回と同じです。

    $ vi centos7/usd/Dockerfile
    
    # 18.09 に書き換え
    ENV USD_VERSION "18.09"
    

    USDのビルド方法の変更は以下の通りです。

    $ vi scripts/build_usd.sh
    
    (中略)
    
        # cd build && \
        sed 's$https://github.com/01org/tbb/archive/4.4.6.tar.gz$https://github.com/01org/tbb/archive/4.4.5.tar.gz$g' build_scripts/build_usd.py > build_scripts/build_usd_modify.py
    
        python build_scripts/build_usd_modify.py --alembic $BUILD_DIR/usd/${USD_VERSION}
    
        #cmake \
        #  -DCMAKE_INSTALL_PREFIX=$BUILD_DIR/usd/${USD_VERSION} \
        #  -DCMAKE_PREFIX_PATH=$BUILD_DIR \
        #  -DPXR_BUILD_TESTS=ON \
        #  -DOPENEXR_LOCATION=$BUILD_DIR \
        #  -DPTEX_INCLUDE_DIR=$BUILD_DIR/include/ptex \
        #  -DOIIO_BASE_DIR=$BUILD_DIR \
        #  -DOPENSUBDIV_ROOT_DIR=$BUILD_DIR \
        #  -DDOUBLE_CONVERSION_INCLUDE_DIR=$BUILD_DIR/include \
        #  -DDOUBLE_CONVERSION_LIBRARY=$BUILD_DIR/lib/libdouble-conversion.so \
        #  -DPTEX_LIBRARY=$BUILD_DIR/lib/libPtex.so \
        #  -DGLEW_INCLUDE_DIR=$BUILD_DIR/include/GL \
        #  -DGLEW_LIBRARY=$BUILD_DIR/lib/libGLEW.so \
        #  -DPXR_MALLOC_LIBRARY:path=$BUILD_DIR/lib/libjemalloc.so \
        #  -DPXR_BUILD_ALEMBIC_PLUGIN=ON \
        #  .. && \
        #make -j ${BUILD_PROCS} && \
        #make install && \
    
    (後略)
    

    あとは前回と同様にbuild-centos7.shを実行すればいいです。注意点としては、標準のビルド処理を使用するとビルド時の標準出力の結果が表示されないため、処理が走っているのか、何かの理由で止まっているのかわかり辛いことが挙げられます。今回はとりあえずtopで様子を見ながら、大体これくらいの時間で終わるだろうなという目星をつけて放置しておきました。

    このようにして環境をつくり、Mayaから出力したアニメーション付きのAlembicファイルをusdviewで再生できることを確認しました。

    ※前述のファイルは、Mocap Onlineから提供されているテスト用のフリーデータを使用し、Mayaから.abcファイルに出力しています。

    USDシーンを作成してみる

    USD環境ができたので、シーンを作成してみます。


    ・アセットの準備

    アセットを一からつくっていると大変なので何かいいデータはないかなと探したところ、Highend3DAnimator Starter Pack(For Short Films or Animations)Final 6.0.0 for Mayaを見つけました。これは無料でどのような目的にも使用できるアセットが100個以上詰まった、ものすごく有難いデータ集です。今回はこれを使わせていただきます。

    このままではただのMayaデータなので、Alembicファイルに変換します。以下のスクリプトをMaya上で実行するとsrcディレクトリにあるファイルをabcファイルに変換してdestに保存します。

    import os
    import maya.cmds as cmds
    
    src = r'/home/chiyama/Documents/usdtest/assets/Street Walk Scene/scenes'
    dest = r'/home/chiyama/Documents/usdtest/assets/Street Walk Scene/cache/alembic'
    
    def getTops():
        ret = []
        for t in cmds.ls(type='transform'):
            p = cmds.listRelatives(t, parent=True)
            if p is not None:
                continue
            if t in ['front', 'top', 'side', 'persp']:
                continue
            ret.append(t)
    
        return ret
    
    for f in os.listdir(src):
        prfx, ext = os.path.splitext(f)
    
        cmds.file(os.path.join(src, f), open=True, force=True)
        tops = getTops()
    
        g = cmds.createNode('transform' ,n='%s_root' % prfx )
        cmds.parent(*(tops + [g]))
    
        fname = os.path.join(dest, '%s.abc' % prfx)
        cmd = '-frameRange 0 0 -uvWrite -root %s -file "%s"' % (g, fname)
        cmds.AbcExport ( j = cmd )
    

    ただ、Mayaから出力したabcファイルをそのままusdviewで見てもsubdivisionが再現されないようです。usdviewで確認したときに、本来はオブジェクトのsubdivisionSchemeプロパティがcatmulClarkになっていてほしいのですが、どうやってもnoneになってしまいます。いろいろ試行錯誤したのですがどうにも上手くいかなかったので、今回は以下のような感じでabcファイルをusdファイルに変換しつつ、このプロパティを書き換えてしまいます。

    $ cat setSubdivision.sh
    #!/bin/sh
    
    for f in *.abc
    do
      d=$(echo $f | sed "s/abc/usd/g")
      echo $f
      usdcat $f | sed 's/subdivisionScheme = "none"/subdivisionScheme = "catmullClark"/g' > $d
    done
    $
    

    このようにして出力したものと、元の.abcを横に並べてusdviewで確認してみました。.abc版では下図の通りsubdivisionSchemeがnoneになっています。


    今回はソフトウェアの制限など諸々の条件があったので、Maya上の作業では.abc版を使用して、ライティングやレンダリング環境では.usd版を使用します。

    次ページ:
    USDシーンを作成してみる
    ・レイアウト

    [[SplitPage]]

    USDシーンを作成してみる

    ・レイアウト

    用意した.abcファイルをリファレンスしてMaya上でレイアウトします。これは通常のMayaでの作業と変わらないです。


    ・MayaからUSDファイルを出力する

    USD Mayaプラグインを使用するとMayaから簡単にUSDファイルを出力できます。ただ、この方法だとリファレンスしたabcファイルの内容も丸々入った形式でしか出力できないようです。特に何も考えなくても別のアプリケーションにデータをもっていけるので楽といえば楽なのですが、せっかく分けて作成したアセットを活用できないので、パイプラインに組み込むときは各自自前の出力ツールを作成するのがよさそうです。

    ということでつくってみましょう。今回は単純な例なので、以下の2つが出力できればシーンは再現できます。

    • ・リファレンスしているabcファイル
    • ・トップノードの位置情報

    このあたりは前回使用したKitchen_setやUSDのドキュメント、それからチュートリアルを参考にしながらスクリプトを書いていきます。

    最終的に以下のようになりました。

    $ cat exportLayout.py
    usdtmpl = r'''
    #usda 1.0
    
    def Xform "World" (
        kind = "assembly"
    )
    {
    %s
    }
    '''
    
    nodetmpl = r'''
        def Xform "%(name)s" (
            references = @%(path)s@
        )
        {
            double3 xformOp:translate = %(trs)s
            float3 xformOp:rotateXYZ = %(rot)s
            float3 xformOp:scale = %(scl)s
            uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"]
        }
    '''
    
    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)
        trs = cmds.getAttr('%s.translate' % root[0])[0]
        rot = cmds.getAttr('%s.rotate' % root[0])[0]
        scl = cmds.getAttr('%s.scale' % root[0])[0]
        nodes.append(nodetmpl % {'name' : ns,
                                 'path' : path,
                                 'trs' : trs,
                                 'rot' : rot,
                                 'scl' : scl})
    
    fp = open(r'/home/chiyama/Documents/usdtest/assets/layout.usd', 'w')
    fp.write(usdtmpl % '\n'.join(nodes))
    fp.close()
    
    $
    

    これをMaya上で実行すると、リファレンスしているアセットとそのトップノードの位置情報を含んだ.usdファイルを生成します。このようにすることで、Maya USDプラグインを使用すると百数十MBになってしまったショットデータのサイズを、数KBに抑えることができました。

    出力したシーンをusdviewで確認してみます。


    無事に再現されているようです。各アセットもきちんと外部の.usdファイルがリファレンスされています。このようにアセットがリファレンスされていると、このシーンを元にライティングやレンダリングを行なっている間にも、ほかの人がアセットをどんどん更新できます。

    ちなみに、この.usdファイルをMayaでリファレンスすることもできます。この場合、各アセットはリファレンスのリファレンスになるわけではなく、シーン全体がひとつのリファレンスとして扱われるようです。インポートも同様で、各アセットもインポートされます。

    前述のように、今回の記事でもusdviewを多用しています。使用してみるとわかるのですが、このツールは本当に頼れる相棒という感じです。何かデータに疑問があったら、とりあえずこれで開いて確認するという使い方を頻繁にしています。特に自分でエクスポータを書くような場合は、usdviewを使うことで格段に効率がよくなります。

    次回予告

    次回は出力したシーンのライティングやレンダリングを行なっていきます。これが終われば、USDを使用したワークフローを最初から最後まで一通り体験したことになります。ここで使用するのはImage Engineが開発・使用しているオープンソースのlookdev/lightingツールのGafferです。Gaffer は『キングスグレイブ ファイナルファンタジーXV』の記事でも取り上げられている、非常に強力なツールです。



    第5回の公開は、2018年10月を予定しております。

    プロフィール

    • 痴山紘史
      日本CGサービス(JCGS) 代表

      大学卒業後、株式会社IMAGICA入社。放送局向けリアルタイムCGシステムの構築・運用に携わる。その後、株式会社リンクス・デジワークスにて映画・ゲームなどの映像制作に携わる。2010年独立、現職。映像制作プロダクション向けのパイプラインの開発と提供を行なっている。新人パパ。娘かわいい。
      @chiyama