blender/blender python

안개 효과 생성

monstro 2025. 8. 13. 16:46
728x90
반응형

- 개요

노드간의 조합을 통해 안개 효과를 생성하는 애드온을 만들어본다

 

1) 노드를 조합하는 함수

import bpy
from bpy.types import Panel, Operator

def mist_comp_action(context):
    tree = context.scene.node_tree
    
    # Set Compositor Node
    comp_node = tree.nodes.get('Composite')
    comp_node.location = (700, 0)
    
    # Set Viewer Node
    viewer_node = tree.nodes.new('CompositorNodeViewer')
    viewer_node.location = (700, 200)
    
    # Set Render Layers Node
    render_layer_node = tree.nodes.get('Render Layers')
    render_layer_node.location = (-200, 0)
    
    # Set Mix Color Node
    mix_node = tree.nodes.new('CompositorNodeMixRGB')
    mix_node.location = (500, 0)
    mix_node.blend_type = 'ADD'
    mix_node.use_clamp = True
    
    # Set Another Mix Color Node
    mix2_node = tree.nodes.new('CompositorNodeMixRGB')
    mix2_node.location = (300, 0)
    mix2_node.blend_type = 'MULTIPLY'
    mix2_node.use_clamp = True
    
    # Set Color Ramp Node
    cr_node = tree.nodes.new('CompositorNodeValToRGB')
    cr_node.location = (0, 0)
    cr_node.color_ramp.elements[0].color = (0.2, 0.2, 0.2, 1)
    cr_node.color_ramp.elements.new(position= 0.27)
    
    # Connect Node`s Link
    link = tree.links.new
    
    link(mix_node.outputs[0], viewer_node.inputs[0])
    link(mix_node.outputs[0], comp_node.inputs[0])
    link(mix2_node.outputs[0], mix_node.inputs[1])
    link(cr_node.outputs[0], mix2_node.inputs[1])
    link(render_layer_node.outputs[0], mix_node.inputs[2])
    link(render_layer_node.outputs[3], cr_node.inputs[0])
    
    return {'FINISHED'}
    
...

 

mist_comp_action 함수의 로직은 다음과 같다

  • Compositor 노드 생성
  • Viewer 노드 생성
  • Render Layers 노드 생성
  • Mix Color 노드 생성
  • 또 다른 Mix Color 노드 생성
  • Color Ramp 노드 생성
  • 생성한 노드들 연결

 

2) 메인 패널 클래스

...

class im_PT_main_panel(Panel):
    bl_label = "Main Panel"
    bl_idname = "im_PT_main_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "INSTA-MIST"
 
    def draw(self, context):
        layout = self.layout
        scene = context.scene
        world = scene.world.mist_settings
        
        # Set props of Mist Pass
        layout.prop(world, "start")
        layout.prop(world, "depth")
        layout.prop(world, "falloff")
        
        layout.operator("im.myop_operator")
        
...

 

im_PT_main_panel 클래스메인 패널로서 동작한다

따라서 bpy.types.Panel 클래스를 상속받는다

패널을 정의하는 draw 함수는 다음과 같이 정의하였다

 

 

생성되는 안개에 영향을 주기 위한 World - Mist Pass 속성의 값을 레이아웃에서 입력받도록 설정한다

입력한 값을 통해 레이아웃의 Operator에서 작업을 진행한다

 

 

3) Operator 클래스

...

class im_OT_my_op(Operator):
    bl_label = "Enable / Disable Mist"
    bl_idname = "im.myop_operator"
    
    def execute(self, context):
        # Get Camera from Scene
        scene = context.scene
        camera = bpy.data.cameras['Camera']
        vl = bpy.context.scene.view_layers["ViewLayer"]
        tree = scene.node_tree
        
        # Enable or Disable Camera`s option
        vl.use_pass_mist = not(vl.use_pass_mist)
        scene.use_nodes = True
        
        if vl.use_pass_mist == True:
            camera.show_mist = True
            mist_comp_action(context)
        else:
            camera.show_mist = False
            mix1 = tree.nodes.remove(tree.nodes.get('Mix'))
            mix2 = tree.nodes.remove(tree.nodes.get('Mix.001'))
            cr = tree.nodes.remove(tree.nodes.get('Color Ramp'))
            
            comp_node = tree.nodes.get('Composite')
            viewer_node = tree.nodes.get('Viewer')
            render_layer_node = tree.nodes.get('Render Layers')
            
            tree.links.new(render_layer_node.outputs[0], comp_node.inputs[0])
            tree.links.new(render_layer_node.outputs[0], viewer_node.inputs[0])

        
        return {'FINISHED'}
        
...

 

im_OT_my_op 클래스패널에서 수행할 동작을 정의한다

따라서 bpy.types.Operator 클래스를 상속받는다

동작을 정의하는 execute 함수는 다음과 같이 정의하였다

 

ViewLayer의 Mist 설정

 

Camera의 Mist 설정

 

안개 효과를 사용하기 위해 필요한 2개의 설정값을 우선 설정한다

  •  ViewLayer의 Mist 옵션이 True인 경우:
    • Camera의 Mist 옵션을 True로 설정
    • mist_comp_action 함수를 호출하고 노드를 조합하여 안개효과 구현
  • ViewLayer의 Mist 옵션이 False인 경우:
    • Camera의 Mist 옵션을 False로 설정
    • 생성된 노드 중에서 Mix 노드와 Color Ramp 노드제거하고 남은 노드들 연결

 

4) 생성한 클래스 등록 / 등록해제

...

classes = [im_PT_main_panel, im_OT_my_op]
 
 
def register():
    for cls in classes:
        bpy.utils.register_class(cls)
        
 
def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
 
 
if __name__ == "__main__":
    register()

 

register 함수와 unregister 함수를 오버라이드하여 생성한 클래스들을 등록 / 등록해제한다

 

- 최종 실행 결과

1) 안개 효과를 주지 않은 상황의 렌더링 결과

 

2) 안개 효과를 준 상황의 렌더링 결과

 

728x90
반응형

'blender > blender python' 카테고리의 다른 글

Info 메세지 출력  (0) 2025.08.19
리스트  (0) 2025.08.19
랜덤값  (0) 2025.08.13
모듈 임포트  (0) 2025.08.06
프로퍼티 서브타입  (0) 2025.08.06