프리오리의 애니메이션 #1

9.13

앞선 네 캐릭터가 애니메이션 리스트를 완전하게 정립했으므로 기수를 나누지 않고 1,2,3기를 모두 한 번에 제작하자. 물량이 많은만큼, 꽤나 긴 여정이 될 것 같다. 일단 대기부터

팬티 안보였으면 좋겠는데… 자동으로 움직이는 애들이라 그게 안된다…

9.14

골반 본은 지금까지 잘 사용하지 않았다. 이것은 내가 3DSMAX를 사용하던 시절의 오래된 습관인데, 바이패드엔 저 골반에 해당하는 pelvis본이 후반 버전에 가서야 움직이기 시작했고, 그마저도 3축이 모두 돌아가지도 않았었다. 게다가 작업대상이 거의 SD화된 꼬맹이들이다보니 저런 골반 움직임에 큰 신경을 쓰지 않아도 됐었는데, 오늘 문득 어제 작업이 마음에 들지 않던 차에 처음으로 각잡고 사용해보니… 완전 신세계다! 지금까지 이걸 왜 안썼지! 애니메이터 인생을 손해본 기분이야!

Idle모션이 끝났으면 NLA에디터에 PushDown으로 등록해준다. 이것은 다른 애니메이션에서 ‘기본값’이 지정되지 않은 애니메이션에 대한 참조값이 된다. 예를 들어 손가락 애니메이션같은 경우 매번 무기를 쥐는 키를 주기가 번거로운데, 이렇게 Idle을 등록해 놓으면 키를 주지 않아도 손가락은 항상 무기를 쥔 상태가 된다. 처음 공부할 땐 그렇게 거지같았던 NLA Editor가, 나중엔 꽤 합리적인 제작 프로세스의 일원이 됐다. 역시 사용자가 못쓸 뿐, 쓸모없는 기능은 없나보다.

애니메이션 작업은 무엇보다 선행되어야 하는 것이 툴과의 연계다. 일단 유니티에 올려야 뭐든 확인을 할 수 있기 때문이다.

그나저나 유튜브에 광고를 붙였더니 쓸데없이 앞뒤로 덕지덕지 많이 붙는다….수익설정 안하면 아예 안붙으면 좋겠는데, 유튜브가 마구잡이로 트니까 그럴바엔 나도 치킨값이나 벌어보자! 싶어서 붙였봤더랬다. 그런데 그랬더니 영상끝나고도 광고가 나온다. 에이…

9.15

달리기 모션 중… 너무 깨지는데… 이게 닐리는 왜 티가 안났지? 싶었더니 코트가 가리고 있었다. 손을 좀 봐야 할 것 같다.

9.16

기본모션을 제작 중.닐리보다 좀 더 살집이 있어서 스커트가 많이 깨진다.

9.17

다이나믹 본 적용. 으아… 잠이 쏟아진다. 오늘은 여기까지

9.18

추석 연휴로 인한 하루 휴가

9.19

치마본이 … 도저히 못쓸 수준이다. 다소 번거롭지만, 달래처럼 수동체계로 변경하도록 하자.

여엉차

9.20

원거리 킥 공격. 이게 꽤 어렵다… 내일 다시 도전해보자.

원거리 킥 다듬고,

근접 킥도 만들고

근접 펀치도 만들고

예쁜 방어 자세가 잘 안나온다… 일단 하원 후에 다시 검토해보자.

9.22

21일은 작업은 했으나 삽질 비중이 높아서 기록할 게 없었다. 작업이 손에 잘 붙는 날이 있고, 그렇지 않은 날이 있는데 이 차이가 어디서 오는걸까.

언젠가 한 번은 등작해야 했던 드롭킥.

점프 공격은 제자리 점프공격과 이동 점프 공격으로 나뉜다. 공중 킥공격이 달래나 앨리스처럼 날아차기일 경우 방향성이 강한 애니메이션이기 때문에 제자리 점프 시 공격이 어색하므로 둘을 따로 제작한다. 허나 역시 매우 귀찮기 때문에 어지간하면 돌려쓰기를 하는 편이다.

차츰 많아지는 모션들. 많아보이지만 앞서 말했듯 JumpKick과 MovingJumpKick은 스테이트만 다를 뿐 모션이 같다. 확장을 위해 슬롯을 따로 관리하는 것이다.(하지만 끝까지 안 쓸 것 같다.)

