def process_call_function(stage, stages, node, node_group): # Step till merge node stage['returns_true'] = [] if node.outputs[0].is_linked: stageNode = nodes.find_node_by_link_from(node_group, node, node.outputs[0]) buildNode(stage['returns_true'], stageNode, node_group) stage['returns_false'] = [] margeNode = None if node.outputs[1].is_linked: stageNode = nodes.find_node_by_link_from(node_group, node, node.outputs[1]) margeNode = buildNode(stage['returns_false'], stageNode, node_group) # Continue using top level stages after merge node if margeNode != None: afterMergeNode = nodes.find_node_by_link_from(node_group, margeNode, margeNode.outputs[0]) buildNode(stages, afterMergeNode, node_group)
def get_root_node(node_group): # Find first node linked to begin node rn = None for n in node_group.nodes: if n.bl_idname == 'BeginNodeType': # Store contexts build_node_tree.cam.renderpath_id = n.inputs[0].default_value # TODO: deprecated if len(n.inputs) > 5: if n.inputs[5].default_value == False: bpy.data.worlds['Arm'].rp_defs += '_LDR' else: if n.inputs[1].default_value == False: bpy.data.worlds['Arm'].rp_defs += '_LDR' rn = nodes.find_node_by_link_from(node_group, n, n.outputs[0]) break return rn
def buildNode(stages, node, node_group): stage = {} stage['params'] = [] append_stage = True if node.bl_idname == 'MergeStagesNodeType': return node elif node.bl_idname == 'SetTargetNodeType': buildNode.last_bind_target = None make_set_target(stage, node_group, node) elif node.bl_idname == 'SetViewportNodeType': make_set_viewport(stage, node_group, node) elif node.bl_idname == 'ClearTargetNodeType': color_val = None depth_val = None stencil_val = None if node.inputs[1].default_value == True: if node.inputs[ 2].is_linked: # Assume background color node is linked color_val = -1 # Clear to world.background_color else: color_val = node.inputs[2].default_value if node.inputs[3].default_value == True: depth_val = node.inputs[4].default_value if node.inputs[5].default_value == True: stencil_val = node.inputs[6].default_value make_clear_target(stage, color_val=color_val, depth_val=depth_val, stencil_val=stencil_val) elif node.bl_idname == 'ClearImageNodeType': image_node = node.inputs[1].links[0].from_node image_name = image_node.inputs[0].default_value color_val = node.inputs[2].default_value make_clear_image(stage, image_name, color_val) elif node.bl_idname == 'GenerateMipmapsNodeType': make_generate_mipmaps(stage, node_group, node) elif node.bl_idname == 'DrawMeshesNodeType': make_draw_meshes(stage, node_group, node) elif node.bl_idname == 'DrawDecalsNodeType': make_draw_decals(stage, node_group, node) elif node.bl_idname == 'BindTargetNodeType': if buildNode.last_bind_target is not None: stage = buildNode.last_bind_target append_stage = False buildNode.last_bind_target = stage constant_name = node.inputs[2].default_value make_bind_target(stage, node_group, node, constant_name) elif node.bl_idname == 'DrawMaterialQuadNodeType': make_draw_material_quad(stage, node_group, node) elif node.bl_idname == 'DrawQuadNodeType': make_draw_quad(stage, node_group, node) elif node.bl_idname == 'DrawWorldNodeType': # Bind depth for quad # if node.inputs[1].is_linked: # stage = {} # stage['params'] = [] # buildNode.last_bind_target = stage # if node.inputs[1].is_linked: # make_bind_target(stage, node_group, node, target_index=1, constant_name='gbufferD') # stages.append(stage) stage = {} stage['params'] = [] # Draw quad # make_draw_world(stage, node_group, node, dome=False) # Draw dome make_draw_world(stage, node_group, node, dome=True) elif node.bl_idname == 'DrawCompositorNodeType' or node.bl_idname == 'DrawCompositorWithFXAANodeType': # Set target if node.inputs[1].is_linked: make_set_target(stage, node_group, node) stages.append(stage) # Bind targets if node.inputs[2].is_linked or node.inputs[3].is_linked or node.inputs[ 4].is_linked: stage = {} stage['params'] = [] buildNode.last_bind_target = stage if node.inputs[2].is_linked: make_bind_target(stage, node_group, node, target_index=2, constant_name='tex') if node.inputs[3].is_linked: make_bind_target(stage, node_group, node, target_index=3, constant_name='gbufferD') if node.inputs[4].is_linked: make_bind_target(stage, node_group, node, target_index=4, constant_name='gbuffer0') stages.append(stage) # Draw quad stage = {} stage['params'] = [] with_fxaa = node.bl_idname == 'DrawCompositorWithFXAANodeType' make_draw_compositor(stage, node_group, node, with_fxaa=with_fxaa) elif node.bl_idname == 'DrawGreasePencilNodeType': stage = {} stage['params'] = [] make_draw_grease_pencil(stage, node_group, node) elif node.bl_idname == 'BranchFunctionNodeType': make_branch_function(stage, node_group, node) stages.append(stage) process_call_function(stage, stages, node, node_group) return elif node.bl_idname == 'LoopStagesNodeType': # Just repeats the commands append_stage = False if node.outputs[1].is_linked: count = node.inputs[2].default_value for i in range(0, count): loopNode = nodes.find_node_by_link_from( node_group, node, node.outputs[1]) buildNode(stages, loopNode, node_group) elif node.bl_idname == 'LoopLampsNodeType': append_stage = False stage['command'] = 'loop_lamps' stages.append(stage) stage['returns_true'] = [] if node.outputs[1].is_linked: loopNode = nodes.find_node_by_link_from(node_group, node, node.outputs[1]) buildNode(stage['returns_true'], loopNode, node_group) elif node.bl_idname == 'DrawStereoNodeType': append_stage = False stage['command'] = 'draw_stereo' stages.append(stage) stage['returns_true'] = [] if node.outputs[1].is_linked: loopNode = nodes.find_node_by_link_from(node_group, node, node.outputs[1]) buildNode(stage['returns_true'], loopNode, node_group) elif node.bl_idname == 'CallFunctionNodeType': make_call_function(stage, node_group, node) elif node.bl_idname == 'QuadPassNodeType': make_quad_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'SSAOPassNodeType': make_ssao_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'SSAOReprojectPassNodeType': make_ssao_reproject_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'ApplySSAOPassNodeType': make_apply_ssao_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'SSRPassNodeType': make_ssr_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'BloomPassNodeType': make_bloom_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'MotionBlurPassNodeType': make_motion_blur_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'MotionBlurVelocityPassNodeType': make_motion_blur_velocity_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'CopyPassNodeType': make_copy_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'BlendPassNodeType': make_blend_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'CombinePassNodeType': make_combine_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'BlurBasicPassNodeType': make_blur_basic_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'DebugNormalsPassNodeType': make_debug_normals_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'FXAAPassNodeType': make_fxaa_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'SMAAPassNodeType': make_smaa_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'TAAPassNodeType': make_taa_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'SSSPassNodeType': make_sss_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'WaterPassNodeType': make_water_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'DeferredLightPassNodeType': make_deferred_light_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'DeferredIndirectPassNodeType': make_deferred_indirect_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'VolumetricLightPassNodeType': make_volumetric_light_pass(stages, node_group, node) append_stage = False elif node.bl_idname == 'TranslucentResolvePassNodeType': make_translucent_resolve_pass(stages, node_group, node) append_stage = False if append_stage: stages.append(stage) # Build next stage if node.outputs[0].is_linked: stageNode = nodes.find_node_by_link_from(node_group, node, node.outputs[0]) buildNode(stages, stageNode, node_group) return None
def traverse_renderpath(node, node_group, render_targets, depth_buffers): # Gather linked draw geometry contexts if node.bl_idname == 'DrawMeshesNodeType': if build_node_tree.cam.renderpath_passes != '': build_node_tree.cam.renderpath_passes += '_' # Separator build_node_tree.cam.renderpath_passes += node.inputs[1].default_value # Gather defs from linked nodes if node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType': if preprocess_renderpath.velocity_def_added == False: assets.add_khafile_def('arm_veloc') bpy.data.worlds['Arm'].rp_defs += '_Veloc' preprocess_renderpath.velocity_def_added = True if node.bl_idname == 'TAAPassNodeType': assets.add_khafile_def('arm_taa') # bpy.data.worlds['Arm'].rp_defs += '_TAA' elif node.bl_idname == 'SMAAPassNodeType': bpy.data.worlds['Arm'].rp_defs += '_SMAA' elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'ApplySSAOPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType': if bpy.data.worlds['Arm'].generate_ssao: # SSAO enabled bpy.data.worlds['Arm'].rp_defs += '_SSAO' elif node.bl_idname == 'DrawStereoNodeType': assets.add_khafile_def('arm_vr') bpy.data.worlds['Arm'].rp_defs += '_VR' elif node.bl_idname == 'CallFunctionNodeType': global dynRes_added fstr = node.inputs[1].default_value if not dynRes_added and fstr.startswith( 'armory.renderpath.DynamicResolutionScale'): bpy.data.worlds['Arm'].rp_defs += '_DynRes' dynRes_added = True # Collect render targets if node.bl_idname == 'SetTargetNodeType' or node.bl_idname == 'BindTargetNodeType' or node.bl_idname == 'QuadPassNodeType' or node.bl_idname == 'DrawCompositorNodeType' or node.bl_idname == 'DrawCompositorWithFXAANodeType': if node.inputs[1].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[1]) parse_render_target(tnode, node_group, render_targets, depth_buffers) # Traverse loops elif node.bl_idname == 'LoopStagesNodeType' or node.bl_idname == 'LoopLampsNodeType' or node.bl_idname == 'DrawStereoNodeType': if node.outputs[1].is_linked: loop_node = nodes.find_node_by_link_from(node_group, node, node.outputs[1]) traverse_renderpath(loop_node, node_group, render_targets, depth_buffers) # Prebuilt elif node.bl_idname == 'MotionBlurPassNodeType' or node.bl_idname == 'MotionBlurVelocityPassNodeType' or node.bl_idname == 'CopyPassNodeType' or node.bl_idname == 'BlendPassNodeType' or node.bl_idname == 'CombinePassNodeType' or node.bl_idname == 'DebugNormalsPassNodeType' or node.bl_idname == 'FXAAPassNodeType' or node.bl_idname == 'TAAPassNodeType' or node.bl_idname == 'WaterPassNodeType' or node.bl_idname == 'DeferredLightPassNodeType' or node.bl_idname == 'DeferredIndirectPassNodeType' or node.bl_idname == 'VolumetricLightPassNodeType' or node.bl_idname == 'TranslucentResolvePassNodeType': if node.inputs[1].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[1]) parse_render_target(tnode, node_group, render_targets, depth_buffers) elif node.bl_idname == 'SSRPassNodeType' or node.bl_idname == 'ApplySSAOPassNodeType' or node.bl_idname == 'BloomPassNodeType' or node.bl_idname == 'SMAAPassNodeType': for i in range(1, 4): if node.inputs[i].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[i]) parse_render_target(tnode, node_group, render_targets, depth_buffers) elif node.bl_idname == 'SSAOPassNodeType' or node.bl_idname == 'SSAOReprojectPassNodeType' or node.bl_idname == 'SSSPassNodeType' or node.bl_idname == 'BlurBasicPassNodeType': for i in range(1, 3): if node.inputs[i].is_linked: tnode = nodes.find_node_by_link(node_group, node, node.inputs[i]) parse_render_target(tnode, node_group, render_targets, depth_buffers) # Next stage if node.outputs[0].is_linked: stagenode = nodes.find_node_by_link_from(node_group, node, node.outputs[0]) traverse_renderpath(stagenode, node_group, render_targets, depth_buffers)