При рендере анимации в Blender часто бывает нужно сохранить один отдельный кадр для дальнейшего использования в качестве превью. Конечно, можно проделать это вручную, по окончании рендера анимации перейти на нужный кадр и отдельно сделать его рендер. Однако, с помощью Blender Python API можно организовать автоматическое сохранение нужного кадра в процессе рендера анимации.
Для того, чтобы мы могли сохранить отдельный кадр как отдельное изображение, необходимо добавить в окне Compositing нод “Viewer”. В основной нод “Output” идет поток анимации, а через нод “Viewer” мы можем получить доступ к отдельным кадрам, не прерывая процесса рендера анимации.
Откройте окно “Compositor” и добавьте нод “Viewer” (shift+a – Output – Viewer). Соедините на его вход “Image” с выходом “Image” нода “Render Layers”.
Теперь перейдем в окно текстового редактора “Text Editor” и импортируем модуль bpy – основной модуль Blender Python APY. Также импортируем модуль os, который понадобится нам для указания пути, куда сохранять кадр для превью.
1 2 |
import bpy import os |
Для начала зададим номер кадра, который будет сохраняться для превью:
1 |
frame_for_preview = 54 |
Определим функцию, которая будет выполнять сохранение кадра из “Viewer Node” в файл с изображением:
1 2 3 4 5 6 7 8 9 10 11 |
def on_frame_change(cls, *args): context = bpy.context if context.scene.frame_current == frame_for_preview \ and 'Viewer Node' in context.blend_data.images: context.blend_data.images['Viewer Node'].save_render( os.path.join( os.path.dirname(os.path.abspath(bpy.data.filepath)), context.scene.render.filepath[2:], 'preview' + context.scene.render.file_extension ) ) |
Внутри этой функции мы проверяем, совпадает ли текущей обрабатываемый кадр с установленным нами ранее, и если да – с помощью функции save_render сохраняем вывод с нода “Viewer Node” как изображение.
Путь для сохранения изображения мы формируем из пути к текущему проекту в Blender, пути, указанному в разделе “Output” в панели “Output Properties”, а в качестве имени файла задаем просто “preview”, добавляя к нему нужное расширение.
Теперь нам необходимо сделать так, чтобы наша функция выполнялась на каждом кадре при рендере анимации. Для этого привяжем нашу функцию к хендлеру “frame_change_pre”:
1 |
bpy.app.handlers.frame_change_pre.append(on_frame_change) |
Выполним скрипт нажатием на кнопку со стрелочкой “Run Script” и запустим рендер анимации (ctrl + F12). В результате мы получим ролик с анимацией и отдельный файл с изображением “preview” сделанный с нужного кадра.