TWA Houdini1/Volumes

TWA 후디니 1 Volume_10 : Point Deform, Brute 캐릭터 표면 연기 만들기

yiss09 2023. 3. 5. 15:56

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

 

HOUDINI1_ VOLUMES

2️⃣ 볼륨의 기초이론과 응용 그리고 SIMULATION까지 경험해보세요.

www.twahoudini.com

 

Volume10에서는 지난 시간 과제로 다루었던 문제를 다룬다.

움직이는 Character 표면에서 Smoke가 나오도록 세팅해줄 예정이다.

 

1. Character 준비 & 정리

2. Smoke Solver Setting

 


1. Character 준비 & 정리

 

Mixamo 하이퍼링크를 걸어두었다.

먼저 Mixamo에서 Brute Character를 다운받아주자.

Character의 몸에서 무언가 뿜어져 나오는 듯한 효과를 줄 예정이다. Animation은 Standing Taunt Battlecry로 정해준다.

Animation이 조금 빠른 것 같이 느껴진다. Overdrive 값을 40으로 낮춰준다.

Download 해준다. 이때 파일이 저장된 경로가 영어로만 구성되게 해주는 것을 추천한다.

 

또한 방금의 Animation을 준 Character의 정지상태가 필요하다. T-pose Animation을 다운받아준다.

 

Agent node를 이용하여 두 가지 Animation의 Brute를 생성해주었다.

해당 Object의 point 정보를 이용할 예정이기에 Unpack 해준다.

 

T-pose의 Brute를 하나 더 생성해준다.

Unpack된 Brute에서 Blast로 하나의 점을 선택준다.

Copy to Points를 통해 Primitives 정보로 만들어준 뒤 색을 입혀 잘 보이게 해주었다.

 

이제 해당 Sphere가 Animation에 따라 손목 위치에 계속 고정되기를 원한다.

새롭게 Point Deform node를 사용해주겠다.

 

Point Deform은 Polygon의 규칙이 같은 두 정보를 기준으로 Point를 이동시켜주는 역할을 한다.

Input 1으로 들어온 정보는 무엇을 바꾸고 싶은지이다.

Input 2로 들어온 정보는 기준이 된다. Input 2로 들어온 정보를 기준으로 Input 1 정보의 상대적인 위치가 정해지게 된다.

Input 3은 어디로 어떻게 변화를 줄려하는를 정해줄 수 있다. 

즉, Input 1으로 들어온 위치 정보를 Input 2와 대조하여 기준을 정하고, Input 2와 Input 3의 내용을 비교하면서 위치 변화를 만드는 것이 Point Deform의 역할이다.

이때 Input 2로 들어가는 정보와 Input 3의 정보는 primitive 규칙이 같아야한다.

 

Point Deform을 사용하는 이유는 이러하다.

1. 정지상태에 만든 효과를 움직이는 상태에 덮어씌우고 싶기 때문이다.

2. Animation의 움직임을 쫓아가되 point의 위치규칙이 깨지지 않길 바라기 때문이다.

 

Character 머리 위에 천사처럼 링을 달아줄 예정이다. Point Defor을 이용하여 머리가 움직이는 동안 Ring이 Animation에 맞춰 머리 위에 고정되도록 만들어보겠다.

Torus를 생성해 사이즈를 조절해준 뒤, Color로 색을 입혀준다.

그대로 Point Deform의 Input 1에 넣어주기만 한다면 Input 2의 T-pose를 기준으로 Ring이 위치한 부분에 따라 Animation의 움직임에서 Ring의 위치가 변하게 된다.

 

이제 Input 1으로 들어갈 정보에 Noise를 한번 줘 볼 예정이다.

바로 Noise를 주기보다는 고른 결과를 얻기 위해 Remesh를 해주려한다.

Remesh를 해주기 위해서 VDB from Polygons로 SDF Volume을 구한 뒤 Convert VDB로 다시 Polygons로 변환해주었다.

Remesh node를 달아 Remesh 해준 뒤 Target Size를 적절히 조절해주었다.

 

Remesh node 아래에 Attribute Vop(Polygons을 수정하는 일이니 Volume Vop이 아닌 Attribute Vop을 사용하는 것이 맞다)을 달아 해당 폴리곤에 Noise를 준다.

모든 Points에 대하여 Turbulent Noise를 주었다. 이때 흑백의 값만이 필요하기 때문에 1D Noise를 그대로 사용해주었다.

Fit Range를 달아 Noise 값의 양수값이 더 잘 보이게 범위를 조절해주었다.

정지 상태에서 만든 효과를 움직이는 상태에 덮어 씌워주었다.

 