기본 공격 제작 끄읏-! 공격모션을 만들며 느낀 점인데, 대낫은 생각보다 더 살벌하게 느껴진다. 실제로는 공격력이 형편없다고 하는데도, 이미지가 워낙 강해 왜 사신이 대낫을 들고 다니는 지 이해하게 됐다. 대낫은 영어로 Scythe, ‘사이드’라고 읽는데, 난 이 캐릭터를 제작하기 전까진 대낫을 시클(Sickle)로 잘못 알고 있었다. 시클은 ‘낫 놓고 기역자도 모른다.’할 때 그 작은 낫을 뜻한다고 한다.

이제 데미지로 넘어가자.

각 캐릭터의 Idle포즈 제작

9.12

Idle포즈는 모든 모션을 통틀어 가장 중요하기도 하지만, 모션을 잡으며 튀는 웨이팅을 체크해주는 작업이 병행된다. 모든 제약조건을 시험해보는 단계이다. 과격한 동작을 취하기도 전이건만, 오류가 엄청나게 튀어나온다. 덕분에 프리오리의 이 간단한 자세를 잡는데도 2시간이 넘게 걸렸다.

프리오리

포즈를 잡으며 삐져나오는 점들

그레텔

도레미

기본 포즈는 다 잡았는데, 시간을 두고 다시 보면 어색한 점이 눈에 띌 때가 있다. Idle모션은 이후의 애니메이션에 전체적으로 영향을 끼치기 때문에 이 과정은 반드시 필요하다. 이후에 보아도 여전히 괜찮으면 애니메이션 작업에 들어가자.

벨 수정

또 수정

그레텔도 수정

도레미…는 아예 컨셉을 바꿨는데 프리오리와 좀 겹치는 느낌이라 폐기

그레텔의 리깅

9.10

이번에 녹화하며 윈도우 기본제공되는 녹화프로그램은 2시간이 한계라는 것을 처음 알았다.

얘 리깅은 별 게 없을 것 같은데, 의외로 꼼꼼히 해야 되는 부분이 꽤 있다. 리깅은 복잡한 화면을 지속적으로 보아야 하기 때문에 피로감이 큰 작업이다. 일단 쉬었다가 저녁에 다시 확인해보자.

9.11

가슴부분에 달린 지퍼가 가슴이 따로 움직일 때, 간격이 벌어지는 문제가 있었다. 게다가 그 경우, 지퍼는 어느 본에 위치하여야 하는가?에 대한 문제도 있어 가슴본을 추적하는 새로운 지퍼본을 만들었다. 지퍼본은 양쪽가슴의 ChildOf로 구성했는데, 이 때 주의할 점은 영향력을 양쪽에 반반주면 안된다는 사실이다.

Constraint(제약조건)은 위에서부터 차례대로 적용되므로 1번이 0.5가 적용된 상태에서 2번이 적용된다. 즉, 절반의 트랜스폼을 추종한 후, 다시 절반을 주면 0.66배가 적용되는 것이다. 이렇게 되면 좀 더 한 쪽으로 치우친 결과를 보여주기 때문에, 2번은 좀 더 낮은 수치를 주어야 제대로 된 결과를 볼 수 있다.

…는 허리를 비트니 제자리를 이탈해서 실패

그런데 곰곰히 생각해보니, 가슴은 애니메이션할 일이 없다. 다이나믹 본이 대신 해주기 때문에…

…그럼 이게 맞나? 테스트해보자.

맞긴한데… 이렇게 되면 본이 3개나 필요없다. 하지만 그냥 3개를 유지하도록 하자. 나중에 쓸 일이 올 것 같기도 해…

여차저차 그레텔도 완료. 도레미로 넘어가자.

벨 리깅

9.7

아우.ㅇ.으으어… 곱슬머리 다시는 하고 싶지 않아!

어깨의 숄은 모델링을 할 때부터 고민이긴 했다. 본 설계를 어떻게 해야 하지? 팔에 의해 형태가 변해야 하지만 팔과 완전히 동일하게 움직일 수는 없다. 약간이긴 하지만 움직임에 이격이 필요하다. 그리고 그것과 별개로 스샷처럼 옷감의 말단을 본의 말단에 맞춰놓으면 움직임이 부드럽지 않다. 전에도 2번째 캐릭터인 닐리가 그렇게 고생을 시키더니, 벨도 그런 조짐이 보인다. 일단 자고 일어나서 … 생각해 보자.

