Skip to content

Commit a8bfdb9

Browse files
committed
Add ambient occlusion features to rendering utilities
- Implemented `enable_ambient_occlusion` function in RendererUtility.py - Added `add_ambient_occlusion` method in MeshObjectUtility.py - Enhanced scene and material handling for ambient occlusion effects
1 parent 3b0002a commit a8bfdb9

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

blenderproc/python/renderer/RendererUtility.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,3 +918,38 @@ def set_render_devices(use_only_cpu: bool = False, desired_gpu_device_type: Unio
918918
bpy.context.scene.cycles.device = "CPU"
919919
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = "NONE"
920920
print("Using only the CPU for rendering")
921+
922+
923+
def enable_ambient_occlusion(distance: float = 1.0, strength: float = 1.0):
924+
""" Enables ambient occlusion in the scene. This can improve object part or point separation.
925+
926+
:param distance: Length of rays, defines how far away other faces give occlusion effect.
927+
:param strength: The amount of ambient occlusion effect added to the scene.
928+
"""
929+
bpy.context.scene.view_layers['ViewLayer'].use_pass_ambient_occlusion = True
930+
bpy.context.scene.world.light_settings.distance = distance
931+
bpy.context.scene.use_nodes = True
932+
933+
nodes = bpy.context.scene.node_tree.nodes
934+
render_layers_node = Utility.get_the_one_node_with_type(nodes, 'CompositorNodeRLayers')
935+
mix_rgb_node = nodes.new('CompositorNodeMixRGB')
936+
mix_rgb_node.blend_type = 'MULTIPLY'
937+
mix_rgb_node.inputs[0].default_value = strength
938+
939+
# Insert the mix-rgb node in between denoise and composite node, if a denoise node is present
940+
links = bpy.context.scene.node_tree.links
941+
try:
942+
denoise_node = Utility.get_the_one_node_with_type(nodes, 'CompositorNodeDenoise')
943+
Utility.insert_node_instead_existing_link(links,
944+
render_layers_node.outputs['Image'],
945+
mix_rgb_node.inputs['Image'],
946+
mix_rgb_node.outputs['Image'],
947+
denoise_node.inputs['Image'])
948+
except RuntimeError:
949+
composite_node = Utility.get_the_one_node_with_type(nodes, 'CompositorNodeComposite')
950+
Utility.insert_node_instead_existing_link(links,
951+
render_layers_node.outputs['Image'],
952+
mix_rgb_node.inputs['Image'],
953+
mix_rgb_node.outputs['Image'],
954+
composite_node.inputs['Image'])
955+
links.new(render_layers_node.outputs['AO'], mix_rgb_node.inputs[2])

blenderproc/python/types/MeshObjectUtility.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,31 @@ def add_auto_smooth_modifier(self, angle: float = 30.0):
551551
modifier = self.blender_obj.modifiers["Smooth by Angle"]
552552
modifier["Input_1"] = np.deg2rad(float(angle))
553553

554+
def add_ambient_occlusion(self, distance: float = 1.0, samples: int = 16, only_local: bool = False):
555+
""" Adds an ambient occlusion effect to the object. This can improve object part or point separation.
556+
557+
:param distance: Length of rays, defines how far away other faces give occlusion effect.
558+
:param samples: Number of rays to trace per shader evaluation.
559+
:param only_local: Only consider the object itself when computing AO.
560+
"""
561+
for material in self.get_materials():
562+
ao_node = material.new_node('ShaderNodeAmbientOcclusion')
563+
ao_node.inputs['Distance'].default_value = distance
564+
ao_node.samples = samples
565+
ao_node.only_local = only_local
566+
567+
# Insert the ambient occlusion node in between the attribute node and the bsdf node, if present
568+
try:
569+
attribute_node = material.get_the_one_node_with_type('ShaderNodeAttribute')
570+
bsdf_node = material.get_the_one_node_with_type('ShaderNodeBsdfPrincipled')
571+
material.insert_node_instead_existing_link(attribute_node.outputs['Color'],
572+
ao_node.inputs['Color'],
573+
ao_node.outputs['Color'],
574+
bsdf_node.inputs['Base Color'])
575+
except RuntimeError:
576+
ao_node.inputs['Color'].default_value = material.get_principled_shader_value('Base Color')
577+
material.set_principled_shader_value('Base Color', ao_node.outputs['Color'])
578+
554579
def mesh_as_trimesh(self) -> Trimesh:
555580
""" Returns a trimesh.Trimesh instance of the MeshObject.
556581

0 commit comments

Comments
 (0)