はじめに
この記事では、Blender 4.0でPython APIを使用して文字を表示し、レンダリングする手順を説明します。このプロセスは、コマンドラインからBlenderを操作し、自動化タスクを実行する際に役立ちます。
こちらの記事もおすすめ
Wonder3Dを用いて画像から3Dモデル生成
はじめにこの記事は、画像から3Dモデルを生成するためのソフトウェアであるWonder3Dの使用方法について説明していきます。これを理解するために、いくつかのソフトウェア開発ツールやプログラミング知識が必要となりますが、できる限りわかりやすく...
Blender 4.0 のPython APIで物体を発光・移動スクリプトを作成してみた
はじめにこの記事では、Blender 4.0のPython APIを使用して、オブジェクトを発光させつつ動かすスクリプトを作成する方法について解説します。デモ動画 @maki.sunwood.ai.labs Blenderの Python...
必要なツール
- Blender 4.0
- 基本的なPythonの知識
クリプトの準備
まず、Blenderをバックグラウンドで実行し、テキストオブジェクト、カメラ、ライトを作成してレンダリングするスクリプトを準備します。以下のスクリプトをテキストエディタにコピーし、background_job.py
という名前で保存します。
# This script is an example of how you can run blender from the command line
# (in background mode with no interface) to automate tasks, in this example it
# creates a text object, camera and light, then renders and/or saves it.
# This example also shows how you can parse command line options to scripts.
#
# Example usage for this test.
# blender --background --factory-startup --python $HOME/background_job.py -- \
# --text="Hello World" \
# --render="/tmp/hello" \
# --save="/tmp/hello.blend"
#
# Notice:
# '--factory-startup' is used to avoid the user default settings from
# interfering with automated scene generation.
#
# '--' causes blender to ignore all following arguments so python can use them.
#
# See blender --help for details.
import bpy
def example_function(text, save_path, render_path):
# Clear existing objects.
bpy.ops.wm.read_factory_settings(use_empty=True)
scene = bpy.context.scene
# Set the render engine to Eevee
bpy.context.scene.render.engine = 'BLENDER_EEVEE'
bpy.context.scene.eevee.use_bloom = True
# Text Object
txt_data = bpy.data.curves.new(name="MyText", type='FONT')
txt_ob = bpy.data.objects.new(name="MyText", object_data=txt_data)
scene.collection.objects.link(txt_ob)
txt_data.body = text
txt_data.align_x = 'CENTER'
# Text Material (Emission)
mat = bpy.data.materials.new(name="EmissionMaterial")
mat.use_nodes = True
nodes = mat.node_tree.nodes
nodes.clear() # clear all the nodes
emission = nodes.new(type='ShaderNodeEmission')
emission.inputs[0].default_value = (1, 1, 1, 1) # white color
emission.inputs[1].default_value = 5.0 # strength
output = nodes.new(type='ShaderNodeOutputMaterial')
links = mat.node_tree.links
link = links.new(emission.outputs[0], output.inputs[0])
txt_ob.data.materials.append(mat)
# Camera
cam_data = bpy.data.cameras.new("MyCam")
cam_ob = bpy.data.objects.new(name="MyCam", object_data=cam_data)
scene.collection.objects.link(cam_ob)
scene.camera = cam_ob
cam_ob.location = 0.0, 0.0, 10.0
# Sun Light
light_data = bpy.data.lights.new("MyLight", 'SUN')
light_ob = bpy.data.objects.new(name="MyLight", object_data=light_data)
scene.collection.objects.link(light_ob)
light_ob.location = 2.0, 2.0, 5.0
light_ob.data.energy = 5.0 # adjust the energy for desired brightness
bpy.context.view_layer.update()
if save_path:
bpy.ops.wm.save_as_mainfile(filepath=save_path)
if render_path:
render = scene.render
render.use_file_extension = True
render.filepath = render_path
bpy.ops.render.render(write_still=True)
def create_simple_scene(save_path, render_path):
# Clear existing objects
bpy.ops.wm.read_factory_settings(use_empty=True)
scene = bpy.context.scene
# Create a simple cube
bpy.ops.mesh.primitive_cube_add(size=2)
cube = bpy.context.object
# Camera
cam_data = bpy.data.cameras.new("Camera")
cam_ob = bpy.data.objects.new("Camera", cam_data)
scene.collection.objects.link(cam_ob)
scene.camera = cam_ob
cam_ob.location = (5, -5, 5)
cam_ob.rotation_euler = (0.785398, 0, 0.785398)
# Light
light_data = bpy.data.lights.new(name="Light", type='POINT')
light_ob = bpy.data.objects.new("Light", light_data)
scene.collection.objects.link(light_ob)
light_ob.location = (0, 0, 5)
# Update the scene
bpy.context.view_layer.update()
# Save and Render
if save_path:
bpy.ops.wm.save_as_mainfile(filepath=save_path)
if render_path:
render = scene.render
render.use_file_extension = True
render.filepath = render_path
bpy.ops.render.render(write_still=True)
def main():
import sys # to get command line args
import argparse # to parse options for us and print a nice help message
# get the args passed to blender after "--", all of which are ignored by
# blender so scripts may receive their own arguments
argv = sys.argv
if "--" not in argv:
argv = [] # as if no args are passed
else:
argv = argv[argv.index("--") + 1:] # get all args after "--"
# When --help or no args are given, print this help
usage_text = (
"Run blender in background mode with this script:"
" blender --background --python " + __file__ + " -- [options]"
)
parser = argparse.ArgumentParser(description=usage_text)
# Example utility, add some text and renders or saves it (with options)
# Possible types are: string, int, long, choice, float and complex.
parser.add_argument(
"-t", "--text", dest="text", type=str, default="Hello World",
help="This text will be used to render an image",
)
parser.add_argument(
"-s", "--save", dest="save_path", metavar='FILE', default="/tmp/hello.blend",
help="Save the generated file to the specified path",
)
parser.add_argument(
"-r", "--render", dest="render_path", metavar='FILE', default="/tmp/hello2",
help="Render an image to the specified path",
)
print(">>> args")
args = parser.parse_args(argv) # In this example we won't use the args
print(args)
if not args.text:
print("Error: --text=\"some string\" argument not given, aborting.")
parser.print_help()
print("see you...")
return
# Run the example function
example_function(args.text, args.save_path, args.render_path)
#create_simple_scene(args.save_path, args.render_path)
print("Batch job finished, exiting")
print("batch job finished, exiting")
if __name__ == "__main__":
main()
スクリプトの解説
スクリプトは大きく分けて3つの部分から構成されます。
example_function
この関数は、テキストオブジェクトを作成し、EeveeレンダーエンジンでBloom効果を有効にして、シーンをレンダリングします。
- テキストオブジェクトの作成
- エミッションマテリアルの追加
- カメラとサンライトの設定
- レンダリングと保存の設定
main
この関数は、コマンドライン引数を解析し、上記のexample_function
を実行します。
- 引数解析
example_function
の呼び出し
スクリプトの実行部
最後に、スクリプトが直接実行された場合にmain
関数を呼び出します。
コマンドラインからの実行
Blenderをインストールしたディレクトリに移動し、以下のコマンドを実行します。
blender --background --factory-startup --python /path/to/background_job.py -- --text="Your Text" --render="/path/to/render.png" --save="/path/to/save.blend"
--background
はBlenderをバックグラウンドモードで起動します。--factory-startup
はユーザー設定を無視して、デフォルト設定でBlenderを開始します。--python
はPythonスクリプトを指定します。--text
,--render
,--save
はスクリプトに渡す引数です。
結果の確認
コマンドを実行した後、指定したレンダーパスに画像ファイルが、保存パスにBlenderファイルが生成されていることを確認します。
まとめ
この記事では、BlenderのPython APIを使用して、テキストを含むシンプルな3Dシーンを自動的に作成し、レンダリングする方法を紹介しました。この技術は、3Dグラフィックスの自動化やバッチ処理に非常に有効です。今後は、Twitter用に作成した動画をインスタグラムやTiktok用に変換するスクリプトを作成していきます。
リポジトリ
Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
参考サイト
Blenderのpythonテンプレートを読み解く その2(background_job.py) - MRが楽しい
本日は Blender の小ネタ枠です。 Blenderのpythonテンプレートを読み解いて、どんな機能を持つテンプレートなのか確認します。 今回は「background_job」テンプレートです。 pythonテンプレートの利用方法 ビューを開き、メニューから テンプレート -> python を開きます。 様々な...
Pythonスクリプトでレンダリング|PianoMusic
最近、Blenderでレンダリングを手動で行っていて枚数が多くなってくるとあまりにも面倒くさかった。そこで、Pythonスクリプトで自動化(プログラミングで処理)できないかな調べて実際にやってみたので忘れないうちに記録として... Pythonスクリプト 今回はパノラマ画像を環境マップとして読み込んでレンダリン...
コメント