Noise가 Point Deform을 거치지 않고 Animation으로 작동하였을 때의 결과와 Point Deform의 결과를 비교해보았다.

왼쪽 Point Deform의 경우엔, Noise가 Character를 따라 잘 움직이고 있다.

하지만 오른쪽 Point Deform을 사용하지 않은 경우엔, Noise가 고정되어 있는 어떠한 배경 안에서 Character가 움직이고 있다는 느낌이 강하게 들었다.

 

Noise를 제거하고 Remesh에서 Target Size를 낮춰 Point의 규칙을 관찰하였다.

Point Deform의 경우엔, Point의 규칙이 깨지지 않고 Animation의 움직임에 따라 잘 움직이고 있는 것을 볼 수 있다.

하지만 Point Deform을 사용하지 않은 경우엔, Animation이 진행됨에 따라 시시각각 Points의 규칙이 변하고 있는 것을 볼 수 있다.  Point의 갯수도 다르고 Primitive가 만들어지는 규칙도 전부 다르기 때문에 매순간 서로 다른 결과가 나오는 것이다.

 

만약 앞의 결과물들을 가지고 colvel을 구하려고 한다면, 각각의 Point의 속도 정보가 필요하다. 속도 정보를 구하기 위해 Trail node를 사용해주겠다. Scene view에서 값이 잘 보이게 하기 위해 @v의 값을 높여주겠다.

Point Deform의 경우엔, 망치가 빠르게 움직임에 따라 속도가 빠르게 존재하고, 느려짐에 따라 속도가 사라지는 것을 볼 수 있다.

하지만 Point Deform을 사용하지 않은 경우엔, 올바르지 않은 정보로 이는 큰 의미를 가지지 못한다. 이 정보를 가지고 colvel을 만든다면 굉장히 엉뚱한 정보가 나올 것이다. 

Point Deform으로 만든 mesh가 필요한 순간이 오게 될 것이다.

 

 


2. Smoke Solver Setting

 

이제 본격적으로 Source 준비를 시작해보겠다.

Brute의 표면에서 연기가 났으면 한다. 가장 먼저 필요한 정보는 Density, Temperature, Col, Colvel이 되겠다.

Density : Scatter, VDB from Particles(Fog)

Temperature : Name, Volume Vop

Col : VDB from Polygons(SDF)

Colvel : Trail(v) → Volume(Vel)

해당 작업에 앞서 고른 결과를 만들기 위해서 먼저 Brute를 Remesh 해주는 작업을 거치겠다.

그 다음 Point Deform을 활용해, Animation에 따라 움직이는 정보의 규칙적인 값을 구해주겠다.

 

Scatter를 통해 Unpack된 Brute의 표면에 점을 뿌려주었다.

벨트, 종아리, 얼굴 부분에 Point가 몰린 것을 보아, 고르지 않게 Points가 뿌려진 것을 알 수 있다.

주먹의 안쪽 부분과 같이 원치 않는 부분마저 Point가 생성되는 것을 볼 수 있다.

 

Point가 골고루 뿌려지게, 이후 만들어질 정보가 균일해지도록 만들기 위해서 Polygons → SDF → Polygons의 변화를 거쳐 Remesh를 해주겠다.

이제 SDF VDB로 변환한 뒤 다시 Polygons로 변환해 Remesh 해주는 과정을 예쁜 면 얻기라고 부르겠다. Network Box로 가둬준다.

 

Point Deform으로 연결해준 결과 생각보다 예쁜 결과가 나오지 않은 것을 볼 수 있다. 바지가 치마처럼 늘어진 부분, 종아리가 늘어난 부분이 보인다.

그 이유는 Input 2로 들어와 기준이 되는 T-pose 상태에서 다리가 너무 가깝게 붙어있기 때문이다. 면이 너무 가깝기 때문에 붙어있는 면으로 인식되어 떨어짐에 따라 늘어나는 것처럼 묘사되는 것이다.

 

이 문제를 해결하기 위해서 T-pose를 기준으로 쓰는 것이 아닌 Animation에서의 한 부분을 기준으로 사용하겠다.

Agent node의 Clip Offset을 Delete Keyframe 해준 뒤 파라미터를 옮겨가며 예쁘게 모양이 잡힌 부분을 찾아낸다. 적당히 전체적인 실루엣이 나쁘지 않다고 판단된다면, 멈추어도 좋다.

 

Point Deform에서의 Radius 값을 조절해준다. 이는 Point Cloud의 Radius라고 생각하면 된다.

값을 낮춰주었을 때 조금 더 Detail한 결과를 얻을 수 있다. Mesh가 찌그러지는 경우, Radius 값을 조절해줌으로써 얼마나 부드럽게 또는 정확하게 Deform을 해줄 것인지를 정해줄 수 있다.

 