9.8

완전히 예쁘지는 않지만, 그럭저럭 잘 움직인다. 팔에 가장 가까운 본이 팔의 움직임을 카피하고 나머지 본들은 비율을 줄여가며 쫓아간다. 여기에 다이나믹 본의 움직임을 더하면 팔랑팔랑 잘 움직일 것으로 기대한다.

9.9

치마의 프릴은 다이나믹 본의 도움을 받을 예정이었는데, 차질이 생겼다. 다이나믹본은 마디가 없는 단일본에 대해선 처리를 하지 않는다. 이를 해결하기 위해선 offset을 두어 가상의 본을 만들어야 하는데, 이것이 본의 방향이 아니라 월드 기준으로 모두 같은 방향을 바라본다.

때문에 이를 해결하기 위해선 프릴마다 2개 이상의 본이 필요하다. 안그래도 긴머리와 숄 때문에 본이 많은데 이를 감안할 것인가? 아니면 절약할 것인가? 를 선택해야 한다.

하지만 최적화는 유저에게 맡기고, 나는 간다. 프릴에 본 2개를 설치하기로 하자. 다만 모든 프릴에 설치하려던 계획을 수정해서, 2개당 1개만 설치하자. 이 정도로도 충분한 효과를 볼 수 있을 것이다.

하지만 정작 본을 심다보니 드는 의문… 프릴은 치마겉에 장식으로 다는 것이다. 즉 치마본의 자식본으로 들어간다. 그렇다면 … 본 하나로도 괜찮지 않을까? 확인이 필요하다.

확인결과, 안된다. 다이나믹본은 링크가 연결되는 1개의 본만 유효하다. 이를 움직이기 위해선 별도의 컴포넌트를 설치해야 한다.

2개의 컴포넌트를 사용해야 제대로 표현된다. 음. 그렇다면 역시 2개의 본을 사용하자.

그런데 그래도 길리슈트를 입은 닐리보다는 적다.

…그런데 프릴을 따로 작업을 해보니…그냥 기본 본만 심는 게 가장 좋은 결과를 보여줬다.

거의 끝나간다. 하지만 타임오버

다 했는데 뭔가 마음에 안든다.. 치마가 별로 안예뻐서 그런 것 같기도 하고…저녁에 한 번 더 보는 편이 좋겠다.

9.10

치마를 리폼해보자.

프릴을 좀 뜨게 하면 예쁠 것 같았는데, 너무 아이돌 치마같아 요란해 보인다.

이번엔 프릴을 좀 더 촘촘히

더 촘촘히…했더니 김말이같아서 이건 실패.

역시 치마가 문제였던 것 같다. 디테일을 잡아주어야 할곳에서 디테일을 잡아주질 못하니 생겼던 문제로 예상된다.

이제 완료! 그레텔로 넘어가자.

프리오리 리깅

9.5

프리오리의 리깅 작업 중 머리카락 – 손

손의 웨이트 데이터 이전이 잘 안되는 문제가 있었다. 프리오리는 한 쪽에 장갑을 끼고 있기 때문에 맨손과 버텍스가 다소 차이가 난다. 하지만 그렇다고 해도 오차범위를 벗어나는 것이 이상해서 와이어를 켜보니 폴리곤이 비정상적으로 많은 문제가 있었다. 섭디가 2번 된 것이다. 이것 때문에 원본 모델에서 다시 이식을 하는 바람에 삽질의 품격을 한단계 더 높이는 계기가 됐다.

프리오리는 미니 스커트를 입고 있으므로 치마본을 닐리에게서 이식해야 할텐데, 이게 잘 될런지 모르겠다. 일단 상체를 모두 작업하고 생각해 보자.

9.6

닐리의 치마본을 이식해와야 한다. 보기에도 복잡하지만 이걸 만드느라 한달 넘게 걸렸었다. 이식도 간편하진 않을 것이다… 두근거리는 마음을 안고 옮겨보자.

아마추어를 병합할 땐 유효하지 않은 드라이버 정보를 삭제해주어야 한다. 이는 병합하기 전에 하는 것이 좋은데, 같은 소스에서 분리된 아마추어일 경우, 드라이버가 2중으로 설정되기 때문이다. 표면적으로는 별 다를 것이 없지만, 이 정보가 누적되면 성능이 눈에 띄게 저하된다. 이는 전 직장에서 일할 때 자동 병합 시스템을 만들며 알아낸 것이다.

