TWA Houdini1/Starter & Particles

TWA 후디니 1 Starter_10 : 고난주간 마지막 & Midterm exam

yiss09 2023. 1. 29. 06:12

https://www.twahoudini.com/course/starterparticles1

 

HOUDINI1_ STARTER & PARTICLES

1️⃣ 후디니 작업을 위한 기본 프로세스 이론을 공부합니다. SOLVER 작동 개념을 훈련하고 PARTICLE 시스템을 구현합니다.

www.twahoudini.com

드디어 고난주간 마지막 강의이다. 마지막인 만큼 과제가 상당히 어려웠다. 힘내서 끝을 내보자!

 


고난주간 마지막 풀이

1. source 만들어주고 솔버에 불러서 포인트 누적하기

2. 초기속도

3. one direction Gravity & point Gravity

4. 포인트를 선으로 묘사할 수 있는가 없는가

5. 포인트의 소멸

6. 바람

7. VEL UPDATE

8. Source에 흑백으로 패턴 주기

9. 첫 Birth 위치에 대해

10. 정리 : 하나의 컨트롤러로

 


1. source 만들어주고 솔버에 불러서 포인트 누적하기

 

solver를 활용해 point를 쌓는 방법이다.

Transform node를 이용해 object에 매 프레임마다 Rotation에 변화가 가게 두었다. 그 다음 add node로 points만 남겨주었다.

1. solver의 4번째 인풋을 활용하여 정보를 불러들였다. 첫번째 인풋을 사용하지 않고 다른 인풋만 사용한 새로운 배운 방법이다.

2. solver 안에서 merge를 활용해 Prev_Frame과 input4에서 불러온 source의 내용을 합쳐 정보가 계속 누적되게 해주었다.

 

앞서 만든 프로세스를 수정해 Scatter node를 추가하여 object의 표면에 점이 무작위로 생성되게 한다.

1. Force Total Count에 animation을 주었다. 시작프레임부터 100개의 point가 매 프레임마다 생성되게 두다가 24 Frame에 도달하면 0개의 포인트를 생성하도록 설정해두었다. point의 갯수는 24 Frame부터는 늘어나지 않고 고정되었다.

2. Global Seed에 $F를 입력해 매 프레임마다 생성되는 point의 위치가 달라지게 해주었다. global seed가 고정되어 있을 때와는 달리 새로 생성되는 point가 잘 확인되었다.

 

 


2. 초기속도

 

1. Sphere object에 normal(points)을 달아주어 각각의 포인트가 Normal을 가지게 하였다.

2. v@vel 즉, points 속도의 방향을 이전 노드에서 얻은 @N과 같다고 하였다.

3. solver 안에서 모든 point가 다음 프레임으로 넘어갈 때마다 v@vel이 더해진 값을 가지도록 하였다. 결과적으로 points들이 @N의 방향으로 계속하여 나아가게 되었다.

이렇게 초기 속도에 대한 셋팅이 일단 완료되었다.

 

 


3. one direction Gravity & point Gravity

 

먼저 one direction gravity를 만들어보자.

1. 이번엔 특이하게도 solver에 들어가기 전 두 개의 Attribute Wrangle을 merge하여 한 input에 넣었다.

2. v@gravity는 앞으로 points에 가해질 중력에 관한 정보이다.

 

3. 앞서 입력해두었던 gravity의 정보를 불러들이기위해 point function을 사용하였다. 여러개의 Attribute wrangle을 merge 했을 때 point function을 사용함으로써 차이점이 생긴다면, 그건 불러들일 Attribute를 적은 이후인 숫자를 입력하는 부분이다. 지금은 merge node에서 gravity의 정보가 제일 위의 순서에 위치하기 때문에 0을 입력해주었다.

4. 중력은 고난주간 5일차에서 배운 것과 마찬가지로 작동한다. 이미 진행되고 방향에 중력에 대한 값을 더해주면 새로운 방향이 생성되는 방식이다.

 

point gravity를 만들어보자.

5. 직접적인 좌표가 될 point에 원 움직임을 넣어준다. point의 위치 정보는 이후 solver에서 불러들일 예정이니 v@target으로 저장시킨다.

6. f@pointpower를 이후 point gravity의 움직임에 제한을 두기 위해 생성해준다.

 

7. input3에서 불러올 point gravity에 대한 정보는 merge에서 2번째 정보로 위치하고 있기 때문에 point function의 마지막 숫자는 1로 자리하게 된다.

8. object의 points 정보로부터 target으로 빨려들어가는 듯한 중력을 만들어주기 위해 (target - @P)를 입력해준다. 그 다음 통제하기 쉽도록 normalize하여 방향벡터들의 크기를 일정하게 만들어준다. 마지막으로 pointpower를 뒤에 곱해주어 point gravity를 통제해준다.

