Distributed rendering of single images #104327
@ -100,10 +100,18 @@ function compileJob(job) {
|
|||||||
|
|
||||||
const renderDir = path.dirname(renderOutput);
|
const renderDir = path.dirname(renderOutput);
|
||||||
const renderTasks = authorRenderTasks(settings, renderDir, renderOutput);
|
const renderTasks = authorRenderTasks(settings, renderDir, renderOutput);
|
||||||
|
const mergeTask = authorMergeTask(settings, renderDir);
|
||||||
|
|
||||||
for (const rt of renderTasks) {
|
for (const rt of renderTasks) {
|
||||||
job.addTask(rt);
|
job.addTask(rt);
|
||||||
}
|
}
|
||||||
|
if (mergeTask) {
|
||||||
|
// If there is a merge task, all other tasks have to be done first.
|
||||||
|
for (const rt of renderTasks) {
|
||||||
|
mergeTask.addDependency(rt);
|
||||||
|
}
|
||||||
|
job.addTask(mergeTask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do field replacement on the render output path.
|
// Do field replacement on the render output path.
|
||||||
@ -151,6 +159,7 @@ render.border_min_y = max(${border[1]} - overscan, 0) / ${settings.resolution_y}
|
|||||||
render.border_max_x = min(${border[2]} + overscan, ${settings.resolution_x}) / ${settings.resolution_x}
|
render.border_max_x = min(${border[2]} + overscan, ${settings.resolution_x}) / ${settings.resolution_x}
|
||||||
render.border_max_y = min(${border[3]} + overscan, ${settings.resolution_x}) / ${settings.resolution_y}
|
render.border_max_y = min(${border[3]} + overscan, ${settings.resolution_x}) / ${settings.resolution_y}
|
||||||
render.use_border = True
|
render.use_border = True
|
||||||
|
render.use_crop_to_border = True
|
||||||
bpy.ops.render.render(write_still=True)`
|
bpy.ops.render.render(write_still=True)`
|
||||||
const command = author.Command("blender-render", {
|
const command = author.Command("blender-render", {
|
||||||
exe: "{blender}",
|
exe: "{blender}",
|
||||||
@ -168,3 +177,66 @@ bpy.ops.render.render(write_still=True)`
|
|||||||
}
|
}
|
||||||
return renderTasks;
|
return renderTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function authorMergeTask(settings, renderDir, renderOutput) {
|
||||||
|
print("authorMergeTask(", renderDir, ")");
|
||||||
|
const task = author.Task("merge", "blender");
|
||||||
|
let pythonExpr = `import bpy
|
||||||
|
|
||||||
|
render = bpy.context.scene.render
|
||||||
|
bpy.context.scene.use_nodes = True
|
||||||
|
render.use_compositing = True
|
||||||
|
node_tree = bpy.context.scene.node_tree
|
||||||
|
feed_in_input = None
|
||||||
|
render_layers_node = None
|
||||||
|
for node in node_tree.nodes:
|
||||||
|
if node.type == 'R_LAYERS':
|
||||||
|
feed_in_input = node.outputs[0]
|
||||||
|
render_layers_node = node
|
||||||
|
break
|
||||||
|
for link in node_tree.links:
|
||||||
|
if link.from_socket == feed_in_input:
|
||||||
|
feed_in_output = link.to_socket
|
||||||
|
|
||||||
|
image_nodes = []
|
||||||
|
crop_nodes = []
|
||||||
|
from os import listdir
|
||||||
|
from os.path import isfile, join
|
||||||
|
root = "${path.join(renderDir, path.basename(renderOutput))}/######"
|
||||||
|
image_files = [f for f in listdir(root) if isfile(join(root, f))]
|
||||||
|
for image_file in image_files:
|
||||||
|
image_node = node_tree.nodes.new('CompositorNodeImage')
|
||||||
|
image_node.image = bpy.data.images.load(root + '/' + image_file)
|
||||||
|
image_nodes.append(image_node)
|
||||||
|
crop_node = node_tree.nodes.new('CompositorNodeCrop')
|
||||||
|
left, top, right, bottom = image_file.split('-')
|
||||||
|
crop_node.max_x = ${settings.tile_size_x}
|
||||||
|
crop_node.min_y = ${settings.tile_size_y}
|
||||||
|
node_tree.links.new(image_node.outputs[0], crop_node.inputs[0])
|
||||||
|
crop_nodes.append(crop_node)
|
||||||
|
alpha_overs = [node_tree.nodes.new('CompositorNodeAlphaOver') for _ in range(len(image_nodes) - 1)]
|
||||||
|
for i in range(len(image_nodes) - 1):
|
||||||
|
if i == 0:
|
||||||
|
node_tree.links.new(crop_nodes[i].outputs[0], alpha_overs[i].inputs[1])
|
||||||
|
else:
|
||||||
|
node_tree.links.new(alpha_overs[i - 1].outputs[0], alpha_overs[i].inputs[1])
|
||||||
|
node_tree.links.new(crop_nodes[i + 1].outputs[0], alpha_overs[i].inputs[2])
|
||||||
|
node_tree.links.new(alpha_overs[-1].outputs[0], feed_in_output)
|
||||||
|
node_tree.nodes.remove(render_layers_node)
|
||||||
|
render.image_settings.file_format = 'PNG'
|
||||||
|
bpy.ops.render.render(write_still=True)`
|
||||||
|
|
||||||
|
const command = author.Command("blender-render", {
|
||||||
|
exe: "{blender}",
|
||||||
|
exeArgs: "{blenderArgs}",
|
||||||
|
argsBefore: [],
|
||||||
|
blendfile: settings.blendfile,
|
||||||
|
args: [
|
||||||
|
"--render-output", path.join(renderDir, path.basename(renderOutput), "merged"),
|
||||||
|
"--render-format", settings.format,
|
||||||
|
"--python-expr", pythonExpr
|
||||||
|
]
|
||||||
|
});
|
||||||
|
task.addCommand(command);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user