그래서 결론. 합치기 전에 요걸 눌러서 지워주면 된다.

오! 그냥 착 붙는다! 이렇게 한 번에 될 줄은 몰랐는데! 그럼 웨이팅만 하면 되겠다.

데이터도 제법 깔끔하게 넘어왔다. 과거의 고생이 헛되지 않았음을 증명해준다. 흑흑.

이제 웨이팅은 끝났지만, 옷에 두께를 주어야 한다. 웨이팅 전에 두께를 만들어 놓으면 값이 복사가 되지 않기 때문에 여러모로 번거롭고, Data transfer를 사용하면 근사치가 들어가긴 하지만 완전히 같지는 않다.

옷의 아웃라인까지 완료. 이제야 윤곽선이 정돈되어 깔끔한 느낌이다. 프리오리의 리깅 완료. 벨로 넘어가자.

도레미 모델링

9.3

2차 마일스톤의 마지막 캐릭터다. 얘는 뭐 딱히 디테일을 설정할 게 없다. 바니걸의 복장은 정해져 있는 것이고, 망치는 보이는 그대로의 디자인이라 내부설정할 것이 없고… 그냥 잘 만들어 보자!

9.4

토끼 귀 때문에 키 185cm!

엉덩이처럼 폴리곤이 겹치는 경우엔 절반을 선택하는 도구인 Side of Active가 잘 작동하지 않는다. 이럴 경우엔 그냥 Seam설정이 편하다. 편의 기능에 생각이 매몰되어 기본기를 잊으면 안된다는 교훈.

허리에 주름을 넣자.

심 구조는 이렇다.

9.5

오늘의 깨달음. Checker Deselect는 가장 하단의 선을 잡고 실행하면 편하다.

머리카락을 짤라주고…

그… 모델링할 게 거의 없는데… 일단 색칠해 보자.

색칠할 것도 그닥 없다… 뭔가 심심한데..

봉재선 위치를 바꿔주고 마무리.

그레텔 모델링

8.30

그레텔의 처음 설정은 간호사였다. 그렇다면 주사기를 무기로 사용해야 하는데, 이것이 ‘액션’을 하기엔 너무 작다는 생각이 들었다. 그렇다고 과장된 커다란 주사기를 사용하고 싶지도 않았고,결국 암살자로 방향을 선회했다. 그렇게 간호사 모자를 쓴 이상한 암살자가 디자인됐다.

현재 제작된 알파 버전의 비오는 폐허 배경이 그레텔의 장소이다.

8.31

땋은 머리가 필요하다. 달래의 머리는 로폴기준으로 만들었고, 얘는 덩어리가 커서 실제로 땋은 모델링이 필요한데, 예전에 한 번 커브로 만들어던 적이 있다.

찾았다. 이런 건 만들어두면 두고두고 도움이 된다.

9.1

예전에 만들어 놓은 땋은 머리 레퍼런스가 있다고 해도 쉽지 않았던 머리카락 모델링.

만들다보니 모자가 영 거슬려서 삭제

큰일났다. 안경이 귓구멍에 꽂혀..

결국 만나고야 만 Transparent셰이더. 안하고 싶었지만 어쩔 수 없다.

옷을 만들어보자.

멋있다. 마치 Concord의 캐릭터 같아.

팔 주름 러프 스케치

모양대로 짜르고, 크리즈를 주고

…는 주름이 너무 많고 펑퍼짐하다… 좀 줄이자.

9.2

꽤 어려운 과제였다.

금도끼, 은도끼도 만들어주자.

원본 모델링 완료. 굳히기에 들어가자.

머리카락을 색칠하고,

9.3

조금씩 전진

이 문신은 게임상에서 거의 보일 일은 없을 것 같지만, 설정했으므로 그려두자.

본체는 완성인데, 안경 셰이더를 따로 만들어야 한다.

오랫만에 만드니 기억이 하나도 안나서 더듬더듬…. 영상을 찍고 나니 역시 대각선이 좋아보여 다시 대각선으로 바꾸었다.

이는 나중에 유니티에서 컨버팅해야 할 것이다.

벨 모델링

8.26