+ gravity와 point gravity에 관한 움직임들은 solver 내에서 각각의 Attribute를 Off 해주면 움직임을 없앨 수 있다.

 

gravity와 point gravity를 둘 다 작동시킨 뒤 point gravity에 animation을 주었다.

 

 


4. 포인트를 선으로 묘사할 수 있는가 없는가

 

포인트를 선으로 만들어주기 위해 Trail node와 Add node를 활용하여 선을 만들어주었다. 이전부터 사용하던 방식 그대로 @ptnum에 따른 i@id를 생성해 id에 따라 point들이 선으로 연결되게 해주었다.

하지만 예상과는 다르게 point들이 일직선으로 연결된 것이 아닌 기하학적인 모양으로 연결된 것을 볼 수 있다.

왜 이런 현상이 일어났는가? 그 원인은 바로 scatter node에서 찾을 수 있었다. 각각의 point들이 생성될 때 point number가 가 겹치게 되는데, random 한 seed에 따라 무작위 위치에서 생성되다 보니 사진과 같이 중구난방인 상태로 점들이 엮이게 된 것이다.

 

이를 해결하기 위해 새로운 방법을 배우게 되었다. 바로 string 타입으로 id를 정의해주는 것이다.

1. 각각의 point들에 대해 독자적인 number를 생성해주기 위해서 string 타입을 이용하였다. frame과 ptnum의 number들을 string 타입으로 만들어 숫자들을 연결시켜줄 예정이다.

2. 여기서 새로운 function이 등장했다. 바로 itoa 이다. itoa를 이용하면 integer 타입의 정보를 string 타입으로 전환시킬 수 있다. 이를 이용해 frame 정보와 ptnum의 정보를 string 타입으로 변경해주었다.

3. 하지만 이 방법도 완벽하지는 않다. 예를 들면 2 프레임의 32번 point는 232로 입력된다. 그리고 23번 프레임의 2번 point도 232로 입력된다. 이러한 중복을 방지하기 위해 frame과 ptnum 사이에 "_"를 더해준다. 그리하면 2_23, 23_2와 같은 방법으로 정보가 입력되니 오류가 발생하지 않을 것이다.

사진을 보면 point들이 원하는 방식으로 잘 연결된 것을 볼 수 있다.

 

 


5. 포인트의 소멸

 

points가 사라지는 효과를 만들기 위해 life를 이용해준다.

1. i@life는 0으로 시작해준다.

2. 이전에 만들어 두었던 @idnum을 활용해 random 값을 생성한다.

random = fit(random,0,1,-amount,amount)

0~1 범위인 random 값을 fit function을 활용해 life가 적용될 범위를 조절해준다.

3. 앞서 만들어진 limit 값에 random 값을 더해주면, 모든 points가 limit 값에 알맞게 떨어지는 것이 아닌 random한 범위로 제각각 사라지는 위치가 달라지게 된다.

마지막으로 float 값인 limit을 floor function을 활용해 integer 값으로 만들어준다.

4. Geometry Spreadsheet에서 확인할 수 있듯이 lifelimit에 도달한 point들의 life가 0인 것을 볼 수 있다.

 

solver 내에서의 life에 관한 Attribute는 StartFrame 이후부터 적용이 시작되어도 무관하기 때문에 Prev_Frame 바로 아래에 위치시킨다.

5. @life ++에 따라 매 Frame 마다 @life가 1씩 증가하게 된다.

6. 만약 life가 lifelimit보다 크다면 point들이 제거되도록 if 문을 설정해두었다. else 문이나 else if가 없는 것은 if문 이외의 문장들은 그대로 두겠다는 뜻이다.

이렇게 lifelimit에 도달한 points는 제거가 되며, life 값이 0가 된다.

 

 


6. 바람

 

이제 points에 바람이 부는 것과 같은 효과를 주기 위해 v@wind를 만들어 solver의 2번째 input에 연결해준다.

 

solver 안에서의 작업이다.

1. 작업을 위해 필요한 정보들을 가져와 정의해준다.

2. 실제 바람이 부는듯한 느낌을 최대한 가깝게 주기 위해 noise가 들어갈 wind에 noise효과에도 random한 값을 주려한다. solver 밖에서 만들두었던(아래에서 설명할 예정) random값인 @windamount를 그대로 활용해 fit function에 넣어주었다. 이 범위를 조절함으로써 특정 범위에서 noise 효과의 세기를 조절할 수 있게 되었다.

3. wind가 실제 바람과 비슷한 느낌을 내기 위해 여러 noise 값들을 추가해주었다. windamount로 wind에 영향을 받는 point들을 random하게 골라주었고, windnoise와 noiseamount로 wind에 noise를 주어 일렁이는 효과를 만들어주었다.

