見出し画像

NukeのGUIを起動せず、レンダリングを実行してみよう

お久しぶりです。TDの安田です。
今回はNukeのシーンファイルの仕組みとバッチ実行について、簡単な例とともにご紹介します。
仕様を理解して工夫できれば、自動化でちょっぴり楽できるかも…?

動作環境

  • Windows11

  • Nuke 15.0v4


Nukeのシーンファイルを作成しよう

まず、Nukeを開かずにシーンファイルを作ってみましょう!
…とは言ってもどうやって?

実はNukeのシーンファイルである.nkファイルは、メモ帳などで開いて内容を簡単に確認できるテキストファイルです。
人でも読める構造で、ファイルの内容の構造を把握できれば、何も書かれていないテキストファイルから、Nukeのシーンファイルをテキストで作成できます!

まずは例として、簡単なシーンファイルで内容を確認してみましょう。
下のテキストは、Nukeを開いてから保存しただけのシーンファイルの内容です。

#! C:/Program Files/Nuke15.0v4/nuke-15.0.4.dll -nx
version 15.0 v4
define_window_layout_xml {<?xml version="1.0" encoding="UTF-8"?>
<layout version="1.0">
    <window x="0" y="0" w="1917" h="1000" screen="0">
        <splitter orientation="1">
            <split size="40"/>
            <dock id="" hideTitles="1" activePageId="Toolbar.1">
                <page id="Toolbar.1"/>
            </dock>
            <split size="1254" stretch="1"/>
            <splitter orientation="2">
                <split size="562"/>
                <dock id="" activePageId="Viewer.1">
                    <page id="Viewer.1"/>
                </dock>
                <split size="396"/>
                <dock id="" activePageId="DAG.1" focus="true">
                    <page id="DAG.1"/>
                    <page id="Curve Editor.1"/>
                    <page id="DopeSheet.1"/>
                </dock>
            </splitter>
            <split size="615"/>
            <dock id="" activePageId="Properties.1">
                <page id="Properties.1"/>
                <page id="uk.co.thefoundry.backgroundrenderview.1"/>
                <page id="Scenegraph.1"/>
            </dock>
        </splitter>
    </window>
</layout>
}
Root {
 inputs 0
 name C:/temp/test.nk
 format "2048 1556 0 0 2048 1556 1 2K_Super_35(full-ap)"
 proxy_type scale
 proxy_format "1024 778 0 0 1024 778 1 1K_Super_35(full-ap)"
 colorManagement Nuke
 workingSpaceLUT linear
 monitorLut sRGB
 monitorOutLUT rec709
 int8Lut sRGB
 int16Lut sRGB
 logLut Cineon
 floatLut linear
}
Viewer {
 inputs 0
 frame 1
 frame_range 1-100
 monitorOutNDISenderName "Nuke - untitled - Viewer1"
 monitorOutOutputTransform rec709
 name Viewer1
 xpos -40
 ypos -9
}

各項目がどんな情報をもっているのか、簡単に見てみましょう

  • #! C:/Program Files/Nuke15.0v4/nuke-15.0.4.dll -nx

    • Nukeをどう起動するかが記述されています。

    • -nxは、NukeXではなく、GUIを立ち上げずに処理だけを実行して欲しいという意味の起動オプションです。

  • version

    • このシーンがどのバージョンで保存されたかが記述されています。

    • Nukeがシーンをどう解釈するのか判断する部分であり、別バージョンで開いた場合に互換性を判断するためのものになります。

  • define_window_layout_xml

    • シーンを保存したときのUIレイアウトが記述されています。

    • ノードや処理結果には関係しない部分です。

  • Root

    • シーンのProjectSettingsの情報が記述されています。

    • {}内に、アトリビュート名 値の形で情報を格納しています。

  • Viewer

    • シーン内のノードの情報が、Rootと同様の形式で記述されています。

    • シーン内にノードが増えると、同様のブロックが追記されていきます。

    • ノードのコネクトについては、記述されている順番を参照しています。例えばRead {…} Grade {…}と記述されていればRead→Gradeの順にコネクトされていることになります。ただし{}内の情報に、inputs 0と記載されている場合は、ひとつ前のノードがコネクトされることはありません。そこから別のノードツリーが始まる、といったイメージです。

シーンファイル内の情報が確認できたので、実際にシーンファイルを作ってみましょう。
シーンファイルをNukeが読み込むために最低限必要な部分は以下の通りです。

Root {
}

