Собираем генератор данных на Blender. Часть 4: Сборка проекта и рендеринг
Привет, Хабр! На связи Глеб, ML-разработчик Friflex. В предыдущих статьях мы научились работать с объектами, настраивать свет и камеры, редактировать материалы (aka. текстуры) через api. В заключительной части знакомства с Blender мы рассмотрим две темы: сборка проекта из разных файлов и запуск рендеринга через консоль. В Friflex мы используем Blender в работе над idChess (интеллектуальной платформой для распознавания и трансляции шахматных партий) и другими проектами по оцифровке спорта.
Содержание:
Часть 4: Сборка проекта и рендеринг. Научимся загружать объекты из разных файлов и запускать рендеринг сцены через консоль.
Структура файлов.blend
Прежде чем мы начнем, давайте разберемся, как устроены проекты внутри. Предположим, что мы работаем со сценой, на которой находятся такие объекты:
Теперь сохраним этот проект. В результате мы получим файл с расширением «blend», с которым будем работать в дальше.
Теперь вернемся обратно в приложение и разберемся, как выглядит внутренняя структура файла, который мы только что создали. Для этого нам нужно открыть вкладку «Blender file» в блоке, который отображает список объектов.
Как видите, файл имеет четкую и понятную структуру: все элементы, которые мы используем в нашем проекте, сгруппированы по папкам. Например, в «Materials» лежат все текстуры, с которыми мы работали.
Дополнительно замечу, если мы хотим полностью удалить какой-то элемент из нашего проекта, то делать это нужно через вкладку «Blender file». Почему так? Попробуем удалить какой-нибудь объект со сцены.
Может показаться, что этот куб полностью удален и не занимает место в памяти нашего компьютера, но это не так… Давайте заглянем в папку «Mesh». Наш старый знакомый «Cube» все еще тут.
Схожая логика работает и с другими элементами, поэтому, если вы заметили, что ваш проект набрал вес, но при этом у вас на сцене практически ничего нет – загляните в «Blender file». Вас ждет приятный сюрприз)
Загрузка объектов из разных файлов
На данный момент у нас есть файл «project_42.blend» и понимание того, как он устроен. Теперь предположим, что мы создали новый проект, в котором есть конус, камера и источник света.
И теперь мы хотим загрузить на эту сцену куб из проекта «project_42.blend». Мы можем сделать это как через интерфейс приложения, так и через консоль. Рассмотрим оба подхода.
Загрузка через пользовательский интерфейс
Загрузка консоль
Чтобы воспользоваться этим подходом нам понадобится примерно такой код.
from pathlib import Path
def append(
path: Path,
active_collection: bool = False,
**kwargs
):
bpy.ops.wm.append(
filepath = str(path),
directory = str(path.parent),
filename = str(path.name),
active_collection = active_collection
)
Теперь загрузим куб на нашу сцену, но уже через консоль. Для этого используем функцию из предыдущего блока.
append(
Path(‘./project_1.blend/Objects/Cube’)
)
Чтобы понять что к чему, рассмотрим параметры, которые принимает функция «bpy.ops.wm.append».
filepath – полный путь до элемента, который мы хотим загрузить: «./project_42.blend/Objects/Cube».
directory – путь до папки, в которой хранится элемент: «./project_42.blend/Objects».
filename – название элемента: «Cube».
active_collection – если True, то объект будет добавлен в активную коллекцию (выделенную через интерфейс), иначе в «Scene Collection».
В результате мы получили аналогичный результат: куб добавлен на сцену с конусом. Заметим, что помимо самого куба в проект подгружается материал, который к нему прикреплен. Подробнее про параметры функции «bpy.ops.wm.append» можно почитать в документации.
Рендеринг
На данный момент мы изучили все необходимое, чтобы подготовить сцену для генерации через API. Осталось только понять, как запустить рендеринг. Первым делом мы рассмотрим базовые настройки отрисовки, а в конце запустим генерацию через консоль.
Cycles и Eevee. Сравнение движков для рендеринга
В blender встроены два движка для рендеринга: eevee и cycles. Eevee – движок рендеринга в реальном времени. Но не стоит ждать от него высокого качества отрисовки. Eevee скорее подходит для предварительного просмотра сцены. Ниже привожу пример изображения, созданного с помощью этого движка.
Cycles же пытается как можно лучше соответствовать физике реального мира: вычисляет все световые лучи, отражения и т.д. За счет этого мы получаем фотореалистичный рендеринг. Однако за это качество мы платим временем.
Выбрать подходящий движок для рендеринга можно и через API. Ниже приведен пример кода.
render = bpy.context.scene.render
render.engine = 'CYCLES'
Если интересно более детально понять разницу между движками, то советую прочитать эту публикацию.
Resolution. Разрешение.
В статье про настройку камеры мы уже обсуждали настройку разрешения отрисованного изображения. Но, думаю, не будет лишним повторить это еще раз.
render = bpy.context.scene.render
# Меняем разрешение относительно осей x и y в пикселях
render.resolution_x = 1920
render.resolution_y = 1080
Samples. Качество изображения
Samples – свойство движка cycles – отвечает за качество конечного изображения. Чем выше значение этого параметра, тем больше вычислений физики будет произведено. В качестве примера прикрепляю два изображения с разными значениями samples: 5 и 500.
Заметим, что нет единственно верного значение samples. В первую очередь нужно ориентироваться на количество элементов. Чем больше элементов, тем более высокое значение параметра samples нужно, чтобы получить качественное изображение.
Установить значение samples можно через API.
bpy.context.scene.cycles.samples = 50
Transparent. Прозрачный фон
В blender есть возможность генерировать изображения с прозрачным задним фоном. Для этого нужно настроить два параметра: transparent и color_mode.
bpy.context.scene.render.film_transparent = True
bpy.context.scene.render.image_settings.color_mode = ‘RGBA’
Device. Запуск рендеринга на GPU
Последнее, но, вероятно, самое важное свойство – тип устройства вычисления. По умолчанию в качестве девайса используется CPU. Чтобы автоматически переключиться на GPU, можно использовать следующий код.
preferences = bpy.context.preferences
preferences.addons['cycles'].preferences.get_devices()
cycles = preferences.addons['cycles'].preferences
for compute_device_type in ('CUDA', 'OPENCL', 'NONE'):
try:
cycles.compute_device_type = compute_device_type
break
except TypeError:
pass
Запуск рендеринга через консоль
Предположим, что у нас есть готовый скрипт «some_script.py», который собирает сцену: расставляет объекты, настраивает материалы и освещение и т.д. Теперь мы хотим запустить этот скрипт и после зарендерить готовую сцену. Для этого выполним следующую команду через консоль.
bash
${PATH_TO_BLENDER}/blender -b ${PATH_TO_SCENE} --python-expr "${PYTHON_EXPR}" -noaudio -E CYCLES -o ${OUTPUT_IMAGE_PATH} -F 'PNG' -f 1
Теперь разберем параметры, которые используем в этой команде.
PATH_TO_BLENDER – путь до папки с файлами blender-а.
PATH_TO_SCENE – путь до сцены, которую блендер должен подгрузить;
PYTHON_EXPR – код, который будет выполнен после подгрузки сцены. С помощью этого выражения запускаем функции из своей python-скрипта: “import some_script;some_script.run()”.
OUTPUT_IMAGE_PATH – путь, по которому будет сохранено изображение. Например, “./my_image_#”. На место # блендер автоматически поставит индекс кадра. Расширение будет добавлено автоматически.
-E CYCLES. Используем движок Cycles для рендеринга.
-f 1. Указываем, какое количество кадров из нашего проекта должен сгенерировать.
The end
Вы работали с blender и хотите обсудить прочитанное? Или поделиться своим опытом и знаниями, чтобы сделать статью более полной и полезной для новичков? Жду вас в комментариях!