Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Convert OpenGL normal-map nodes to DirectX normal-map nodes in this scene.
- Run this script from Blender's Text Editor. It updates every Normal Map node in
- materials assigned to objects in the active scene, including nodes inside nested
- shader node groups.
- """
- import bpy
- def iter_material_node_trees(material):
- """Yield the material node tree and any nested shader node-group trees once."""
- visited_trees = set()
- def visit(node_tree):
- if node_tree is None or node_tree.as_pointer() in visited_trees:
- return
- visited_trees.add(node_tree.as_pointer())
- yield node_tree
- for node in node_tree.nodes:
- if node.type == 'GROUP' and node.node_tree is not None:
- yield from visit(node.node_tree)
- yield from visit(material.node_tree)
- def scene_materials(scene):
- """Yield each material assigned to an object in *scene* once."""
- seen_materials = set()
- for obj in scene.objects:
- for material_slot in obj.material_slots:
- material = material_slot.material
- if material is None or material.as_pointer() in seen_materials:
- continue
- seen_materials.add(material.as_pointer())
- yield material
- def convert_opengl_normal_maps_to_directx(scene=None):
- """Set OpenGL Normal Map node conventions to DirectX and return counts."""
- scene = scene or bpy.context.scene
- material_count = 0
- converted_count = 0
- for material in scene_materials(scene):
- if not material.use_nodes or material.node_tree is None:
- continue
- material_count += 1
- for node_tree in iter_material_node_trees(material):
- for node in node_tree.nodes:
- if node.type != 'NORMAL_MAP':
- continue
- # Blender 5.2's Normal Map node Mode dropdown; this does not
- # modify the RGB values in the source image.
- if node.convention == 'OPENGL':
- node.convention = 'DIRECTX'
- converted_count += 1
- print(
- f"OpenGL to DirectX Normal Map: converted {converted_count} node(s) "
- f"across {material_count} scene material(s)."
- )
- return converted_count, material_count
- if __name__ == "__main__":
- convert_opengl_normal_maps_to_directx()
Advertisement