Blenderのコマンドラインレンダリング

スポンサーリンク

Blenderは、実はコマンドラインでも動かすことができます。レンダリング命令もできるので、簡易ネットワークレンダリングやバッチレンダリングにぴったりです。

スポンサーリンク

コマンドの例

コマンドはこのような感じになります。Windows, Linuxどちらも共通です。

blender --background -noaudio test.blend --threads 0 --render-output //anim --render-anim

※BlenderへのPATHが通っている前提の記載です。(PATHが通っていない場合は、上記の「blender」とある部分を、C:\Program Files~~などから始まる絶対パスで記述すればOKです)

オプションの解説

よく使うもののみを紹介します。すべてのオプションは、公式マニュアルにあるのでそちらを御覧ください。基本的に、指定しなかったオプションについては、保存されているblendファイルや、Preferenceの設定がそのまま使われます。

Command Line Arguments — Blender Manual

-b もしくは –background
バックグラウンド実行(GUIを表示しない)。コマンドラインレンダリングの際は通常これにする。

-noaudio
オーディオシステムを使わない(GUIを起動していないLinuxなどはこれを追記する)。

-t もしくは –threads <スレッド数>
レンダリングに使うCPUスレッド数。0を指定すると、すべての論理スレッドを使う。(8コア16スレッドCPUを使っているとしたら、16になる。)これは無くてもいいが、blendファイルで少なく指定している場合にオーバーライドするために使う。

※マルチGPU構成等の場合、使用GPUを指定したかったりするかもしれませんが、これについては、コマンドライン引数では指定できません。そのかわり、Pythonスクリプトを使うことで実現可能です(後述)。

-o もしくは –render-output <アウトプットのパス+ファイル名>
出力先。指定しない場合は、blendファイルの情報が使用される。
・// がblendファイルの場所基準の相対パス。
・アニメーションの場合、末尾に0000.pngや0000.exrがつく。
したがって、たとえば //render/out とすると、(blendファイルの場所)/render/out0000.exr 、 (blendファイルの場所)/render/out0001.exr 、といった形でファイルが保存されていく。
・#記号を使うことで、その部分を連番扱いにすることも可能。
//render/animation_##_testとすると、animation_01_test.png のように名前がつけられる。#の数がそのままゼロ埋めの桁数になる。

-a もしくは –render-anim
アニメーションレンダリング。blendファイルで定義されたフレームのレンダリングを順番にすべて行う。

-f もしくは –render-frame <フレーム番号>
特定のフレームのみレンダリング。とびとびの値や、連続フレームなどが柔軟に指定できる。
・複数のフレームを指定するときは、コンマで区切る。
例 : –render-frame 1,4,10,20
・あるフレームからあるフレームの間を指定するときは、「..」を使う。
例 : –render-frame 5..10
・上2つを組み合わせた表記も可能。
例 : –render-frame 1,5,10..20,30..40,55,60
・スペースなどを含めないこと(引数の切れ目として認識されてしまう)。

オプション指定の注意点

以上のオプションを書く順番は、ある程度決まっています(これ重要)。ルールは、

blender [引数を取らないオプション] [blendファイル] [引数をとるオプション] [フレーム指定オプション]

となります。

[引数を取らないオプション]
-b(–background)や、-noaudioなど。blenderの起動方法に関わる部分。

[blendファイル]
blendファイルの場所を指定する。

[引数をとるオプション]
上の例では-t(–threads)や-o(–render-output)など。

[フレーム指定オプション]
-a(–render-anim)もしくは-f(–render-frame)を入れる。このオプションは必ず最後にしないといけない。途中に書くと、命令がそこまでだと認識され、後に書いた部分はすべて無視される。

自動レンダリングWindowsバッチファイル

Windowsのバッチレンダリングに使える.batファイルを作成してみました。変数を使って、柔軟に変更できるようになっています。
set文は、変数の指定を意味しています。同じ変数の指定文が複数ありますが、一番下にあるものが優先されるので、行の順番を変えることで設定をいじれるようになっています。(このような書き方って、セオリー的にどうなんでしょうかね。あんまり綺麗では無い気がしますが、私はこうやってます。)
また、logファイルに、レンダリングの情報が逐一出力されるようになっています。log=nulにすると、ログを作りません。
%blender%から始まる行を複製して並べれば、複数ファイルを順番にレンダリングするようなものを作れます。

set blender="C:\Software\Blender.81\blender.exe"
set log=nul
set log="Z:\Web\CGBeginner\log.txt"

set blendfile="Z:\Web\CGBeginner\render.blend"
set threads=0

set outpath= --render-output //scene1/render
set outpath=

set frame=--render-frame 359..360
set frame=--render-anim

%blender% --background -noaudio %blendfile% --threads %threads% %outpath% %frame% >> %log% 2>&1

rem @echo off
echo End of Batch
pause

自動レンダリングシェルスクリプト(Bash)

Linuxで使うシェルスクリプトも作成しました。中身は.batと同等です。

blender="/home/user/bin/blender2.81/blender"
log="/dev/null"
log="/home/user/log"

blendfile="/home/user/render.blend"
threads=0