4. 완성된 @wind는 @P에 더해져 points의 움직임에 영향을 끼치게 된다.

 

solver 밖에서 wind에 관해 만들어두어야하는 initial value 값이다.

5. 앞서 언급되었던 windamount이다. 이전에 만들어두었던 @idnum을 활용해 random한 값을 만들어주었다.

6. windamount에 chramp를 함으로써 그래프를 조절해 wind에 영향을 받는 point들의 범위를 조절해 줄 수 있다.

 

windnoise에 관한 정보를 깜빡할 뻔 했다. attribute vop을 활용해 noise를 생성해준다. attribute vop은 solver 안에서 life attribute 아래에 생성해준다.

7. Time에 관한 정보를 활용해 animation을 줄 예정이기 때문에 4D input, 3D noise를 선택하여야 한다.

8. 4D Frequency를 조절해 noise의 폭을 줄일 수 있다. 숫자가 올라갈수록 noise가 더욱 더 꾸불꾸불해진다는 것이다.

 

 


7. VEL UPDATE

 

points의 움직임이 조금 튀는 경향이 있어 통제를 가하기 위해 vel에 제한을 걸겠다.

1. length function을 활용해 @vel의 길이를 float값으로 변환시켜준다.

2. 만약 len이 vellimit보다 크다면 @vel은 normalize(@vel) * vellimit이 된다. 나는 풀이에 들어가기전 혼자 시도해보는 과정에서 이러한 부분을 표현해내기 위해 clamp function을 이용하고자 하였다. normalize를 이용한 방식이 clamp를 이용한 방법보다 훨씬 깔끔한 방식이라고 느껴진다.

 

3. v@vel에 float 값을 곱해주면 power를 조절해주는 것과 같은 효과를 가진다. 1보다 작은 수인 0.9를 곱해줌으로써 point gravity로 인한 과한 움직임을 제한시켜준다.

 

 


8. Source에 흑백으로 패턴 주기

 

Attribute Noise를 활용해 흑백의 Cd를 얻는다.

그 다음 Group expression을 활용하면 흑백의 구간 중 원하는 범위를 group화 시킬 수 있다. 여기서 group type을 points로 두지 않으면 원하는 결과를 내지 못하기 때문에 반드시 확인해야한다.

 

1. 고난주간 4일차에서 배웠던 attribute transfer를 활용해 움직이는 sphere의 흔적을 남겨 pattern을 만들어준다.

2. groupexpression을 활용해 grid에서 붉은 부분만 떼어낸다.

 

3. solver 끼리 중복되면 오류가 발생할 수 있기 때문에 file cache를 활용해 pattern을 저장해준 뒤 object로 활용해준다.

 

 


9. 첫 Birth 위치에 대해

 

지금까지의 solver 구조를 그대로 사용하게 되면 그림과 같이 points에 층이 생기는 것을 볼 수 있다. 이는 첫 번째 Frame에서 여태 우리가 입력해주었던 정보들이 작동하지 않기 때문에 발생하는 문제이다. 이러한 계단의 모습은 완벽하지 못하다.

이를 수정하기 위해 solver의 구조를 바꿔 보겠다.

 

첫 Frame에서도 여러 정보들이 그대로 작동하게 만들기 위해 중요 내용들을 object의 정보가 들어오는 input 아래에 복사 붙여넣기 해주었다.

이후 point jitter를 활용해 조금 더 point들이 흩뿌려지게 만들어 층이 진 구간을 제거해주었다.

 

마지막으로 새롭게 배우게 된 @Alpha이다. 투명도에 관여한다고 하니 Cd 값과 연결지어 식을 완성지으면 될 것 같다.

 

 

 


10. 정리 : 하나의 컨트롤러로

 

이 부분은 TWA 최초입문강의에서 많이 다루어보았던 부분이다.

여유가 좀 있다면 확실하게 마무리 하고 싶지만 너무 늦은 밤인 관계로 이 부분은 생략하고 넘어가려 한다.

 

 


고난주간 2주도 안되는 시간이었지만 굉장히 고되고 길게 느껴졌다. 과제를 하면서 좌절도 많이 하고 포기 하는 부분도 있었지만 과제를 완성하기 위해 고민하고 시도해내는 과정에서 후디니에 더 매력을 느끼게 되는 시간이 된 것 같다.

이번 고난주간의 공부 방법은 앞으로의 후디니 인생에 있어 하나의 공부 방식으로 채택하려 한다. 여유가 있을 때는 한주에 한번씩 여유가 없을 때는 한달 내내 고민하여 문제를 풀어보는 방식으로 앞으로 스스로의 고난주간을 가질 생각이다.

좋은 강의를 제공해주신 TWA 강사님과 조교님께 감사드리며, 고난주간을 마쳐보려 한다.