이제 만들어둔 면의 규칙이 깨지지 않는 조건에서 density, temperature, col, colvel를 만들어보겠다.

density에서 새로운 내용을 다룰 예정이기 때문에, 먼저 col과 colvel부터 만들어보겠다.

Point Deform 아래에 SDF 정보를 생성해 col의 정보를 만들어준다.

그 다음 colvel의 정보를 만들기 위해 Trail을 달아 Animation에서의 v를 구해주겠다.

빠르게 움직이는 부분의 Trail의 길이가 길게 늘어난 것을 볼 수 있다.

 

Volume Trail로 Animation에 따라 각 위치에서의 속도를 관찰하였다.

Advect by Time을 선택해 시간에 따라 움직이는 속도를 시각화해주었다.

완성된 col과 colvel의 정보를 merge로 합쳐준 뒤, 다음 작업을 위해 옆으로 밀어두겠다.

 

이제 density 정보를 만들어주려한다. Object의 표면에만 density 정보를 가지게 할 예정이기에 VDB from Particles를 사용해준다. 

우선은 표면의 연기가 랜덤하게 나오길 원하기 때문에 Noise Pattern을 만들어준다.

새로운 Point Deform의 Input 1으로 들어갈 정보에 Attribute Vop을 달아준다.

Turbulent Noise를 달아주고, Fit Range로 범위를 잡아준다. Noise가 좀 더 작고 빈번하게 존재하기를 원하기 때문에 Frequency 값을 높여주도록 한다.

만들어진 Noise를 Cd로써 표현되게 해준다.

 

방금 만든 Noise Pattern이 위로 움직이도록 만들고 싶다. Offset 값을 조절해주어도 되지만, 다른 방법을 사용해보도록 하겠다.

만약 바로 Time을 Turbulent Noise의 Offset에 연결해준다면, 대각선으로 움직이는 Noise를 보게될 것이다. 하지만 우리는 위로 직진하는 움직임을 원하고 있다.

Float to Vector를 달아 y값을 제외한 x,z 값에 Constant로 0의 값을 넣어주겠다. y값에는 Time을 연결해주었다. 이때 위로 올라가는 속도가 너무 느린 것 같이 느껴진다면 y값에 Multiply Constant를 달아 속도를 높혀준다.

완성된 Noise를 Bind Export를 통해 density Attributes로 만들어주었다.

 

Attribute Delete로 Noise를 만들면서 Point에 들어간 Cd를 제거해주고, Scatter를 달아 주었다.

이후 해당 Noise 정보를 Fog Volume으로 만들어주기 위해서 Scatter로 Point를 흩뿌려준 것이다.

Point Deform을 연결해주었다.

 

Point Deform 아래에 VDB from Polygons를 연결해 Fog VDB로 전환시켰다. 해당 정보를 density라 하였다.

Point Radius Scale에 (Voxel Size * Minium Radius in Voxels) * 1.001을 넣어주었다.

Brute의 표면으로만 구성된 density를 완성하였다.

해당 Fog VDB에 Name을 달아 temperature 정보를 만들어주었다.

density, temperature, col, colvel을 merge하여 source로 두었다.

 

Animation은 Point Deform의 Input3으로 들어오는 Agent node에 의해서 조종되고 있다.

에너지가 올라오는 시간이 더 길었으면 한다. Agent의 ClipOffset 값을 수정해주려한다.

지금까지 만들어둔 세팅에서의 변화는 너무 무거우니, 새로운 Agent를 만들어 작업해주겠다.

Brute가 팔을 펴는 Animation의 범위를 늘려주었고, 그 뒤엔 Brute가 숨쉬는 것처럼 구간반복을 해주었다.

Brute가 정면을 보게하기 위해서 Transform을 달아 Roate.y 값도 수정해주었다.

이렇게 만들어준 Agent로 Source에서의 Agent를 교체해주겠다. 

 

이제 Brute가 두 팔을 펼치는 순간 연기가 뒤쪽으로 나오게 만들어볼 예정이다.

그리고 팔을 완전히 펼친 순간 연기가 위로 올라가다가 사라지는 것처럼 묘사할 예정이다.

Dop Network 안에서의 Smoke 기본 세팅을 해주었다.

Smoke Object로 Bound의 영역을 잡아주었고, Volume Source의 SOP Path를 지정해준 뒤에 Geometry 단계에서 만들어둔 Source를 적어주었다. Gas Resize Fluid Dynamic도 달아주었다.

 

Density에 Volume Vop으로 Parameter를 달아 이후 연기가 어느 시점에서 나올지를 조절해줄 수 있다.

 

temperature의 Volume Vop에서 Noise를 주었다.

