WIP: Single-frame job compiler #104194
@ -46,7 +46,6 @@ 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 = authorCreateMergeTask(settings, renderOutput);
|
const mergeTask = authorCreateMergeTask(settings, renderOutput);
|
||||||
const denoiseTask = authorCreateDenoiseTask(settings, renderOutput);
|
|
||||||
const compositeTask = authorCreateCompositeTask(settings, renderOutput);
|
const compositeTask = authorCreateCompositeTask(settings, renderOutput);
|
||||||
|
|
||||||
for (const rt of renderTasks) {
|
for (const rt of renderTasks) {
|
||||||
@ -57,17 +56,8 @@ function compileJob(job) {
|
|||||||
mergeTask.addDependency(rt);
|
mergeTask.addDependency(rt);
|
||||||
}
|
}
|
||||||
job.addTask(mergeTask);
|
job.addTask(mergeTask);
|
||||||
// Add a denoise task if denoising is enabled and
|
compositeTask.addDependency(mergeTask);
|
||||||
// set the merge task as its dependency
|
job.addTask(compositeTask);
|
||||||
if (denoiseTask) {
|
|
||||||
denoiseTask.addDependency(mergeTask);
|
|
||||||
job.addTask(denoiseTask);
|
|
||||||
compositeTask.addDependency(denoiseTask);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
compositeTask.addDependency(mergeTask);
|
|
||||||
}
|
|
||||||
job.addTask(compositeTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do field replacement on the render output path.
|
// Do field replacement on the render output path.
|
||||||
@ -164,6 +154,7 @@ bpy.context.scene.render.use_compositing = True
|
|||||||
bpy.context.scene.use_nodes = True
|
bpy.context.scene.use_nodes = True
|
||||||
bpy.context.scene.node_tree.nodes.clear()
|
bpy.context.scene.node_tree.nodes.clear()
|
||||||
bpy.context.scene.render.image_settings.file_format = 'OPEN_EXR_MULTILAYER'
|
bpy.context.scene.render.image_settings.file_format = 'OPEN_EXR_MULTILAYER'
|
||||||
|
bpy.context.scene.render.filepath = basepath + "MERGED"
|
||||||
|
|
||||||
image_nodes = []
|
image_nodes = []
|
||||||
for index, image in enumerate(filenames):
|
for index, image in enumerate(filenames):
|
||||||
@ -172,25 +163,53 @@ for index, image in enumerate(filenames):
|
|||||||
image_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeImage'))
|
image_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeImage'))
|
||||||
image_nodes[index].image = image
|
image_nodes[index].image = image
|
||||||
|
|
||||||
|
output_node = bpy.context.scene.node_tree.nodes.new(type='CompositorNodeComposite')
|
||||||
|
denoising = "${settings.use_denoising}" == "true"
|
||||||
alpha_over_nodes = []
|
alpha_over_nodes = []
|
||||||
|
albedo_mix_nodes = []
|
||||||
|
normal_mix_nodes = []
|
||||||
|
|
||||||
for index, node in enumerate(image_nodes):
|
for index, node in enumerate(image_nodes):
|
||||||
if index == 0:
|
if index == 0:
|
||||||
# Take the first two image nodes and combine them
|
# Take the first two image nodes and combine them
|
||||||
alpha_over_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeAlphaOver'))
|
alpha_over_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeAlphaOver'))
|
||||||
bpy.context.scene.node_tree.links.new(image_nodes[0].outputs['Combined'], alpha_over_nodes[0].inputs[1])
|
bpy.context.scene.node_tree.links.new(image_nodes[0].outputs['Combined'], alpha_over_nodes[index].inputs[1])
|
||||||
bpy.context.scene.node_tree.links.new(image_nodes[1].outputs['Combined'], alpha_over_nodes[0].inputs[2])
|
bpy.context.scene.node_tree.links.new(image_nodes[1].outputs['Combined'], alpha_over_nodes[index].inputs[2])
|
||||||
|
if denoising:
|
||||||
|
albedo_mix_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeMixRGB'))
|
||||||
|
albedo_mix_nodes[index].blend_type = 'ADD'
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[0].outputs['Denoising Albedo'], albedo_mix_nodes[index].inputs[1])
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[1].outputs['Denoising Albedo'], albedo_mix_nodes[index].inputs[2])
|
||||||
|
normal_mix_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeMixRGB'))
|
||||||
|
normal_mix_nodes[index].blend_type = 'ADD'
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[0].outputs['Denoising Normal'], normal_mix_nodes[index].inputs[1])
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[1].outputs['Denoising Normal'], normal_mix_nodes[index].inputs[2])
|
||||||
else:
|
else:
|
||||||
# Take one image node and the previous alpha over node
|
# Take one image node and the previous alpha over node
|
||||||
alpha_over_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeAlphaOver'))
|
alpha_over_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeAlphaOver'))
|
||||||
bpy.context.scene.node_tree.links.new(alpha_over_nodes[index-1].outputs['Image'], alpha_over_nodes[index].inputs[1])
|
bpy.context.scene.node_tree.links.new(alpha_over_nodes[index-1].outputs['Image'], alpha_over_nodes[index].inputs[1])
|
||||||
bpy.context.scene.node_tree.links.new(image_nodes[index+1].outputs['Combined'], alpha_over_nodes[index].inputs[2])
|
bpy.context.scene.node_tree.links.new(image_nodes[index+1].outputs['Combined'], alpha_over_nodes[index].inputs[2])
|
||||||
|
if denoising:
|
||||||
|
albedo_mix_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeMixRGB'))
|
||||||
|
albedo_mix_nodes[index].blend_type = 'ADD'
|
||||||
|
bpy.context.scene.node_tree.links.new(albedo_mix_nodes[index-1].outputs['Image'], albedo_mix_nodes[index].inputs[1])
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[index+1].outputs['Denoising Albedo'], albedo_mix_nodes[index].inputs[2])
|
||||||
|
normal_mix_nodes.append(bpy.context.scene.node_tree.nodes.new(type='CompositorNodeMixRGB'))
|
||||||
|
normal_mix_nodes[index].blend_type = 'ADD'
|
||||||
|
bpy.context.scene.node_tree.links.new(normal_mix_nodes[index-1].outputs['Image'], normal_mix_nodes[index].inputs[1])
|
||||||
|
bpy.context.scene.node_tree.links.new(image_nodes[index+1].outputs['Denoising Normal'], normal_mix_nodes[index].inputs[2])
|
||||||
if index + 1 == len(image_nodes) - 1:
|
if index + 1 == len(image_nodes) - 1:
|
||||||
# Link the last image node and feed the output into the composite node
|
if denoising:
|
||||||
output_node = bpy.context.scene.node_tree.nodes.new(type='CompositorNodeOutputFile')
|
denoise_node = bpy.context.scene.node_tree.nodes.new(type='CompositorNodeDenoise')
|
||||||
output_node.base_path = basepath + "MERGED"
|
bpy.context.scene.node_tree.links.new(alpha_over_nodes[index].outputs['Image'], denoise_node.inputs['Image'])
|
||||||
bpy.context.scene.node_tree.links.new(alpha_over_nodes[index].outputs['Image'], output_node.inputs['Image'])
|
bpy.context.scene.node_tree.links.new(albedo_mix_nodes[index].outputs['Image'], denoise_node.inputs['Albedo'])
|
||||||
|
bpy.context.scene.node_tree.links.new(normal_mix_nodes[index].outputs['Image'], denoise_node.inputs['Normal'])
|
||||||
|
bpy.context.scene.node_tree.links.new(denoise_node.outputs['Image'], output_node.inputs['Image'])
|
||||||
|
else:
|
||||||
|
# Link the last image node and feed the output into the composite node
|
||||||
|
bpy.context.scene.node_tree.links.new(alpha_over_nodes[index].outputs['Image'], output_node.inputs['Image'])
|
||||||
break
|
break
|
||||||
bpy.ops.render.render()`;
|
bpy.ops.render.render(write_still=True)`;
|
||||||
const command = author.Command("blender-render", {
|
const command = author.Command("blender-render", {
|
||||||
exe: "{blender}",
|
exe: "{blender}",
|
||||||
exeArgs: "{blenderArgs}",
|
exeArgs: "{blenderArgs}",
|
||||||
@ -205,42 +224,14 @@ bpy.ops.render.render()`;
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
function authorCreateDenoiseTask(settings, renderOutput) {
|
|
||||||
if (! settings.use_denoising) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const task = author.Task(`denoise`, "blender");
|
|
||||||
let pythonExpression = `
|
|
||||||
import bpy
|
|
||||||
print("Running the denoiser")
|
|
||||||
bpy.ops.cycles.denoise_animation(input_filepath="${renderOutput}/MERGED.exr", output_filepath="${renderOutput}/DENOISED.exr")`;
|
|
||||||
const command = author.Command("blender-render", {
|
|
||||||
exe: "{blender}",
|
|
||||||
exeArgs: "{blenderArgs}",
|
|
||||||
argsBefore: [],
|
|
||||||
blendfile: settings.blendfile,
|
|
||||||
args: [
|
|
||||||
"--python-exit-code", 1,
|
|
||||||
"--python-expr", pythonExpression
|
|
||||||
]
|
|
||||||
});
|
|
||||||
task.addCommand(command);
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
function authorCreateCompositeTask(settings, renderOutput) {
|
function authorCreateCompositeTask(settings, renderOutput) {
|
||||||
let filename;
|
let filename;
|
||||||
let pythonExpression = `
|
let pythonExpression = `
|
||||||
import pathlib
|
import pathlib
|
||||||
import os
|
|
||||||
import bpy
|
import bpy
|
||||||
C = bpy.context
|
C = bpy.context
|
||||||
basepath = "${renderOutput}/"
|
basepath = "${renderOutput}/"
|
||||||
filenames = [f for f in os.listdir(basepath) if os.path.isfile(basepath + f)]
|
filename = "MERGED.exr"
|
||||||
if "DENOISED.exr" in filenames:
|
|
||||||
filename = "DENOISED.exr"
|
|
||||||
else:
|
|
||||||
filename = next((s for s in filenames if "MERGED" in s), None)
|
|
||||||
`;
|
`;
|
||||||
if (settings.use_compositing) {
|
if (settings.use_compositing) {
|
||||||
// Do the full composite+export pipeline
|
// Do the full composite+export pipeline
|
||||||
|
Loading…
Reference in New Issue
Block a user