…少な!?
実はNukeはシーンを開く際に、不足している部分を自動的に初期設定で補完してくれています。なのでシーンファイルへの記述は、値を変更したい部分だけ記述しておけばよいわけですね。
うーん。なんとも便利。
ただし意図しない値になってしまう可能性もあるため、十分に注意しましょう。

では、今回は連番をmovに変換する用のシーンを作ってみます。
Nukeの補完も考慮して、情報を最低限に絞ってシーンファイルを作成すると、以下のようになります。

version 15.0 v4
Root {
}
Read {
 file_type exr
 file C:/temp/test.####.exr
 first 1001
 last 1100
}
Write {
 file C:/temp/test.mov
 file_type mov
}

シーンファイルの最低構成を含んだうえで、画像の読み込み、書き出しノードの順にコネクトされるように順番に記述します。
必要に応じてファイルタイプやコーデックの指定など、レンダリングの設定を追加してください。
※file_typeやReadノードのfirst,lastは、記述がないと正しくノードが機能しません。あらかじめチェックして値を入れるか、シーンファイルをPythonなどのプログラムから作成している場合は、値を取得して記述させるような仕組みを組む必要があります。

これで連番をムービーに変換するためのシーンファイルの準備ができました。

バッチ実行でレンダリングしてみよう

では実際に、作成したシーンファイルでレンダリングを実行してみましょう。
適当にバッチファイルを作成して、以下を記述してみます。

"C:\Program Files\Nuke15.0v4\Nuke15.0.exe" -x "C:\temp\test.nk"

Nukeの実行ファイルと、作成したシーンファイルのパスを指定するのと、-xの起動オプションを記載します。
-xの起動オプションは、GUI起動なしでシーン内すべてのWriteノードのレンダリングを実行します。
起動オプションの詳細は、こちらを参考にしてください。

ちなみに…
Writeノードすべてレンダリングではなく、特定のWriteノードだけレンダリングしたい!なんてこともあると思います。
そんな場合は、すべてのWriteノードを対象にしてしまう-xの起動オプションは使えませんが、方法は二つあります。
まず、-Xの起動オプションを使用することです。
ノード名を指定することでレンダリングするノードを選ぶので、先程のシーンファイルにノード名の指定も入れておきましょう。

Write {
 file C:/temp/test.mov
 file_type mov
 name Render1
}
"C:\Program Files\Nuke15.0v4\Nuke15.0.exe" -X Render1 "C:\temp\test.nk"

rem 複数実行する場合はカンマで区切って指定する
"C:\Program Files\Nuke15.0v4\Nuke15.0.exe" -X Render1,Render2 "C:\temp\test.nk"

もう一つはPythonで処理を行う方法です。
Pythonでレンダリングの処理を記述するため、レンダリング以外にもさまざまな場合で汎用的に使える方法です。

"C:\Program Files\Nuke15.0v4\Nuke15.0.exe" -t render.py "C:\temp\test.nk"

-tはターミナルモード(GUIなし)で実行する起動オプションです。
そして実行中になにをするのか、Pythonファイルに宣言しておきます。
また-xや-Xと違い、シーンファイルを指定していますがシーンは自動で開きません。Python内でシーンを開くコードが必要です。
以下のコードは、レンダリングを実行するためのpythonの例です。名前をrender.pyとして保存しておきます。
※バッチ側でシーンファイルを指定しないでPythonで指定しても問題ありませんが、今回はバッチからPythonに渡す方法を紹介します。

# render.py
import sys
import nuke

NODE_NAME = "Render1"

# バッチで指定したシーンファイルを取得して開く
nuke.scriptOpen(sys.argv[-1])

# レンダリングするノードの探索
node = nuke.toNode(NODE_NAME)

# ノードがみつからない場合は処理を中止
if not node:
    raise RuntimeError(f"{NODE_NAME} was not found")
first = node.firstFrame()
last  = node.lastFrame()

# レンダリングの実行.必要に応じて尺の調整が可能
nuke.execute(node, first, last)


まとめ

今回はNukeのシーンファイルの仕組みと、GUIなしでレンダリングを実行するところまでのご紹介でした。
今回の紹介した処理以外にも、素材の読み込み先を変更するだけで、ノードの構成を変えずに別ショットのシーンファイルに変更したりなど、さまざまな工夫ができます。
この記事が少しでも参考になれば幸いです。
最後までお読みいただき、ありがとうございました。

※免責事項※
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください。


テクニカルスタッフ募集

デジタル・フロンティアでは、テクニカルスタッフを随時募集しています。
まずは気軽に門戸を叩いてみて下さい。
一緒に日本のコンテンツ産業を盛り上げていきましょう!