Turbulent Noise의 값이 작기 때문에 Fit Range를 달아 값의 범위를 늘려주었다.

만약 더 큰 Noise 값을 원한다면 Add로 값을 더해줄 수 있다.

 

Dop Import Fields로 Density를 Geometry 단계에서 볼 수 있도록 만들어주었다.

그 다음 Light를 설치해 물체에 입체감을 주었다.

Volume Visualization을 통해 Smoke에 색을 입혀준다.

Density Scale을 높여 Smoke가 더 잘 보이도록 해주었다.

DIffuse Range를 조절해 색을 조명할 부분을 변경해줄 수 있다.

 

Volume Source에서 colvel의 Source Scale을 높여 Smoke가 Animation에 더 많이 끌려가게 만들어주었다.

 

이제 어떠한 바람에 의해 Smoke가 뒤로 밀려나다가 어느 순간에 다시 조금 앞으로, 그

리고 다시 약간의 바람에 의해 뒤로 밀려나도록 만들어볼 예정이다.

Geometry 단계에서새로운 VDB와 Box를 생성해 VDB Activate에 연결해주겠다.

 

아래에 Volume Vop을 달아 Noise를 주었다.

Multiply로 Amplitude 값을 조절해주었으며, 그 값이 Bind Export를 통해 wind의 정보가 되게 하였다.

오른쪽 사진은 Volume Trail로 관찰한 Noise의 흐름이다. Brute 뒤쪽 방향으로 바람이 부는 것과 같은 느낌이 난다.

 

wind의 효과를 Smoke에 적용시키기 위해서 VolumeSource를 새로 만들어 달아주었다.

 

이제 wind에서 만든 Parameter를 이용해, Smoke가 뒤로 밀려나다가 어느 순간에 다시 조금 앞으로, 그

리고 다시 약간의 바람에 의해 뒤로 밀려나도록 만들어볼 예정이다.

방법은 생각보다 어렵지 않다. 앞서 만든 vel_mult 값에 Animation을 준다.

이때 Smoke가 뒤쪽 아래로 떨어지게 만들고 싶다면, Constant를 달아 vector 값을 더해주도록 한다.

 

오른쪽은 Ground Plane이 존재한다.

효과가 잘 들어간 것을 볼 수 있다.

Smoke가 바닥으로 향하는 것을 막아주기위해서 Dop Network 안에서 Ground Plane을 달아준다.

 

Volume Visualization의 Diffuse Ramp를 수정해주었다.

Smoke가 발산될 때 노란색이 보이도록 해주었다.

 

마지막으로 연기의 Noise를 주기 위해 Gas Turbulence, Gas Shred, Gas Disturb를 연결해준 뒤 그 값들을 Tweak 해주었다.

 

Volume을 Simulation 하는데 2시간, 3시간 쓰는 것은 아까울 일이 아니다. 예쁜 결과를 얻고 싶다면 될때까지 Tweak 해주는게 맞다. 

작은 값들을 조금씩 바꿔가면서 예쁜 연기를 얻는 과정을 직접 해본다면 굉장히 힘들 것이다. 강의에서 쉽게 결과들이 예쁘게 Tweak 되는 것처럼 보인다. 하지만 그렇지 않다. 강사님께서도 수업을 준비하시면서 그럴싸한 값, 좋은 값들을 찾기 위해서 엄청나게 애를 쓰고 계신다. 절대 쉬운 과정이 아니니, 직접 값을 다루어보아야 한다. Guide 없이 직접 값들을 찾는다면, 예쁜 결과를 얻는데에 1시간~2시간이 쉽게 쓰일 것이다. Tweak을 해보다보면 왜 강의에서 어떤 순간에 어떤 값들을 조절했던 것인지 알게 되는 순간이 올 것이다.

강의에서 제공되는 예쁜 값들을 외우는 것은 의미가 없다. 만약 Object의 Scale이 변할 경우 Tweak해둔 값들을 다시 전부 변경해야할 것이기 때문이다. 직접 값들을 변경해보고 그 느낌들을 알아가는 것이 매우 중요하다.

 

이제 File Cache를 이용해 결과를 저장해주려 한다.

저장하기 전 voxel size를 낮춰 해상도를 높이고, Dop Import Fields에서 density의 정보뿐만 아니라 temperature, vel의 정보도 볼 수 있게 해주었다.

File Cache가 완료되었다면, blast를 달아 density만을 보도록 한다.

Volume Visualization을 달아서 Scene view에서 결과를 확인해본다.

 

정면에서와 측면에서의 결과이다.

 

만약 좀 더 나은 결과를 얻

고 싶다면 Tweak를 많이 시도해보도록 하자.