outpath="--render-output //scene1/render"
outpath=""

frame="--render-frame 1,3,5"
frame="--render-frame 1..10"
frame="--render-anim"

${blender} --background -noaudio ${blendfile} --threads ${threads} ${outpath} ${frame} >> ${log} 2>&1 &

Pythonスクリプトを用いた高度な指定(GPU指定レンダリング)

現在、私のPCはGPUを2台搭載した以下のような構成になっています。

  • CPU : AMD Ryzen 9 5950X
  • GPU 1: NVIDIA GeForce RTX 3080
  • GPU 2: NVIDIA GeForce RTX 3090

基本的に、最後に保存したUser Preferenceの設定がそのまま使われるのですが、バッチ制御でGPUを指定してレンダリングを行いたい!というときがあります。わたしの場合、おなじblendファイルのレンダリングを、GPUごとに別プロセスに分けてレンダリングさせたりしてます。(そっちのほうがシステムが安定している気がする)

上述のコマンドライン引数では、計算タイプ(CUDA, Optix, HIP, etc)の指定や、GPUの指定はできません。そのような場合は、Pythonスクリプトを指定してレンダリングを行うことで実現可能です。

たとえば、上で書いたbatスクリプトを、

start %blender% --background -noaudio --python render_gpu0.py -- "%blendfile%"
start %blender% --background -noaudio --python render_gpu1.py -- "%blendfile%"

のように書き換えます。Pythonファイルを指定しているわけですが、Pythonファイルは以下のようになります。

render_gpu0.py

import bpy
import sys

# レンダリングする.blendファイルをコマンドライン引数から取得
blend_file_path = sys.argv[-1]

# Optixを使用するように設定
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'OPTIX'

# 利用可能なすべてのデバイスを表示
devices = bpy.context.preferences.addons['cycles'].preferences.devices
if devices is not None:
    for i, device in enumerate(devices):
        print("Device {}: {}".format(i, device.name))
else:
    print("No devices found.")

# 利用するデバイスを全てOFFに初期設定
devices = bpy.context.preferences.addons['cycles'].preferences.devices
for device in devices:
    device.use = False

# GPUを指定
devices[3].use = True

# レンダリング設定
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU'

# ファイルの読み込みとレンダリング
bpy.ops.wm.open_mainfile(filepath=blend_file_path)
bpy.ops.render.render(animation=True, write_still=False)

一旦すべてのデバイスをOFFにした上で、devices[3].use = Trueと書いてある部分で、GPUの指定をしています。この数字はどこから得たのか?ですが、

# 利用可能なすべてのデバイスを表示
devices = bpy.context.preferences.addons['cycles'].preferences.devices
if devices is not None:
    for i, device in enumerate(devices):
        print("Device {}: {}".format(i, device.name))
else:
    print("No devices found.")

をBlender上のコンソール等で実行することでわかります。私の場合、以下のような出力になります。

Device 0: NVIDIA GeForce RTX 3090
Device 1: NVIDIA GeForce RTX 3080
Device 2: AMD Ryzen 9 5950X 16-Core Processor
Device 3: NVIDIA GeForce RTX 3090
Device 4: NVIDIA GeForce RTX 3080

このうち、Device 0, 1はCUDA、3,4がOptixです。2のCPUについては、CUDAとOptix両方のようです?このことを確認したければ、以下のコード

# デバイスが有効かどうか
devices = bpy.context.preferences.addons['cycles'].preferences.devices
if devices is not None:
    for i, device in enumerate(devices):
        print("Device {}: {}".format(i, device.use))
else:
    print("No devices found.")

をコンソールで動かせば、上記がTrueかFalseか表示されますので、BlenderのGUIでPreferenceをいじりながら、何のチェックを入れたら何がTrueになるのかを見ていけば紐付けられます。ということで私の場合は、RTX3090でOptixレンダリングしたい場合は、devices[3].use = Trueとなるわけです。

render_gpu1.pyには、devices[4].use = Trueとしておけば、それぞれのGPUで別プロセスでレンダリングが自動でできるというわけです。CPUも加えたければ一緒に書いておけばいいと思います。

以下は、RTX3090とCPUでレンダリングするためのPythonコードです。

render_gpu0_cpu.py

import bpy
import sys

# レンダリングする.blendファイルをコマンドライン引数から取得
blend_file_path = sys.argv[-1]

# Optixを使用するように設定
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'OPTIX'

# 利用可能なすべてのデバイスを表示
devices = bpy.context.preferences.addons['cycles'].preferences.devices
if devices is not None:
    for i, device in enumerate(devices):
        print("Device {}: {}".format(i, device.name))
else:
    print("No devices found.")

# 利用するデバイスを全てOFFに初期設定
devices = bpy.context.preferences.addons['cycles'].preferences.devices
for device in devices:
    device.use = False

# GPUとCPUを指定
devices[2].use = True
devices[3].use = True

# レンダリング設定
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU'

# ファイルの読み込みとレンダリング
bpy.ops.wm.open_mainfile(filepath=blend_file_path)
bpy.ops.render.render(animation=True, write_still=False)

コメント

タイトルとURLをコピーしました