벨은 왕위를 장녀가 아닌 자신이 물려받아야 한다는 왕가의 차녀이다. 매사에 기품있고 예의바르게 행동하지만 조금만 수틀려도 쉽게 신경질을 내며 쌍욕을 한다. 즉, 매우 가식적이며 신경질적인 성격. 왕위 계승이 얼마남지 않자 초조해진 이 차녀는 언니에게 독살을 시도하지만 곧 실패하고 도망친다. 하지만 꿈을 굽히지 않고 모든 걸 뒤엎을 수 있는 한 방을 원하기에 배틀퀸이 되려 한다…는 러프한 설정

벨은 모델링 난이도가 꽤 높을 것으로 예상된다. 곱슬머리와 치마의 레이스의 폴리곤 접힘 처리가 관건이다. 차근차근 진행해보자.

8.27

오랫만에 스크립트를 추가했다. 이 코드는 오리진을 x:0으로 옮겨준다. 미러를 정확히 하고 싶을 때 사용하는데, 코드대로라면 y,z는 유지되어야 할 것 같지만, 어쩐지 원점으로 이동한다. 이렇게 되면 사실 3D커서를 원점에 두고 미러하는 것과 같은데…그건 파이메뉴를 2번이나 열어야 하니 그냥 이걸 쓰자. 역시나 chatGPT가 짜주었다.

        obj = bpy.context.active_object
        bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='BOUNDS')
        origin_location = obj.matrix_world.translation
        offset = mathutils.Vector((origin_location.x, 0, 0))
        obj.location -= offset

        obj.data.transform(mathutils.Matrix.Translation(offset))
        bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)   

모델은 아직 러프한 상태

머리카락 심는 중… 정공법으로 돌파하겠다! 컴퓨터가… 이걸 버틸까..?

손님, 머리숱이 많으시네요.

머리카락 12,000개. 예상외로 얼마 안된다

8.28

뭔가 어렵네… 오늘은 모델링이 잘 손에 안붙는 느낌이다.

오리진 x:0코드가 작동이 잘 되지 않아서 손으로 다시 짰다. 매트릭스를 건드는 건 늘 골치가 아프니, 원시적인 방법으로 옮겨주자.

        obj = bpy.context.active_object
        
        set_mode('OBJECT')
        bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='BOUNDS')
        bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
        
        set_mode('EDIT')
        mesh = bmesh.from_edit_mesh(obj.data)
        
        offset = obj.location.x
        
        for vertex in mesh.verts:
            vertex.co.x += offset
            
        bmesh.update_edit_mesh(obj.data)
        
        set_mode('OBJECT')        
        obj.location.x = 0

set_mode는 모드 변환을 쉽게 사용하려고 만든 커스텀 함수이다.

def set_mode(m):  
    if bpy.context.mode != m:
        bpy.ops.object.mode_set(mode=m, toggle=False)

잘 작동한다. 역시 아날로그가 최고다.

이제 프릴을 만들 차례. 몇 가지 테스트를 해야 한다.

프릴스커트를 만드는 법에 대한 기록

8.29

팬티는 사실 이렇게까지 안해도 되는데, 파고 있다.

레이피어까지 완료. 이제 텍스처링을 해보자.

텍스처링 과정. 삽질 한가득

8.30

끝난 것처럼 보이지만, 손볼 곳이 남아있다.

  • 윗머리 폴리곤을 너무 아껴서 각지게 보이는 문제
  • 가슴골 윗부분의 아웃라인은 좀 더 얇게 처리

배면법을 일률적으로 적용하면 선맛이 살지 않는다. 3D에서 선맛을 찾는 것은 좀 이상하지만, 어쨌거나 실제 그림을 그린다면, 아무도 저렇게 가슴 위쪽까지 투박하게 선을 긋지는 않을 것이다.

이를 위해서 아웃라인 제네레이팅을 할 때 웨이트값을 참고해서 Fatten을 적용하는 기능을 만들었었다. 사실 이 기능은 이전 프로젝트에도 사용되던 기법인데, 뭐 이렇게까지 해야될까…싶어서 만들어 놓고도 작업자들에게 권장하지 않았다. 귀찮기 때문. 하지만 이것은 분명한 쓸모가 있다.

이제 정수리를 정리해 보자.

아휴.. 참 대충도 만들었다. WIP를 따로 저장해두는 이유가 바로 이런 것 때문이다. 한 번에 잘 나오는 결과물은 없으므로 계속 다듬어 주어야 한다.

벨은 타캐릭터보다 머리가 조금 작다. 이게 익스포트가 잘 될까… 잘 되길 바랍니다.

이로서 벨 모델링 완료. 그레텔로 넘어가자.