Python을 사용하여 Blender에서 디지털 시계를 스크립팅하는 방법

12601 단어 pythontutorialblender
이 튜토리얼은 Blender 2.91을 사용합니다.

사용 가능 here



장면을 설정합니다.



이것은 기본 사항을 다루지 않습니다. 시작하려면 Andrew Price의 훌륭한 튜토리얼 비디오를 추천합니다. 그러나 이 장면을 정확히 복제하는 데 필요한 모든 것이 아래에 나열되어 있습니다.

기본 큐브 제거, 카메라 위치 변경, 표시된 설정으로 텍스트 추가를 제외하고 이 장면의 모든 것이 기본값입니다.

평면과 텍스트의 재료는 기본 원칙 셰이더입니다. 이 경우 평면은 검은색이고 텍스트는 흰색입니다.



이것이 우리가 시작하는 것입니다. 텍스트 개체의 이름은 "텍스트"입니다. 나중에 이 개체를 참조하는 데 사용할 것입니다. 또한 텍스트를 메쉬로 변환하지 마십시오. 일부 글꼴은 3d 지오메트리를 텍스트 개체로 제공할 때 아티팩트 때문에 올바르게 렌더링하려면 정적 메시로 변환해야 합니다. 이렇게 하려면 호환되는 글꼴을 선택하기만 하면 됩니다. 부드러운 모서리와 가장자리가 가장 좋습니다.

파이썬 출시





UI를 사용하여 이 장면을 설정하기 위해 수행한 모든 작업은 Python으로도 스크립팅할 수 있습니다. API를 배우려면 Blender를 사용하고 Python 콘솔의 출력을 살펴보기만 하면 됩니다. 이 경우 UI를 사용하여 장면을 만들고 흥미로운 부분을 Python에서 코딩했지만 스크립트에서도 Python 콘솔의 명령을 복제하면 동일한 장면이 나타납니다. 실제로 UI가 전혀 필요하지 않으며 도전을 원하는 경우 표시된 Python에서 전체 장면을 구성할 수 있습니다.

작동 원리



다음은 시계를 작동시키는 데이터 구조, 생성기 및 콜백을 분해합니다.

데이터 구조.



다음 섹션의 이 total_frames는 풀 모션 디스플레이에 대해 계산됩니다. 이 예제는 장면 요소가 움직이지 않는 경우 이러한 모든 프레임을 렌더링할 필요가 없으며 그 방법은 나중에 다룹니다.

minute, second = '10', '01' # variable assignment
total_frames = ((int(minute) * 60) + int(second)) * 30 # 30fps video times the total seconds
scene.frame_end = total_frames # let Blender know how long the scene is.

seconds = ['%02d'% (i,) for i in reversed(range(60))] # list comprehension to create all the seconds in a minute

seconds_arr = [seconds] * int(minute) # this is what we give to our generator

if not second == '00': # if the timer is not a whole minute, we need a partial list to add to the front.
    seconds_arr[:0] = [seconds[(60 - int(second)):]]


이렇게 하면 시계가 0까지 카운트다운하는 올바른 순서가 생성됩니다. 세려면 생략

reversed()


부분 초를 끝에 추가하십시오.

[seconds[:(60 - int(second))]]


발전기



방금 만든 구조를 반복하는 방법에는 여러 가지가 있습니다. 내가 선택한 방법은 프레임 변경 콜백이 다음 반복 함수를 호출하기에 완벽한 시간이라는 것을 알았기 때문에 생성기를 만드는 것이었습니다.

# this function will count through the seconds_arr and give us the correct clock face string each time it is called.
@persistent # this decorator keeps the generator from being refreshed during the render.
def time_remaining(seconds_arr):
    while seconds_arr:
        current_minute = seconds_arr.pop(0)
        for sec in current_minute:
            yield (str(len(seconds_arr)) + ':' + str(sec))


clock = time_remaining(seconds_arr) # now we have the generator, we just need a way to call it


합병증



카운트다운만 원하는 경우 건너뜁니다. 나는 시계가 장면 주위에서 부드럽게 움직이기를 원했고 모든 키프레임을 손으로 설정하고 싶지 않았습니다. 기하학에서 기억할 수 있는 다른 방법을 사용하여 원이나 그림 8 패턴을 그릴 수 있습니다. 작은 범위 내에서 모든 축에서 임의의 움직임을 원했습니다.

text.location = (0,0,.2) # set the starting location x, y, z
text.keyframe_insert('location', frame=1) # first keyframe
text.keyframe_insert('location', frame=scene.frame_end) # last keyframe

for frame in range(total_frames):
    if frame % 300 == 0: # every 10 seconds
        text.location = (random.uniform(-2,2),random.uniform(-1.2,1.2),random.uniform(.2, 1.0)) # pick a random number for all three axis
        text.keyframe_insert('location', frame=frame) # add keyframe

text.location = (0,0,.2) # move the text back to the start before the render starts (for a test render)


콜백



모든 것을 하나로 묶고 장면을 자동화할 시간입니다. 블렌더는 콜백을 트리거할 수 있는 몇 가지 강력한 이벤트를 제공합니다.

# this is the callback function that will fire on each frame change. The callback passes the current scene as its first argument.
def draw_clock(scene):
    global clock # global variable
    text = scene.objects['Text'] # grab the text object
    current_frame = scene.frame_current
    if current_frame % 30 == 0: # every second at the project fps
        text.data.body = next(clock) # invoke the generator

bpy.app.handlers.frame_change_pre.append(draw_clock) # attach callback to the frame change event.


이 예에서 선택한 방법은 frame_change_pre입니다. 프레임이 그려지기 전에 프레임이 변경될 때마다 실행됩니다. 변경 시 프레임 번호를 프레임 속도로 나눌 수 있는 경우 마지막으로 렌더링된 프레임 직전에 0이 될 때까지 두 번째 카운트가 감소합니다.

렌더링 시간



스크립트는 한 번만 실행하면 됩니다. 위 스크린샷에는 명령줄에서 이 스크립트를 사용하기 위한 주석 코드를 남겼습니다. 스크립트가 실행되면 이미지를 렌더링하는 경우 다음과 같은 첫 번째 프레임이 있어야 합니다.



모든 것이 좋아 보인다면 출력 디렉토리를 확인하고 프로젝트 fps를 30으로 변경하고 Render Animation을 누르십시오. 10:01 애니메이션은 18030 프레임이므로 선택적 코드로 시계가 화면을 이동하는 경우 이 렌더링 시간이 오래 걸릴 것으로 예상하십시오! 모션 없이 렌더링하는 경우 광원이 움직이지 않고 똑같은 프레임을 반복적으로 렌더링할 이유가 없기 때문에 프레임 0에서 시작하여 각 시퀀스마다 30프레임을 건너뛸 수 있습니다.

좋은 웹페이지 즐겨찾기