- 개요
컴포지터는 렌더링이 끝난 이미지나 동영상에 추가적인 보정과 편집을 수행하는 공간이다
이와 같은 컴포지터를 구성하는 커스텀 노드 그룹을 생성할 수 있는 Add-On을 만들어본다
1) 메인 패널 클래스
import bpy
class NODE_PT_MAINPANEL(bpy.types.Panel):
bl_label = "Custom Node Group"
bl_idname = "NODE_PT_MAINPANEL"
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_category = "New Tab"
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator('node.test_operator')
...
메인 패널 역할을 수행하는 NODE_PT_MAINPANEL 클래스를 생성하였다
패널로 사용해야 하므로 bpy.types.panel 클래스를 상속받았다
어트리뷰트는 다음과 같이 구성하였다
- 메인 패널 클래스의 라벨
- 메인 패널 클래스의 idname
- 메인 패널을 사용할 스페이스, 컴포지터에서 사용하므로 노드 에디터로 지정
- 패널의 타입을 UI로 지정하여 사이드바에 패널을 추가
- 사이드바에서 메인 패널의 카테고리
메인 패널 클래스의 어트리뷰트를 정의하였다면 draw 함수를 통해 패널을 구현해야 한다
레이아웃을 잡고 연산(기능)을 수행할 하나의 행을 추가한다
해당 행의 operator 속성에 Add-On 클래스의 idname을 인자로 넣어준다
2) 커스텀 노드 그룹 생성 함수
...
def create_test_group(context, operator, group_name):
# Enable use nodes
bpy.context.scene.use_nodes = True
# Ceate Node Group
test_group = bpy.data.node_groups.new(group_name, 'CompositorNodeTree')
# Set Node Group Input node
group_in = test_group.nodes.new('NodeGroupInput')
group_in.location = (-200,0)
test_group.interface.new_socket(name = 'Factor Value', in_out = 'INPUT')
test_group.interface.new_socket(name = 'Color Input', in_out = 'INPUT')
# Set Node Group Output node
group_out = test_group.nodes.new('NodeGroupOutput')
group_out.location = (400,0)
test_group.interface.new_socket(name = 'NodeSocketColor', in_out = 'OUTPUT')
# Set Mask Node
mask_node = test_group.nodes.new(type='CompositorNodeBoxMask')
mask_node.location = (0, 0)
mask_node.rotation = 1
# Set Mix Node
mix_node = test_group.nodes.new(type='CompositorNodeMixRGB')
mask_node.location = (200, 0)
mix_node.use_clamp = True
mix_node.blend_type = 'OVERLAY'
# Link All nodes
link = test_group.links.new
link(mask_node.outputs[0], mix_node.inputs[1])
link(group_in.outputs[0], mix_node.inputs[0])
link(group_in.outputs[0], mix_node.inputs[2])
link(mix_node.outputs[0], group_out.inputs[0])
# return Custom Node Group
return test_group
...
create_test_group 함수는 커스텀 노드 그룹을 생성한다
절차는 각각 다음과 같이 구분할 수 있다
- 생성할 노드 그룹에 대해 노드의 사용을 허가한다
- CompositorNodeTree 타입의 노드 그룹를 생성한다
- 생성한 노드 그룹에 대한 인풋 노드를 생성하고 설정한다
- 인자로는 실수값과 컬러값을 받는다
- 생성한 노드 그룹에 대한 아웃풋 노드를 생성하고 설정한다
- 반환값은 컬러값을 반환한다
- 직사각형의 마스크를 생성하는 마스크 노드를 생성한다
- 두 개의 컬러 입력 값을 혼합하는 Mix 노드를 생성하고 설정한다
- 혼합 모드는 Overlay 방식으로 설정
- clamp를 사용하여 받은 두 개의 입력값을 절충하여 생성
- 완성한 노드들을 연결하여 설정이 끝난 노드 그룹 반환
3) 노드 그룹 생성 함수를 사용하는 동작 클래스 생성
...
class NODE_OF_TEST(bpy.types.Operator):
bl_label = "Add Custom Node Group"
bl_idname = "node.test_operator"
def execute(self, context):
custom_node_name = "Test Node"
my_group = create_test_group(self, context, custom_node_name)
test_node = context.scene.node_tree.nodes.new('CompositorNodeGroup')
test_node.node_tree = bpy.data.node_groups[my_group.name]
test_node.use_custom_color = True
test_node.color = (0.5, 0.4, 0.3)
return {'FINISHED'}
...
2)에서 생성한 함수를 사용하는 Operator 클래스를 정의하였다
해당 클래스에서 클래스의 라벨과 idname 속성을 설정한다
이후 Operator 클래스의 동작을 위한 execute 함수를 정의하였다
2)에서 정의한 함수를 사용하여 커스텀 노드 그룹을 생성 + CompositorNodeGroup 타입의 노드를 생성한다
CompositorNodeGroup 타입의 노드의 노드 트리에 커스텀 노드 그룹을 추가하고
CompositorNodeGroup 타입의 노드에서 색을 설정한다
이후 execute 함수를 종료하기 위해 FINISHED를 반환한다
4) 작성한 Add-On 클래스의 등록
...
def register():
bpy.utils.register_class(NODE_PT_MAINPANEL)
bpy.utils.register_class(NODE_OF_TEST)
def unregister():
bpy.utils.unregister_class(NODE_PT_MAINPANEL)
bpy.utils.unregister_class(NODE_OF_TEST)
if __name__ == "__main__":
register()
register 함수와 unregister 함수를 추가하여 작성한 Add-On 클래스를 등록 / 등록해제할 수 있도록 한다
- 최종 실행 결과
'blender > blender python' 카테고리의 다른 글
| 단축키 (0) | 2025.07.23 |
|---|---|
| 커스텀 레이아웃 (0) | 2025.07.17 |
| 텍스트 Add-On (0) | 2025.07.09 |
| 대화 상자 (0) | 2025.07.09 |
| BPY를 이용한 키프레임 모디파이어 추가 (0) | 2025.07.02 |