TWA Houdini1/Volumes

TWA 후디니 1 Volume_15 : 폭발 Divergence

yiss09 2023. 3. 17. 19:44

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

 

HOUDINI1_ VOLUMES

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

www.twahoudini.com

 

Volume15에서는 폭발을 배우기 위해 Divergence(팽창)를 다루어볼 예정이다.

 

1. Smoke, tempvel 기본 세팅

2. 폭발, Divergence

3. Attribute Wrangle로 Keyframe Animation 다루기

 

 


1. Smoke, tempvel 기본 세팅

 

일단은 Smoke 기본 셋팅과 지난 시간 배운 tempvel 세팅을 빠르게 잡아보겠다.

한번 만든 세팅을 불러와 사용할 수도 있지만, 정말 중요한 내용의 경우 복습하고자 다시 만들어보는 것이다.

먼저 Geometry 단계에서 Smoke의 Source 셋팅을 만들어주었다. vel의 값을 {0,1,0}으로 정해주었다.

Dop Network 안에서 연기가 발생하기 위한 세팅을 잡아주겠다.

그 다음 Dop Import로 Volume Visualization을 두 개 달아주겠다. 하나는 연기로써의 결과를 볼 것이고, 다른 하나는 불로써의 결과를 나타낼 것이다. 색이 다른 두 개의 Light(Distant)를 생성해 연기에 입체감을 더해주었다.

 

지금까지는 voxel size를 Control에서의 파라미터를 이용해서 조절해주었다. 오늘은 새로운 방식으로 voxel size를 조절해주겠다.

Add로 점 하나를 생성해준 뒤 Attribute Wrangle을 달아준다.

Attribute Wrangle에서 f@divsize를 생성해 chf으로 그 값을 조절할 수 있도록 해준다.

f@divsize의 값을 point function으로 VDB from Polygons의 voxel size와 Smoke Object의 divsion size에 넣어주도록 하겠다.

f@divisize에서의 float 값을 조절해줌으로써 전체의 voxel size를 통제할 수 있게 되었다.

 

만약 Smoke의 모양을 바꿔주고 싶다면 Gas Turbulence로 그냥 공간상에 Noise를 발생시켜줄 수 있다. 하지만 이는 아쉬운 결과이다.

우리는 좀 더 나은 결과를 위해 tempvel이라는 임시 Field를 만들어 지난 Frame의 결과를 기준으로 어떠한 vector 정보를 만들 것이다. 이때 tempvel 안에 들어갈 정보로 gradient가 쓰이게 된다. 그리고 tempvel을 advect의 조건 중 하나로 이용하게 될 것이다. 그리고 tempvel의 정보를 vel에 더해준 뒤, 임시로 사용되었던 tempvel Field를 제거해줄 것이다.

이렇게 만들어준 한 싸이클의 방식은 다른 정보를 이용할때도 사용되기 때문에 Null로 분류해주도록 하겠다.

 

이제 tempvel의 세팅을 해주겠다.

Gas Match Field, Gas Analysis, Gas Field Vop, Gas Advect Field, Gas Calculate, Gas Linear Combination 순으로 앞서 분류해둔 Null에 연결해주도록 한다.

Gas Field Vop 안에서 tempvel에 normalize를 해준 뒤 Multiply를 달아 Parameter로 그 값을 조절할 수 있도록 해주었다. Normalize node로부터의 정보를 position으로 이용하는 Anti-Aliased Flow Noise를 생성해 tempvel 값에 더해주었다. 만약 이 둘의 비율을 조절해주고 싶다면 각각 곱해진 Constant 값을 조절해주도록 하자. 3:7로 Noise 값에 더 큰 비중을 주었다.

 

Noise의 Frequency를 5로 높여주고 tempvelmult를 1로 준 결과이다. 연기 사이사이 Noise 패턴과 밀도가 높은 쪽으로 뽀개지는 효과를 관찰할 수 있다.

Volume Visualization의 Density Scale과 Shadow Scale을 4로 높여주어 더욱 연기같이 보이도록 해주었다.

 

 


2. 폭발, Divergence

 

이제부터 폭발에 대해 다루어보도록 하겠다.

폭발이라고 하면 펑하고 터지는 과정이 먼저 떠오르게 될 것이다. 즉, 작은 사이즈에서 큰 사이즈로 빠르게 변하는 과정이 필요하다. 이때 Divergence(팽창) Field에 대한 개념이 쓰일 것이다.

Smoke Solver의 경우 이미 계산 공식이 node안에 박혀있다. Smoke Solver는 주어진 재료들을 바탕으로 Volume 결과를 만들어줄 뿐이다.

그렇다면 지금까지 만들어준 연기에서 팽창의 효과가 없었던 이유가 무엇일까? 바로 Divergence라는 그릇에 Source가 한번도 담아진 적이 없었기 때문이다.

그렇다면 우리가 가진 density를 Divergence에 올리면 어떻게 될지 알아보겠다.

 

앞에서의 Input3의 tempvel을 잠시 끊어두고, Gas Caculate을 생성해 Smoke Solver의 Input3에 연결해주겠다.

Source Field로서 density를, Dest Field로서 divergence를 사용해주겠다. Calculation은 Copy로 두도록 하겠다.

후디니가 터질 수도 있으니 해상도를 낮춰서 결과를 보겠다.

Play를 해보면 연기가 굉장히 빠르게 커지는 모습을 볼 수 있다. 빠르게 커져 어느새 Bounding Box를 건드리고 있는 것을 볼 수 있다.

 

이제 앞에서 만들어두었던 tempvel 세팅에서 Divergence 작업을 해주도록 하겠다. divergence에 대한 결과만을 보기 위해서 잠시 tempvel은 사용하지 않도록 하겠다. tempvelmult에 0의 값을 준다.

우리는 밀도의 모양에 따라 팽창이 발생되기를 원한다. 이를 위해서 Gas Match Field를 하나 더 추가해 임시로 tempdiv Field를 생성해주도록 하겠다. Gas Match Field끼리 Merge로 묶어주겠다.

 

그 다음 tempdiv라는 그릇에 내용을 추가해줄 차례이다. Gas Field Vop을 추가해 Merge로 묶어준다.

Gas Field Vop 안에서 tempdiv 값이 density와 동일하다고 선언해주겠다.

Multiply를 달아 Parameter로 tempdiv 값을 조절할 수 있도록 해주었다.

 

다음은 Advect가 아닌 Divergence Field에 Gas Calculate으로 값을 넣어줄 차례이다.

앞서 만들어준 tempdiv를 divergence Field에 넣어주도록 하겠다. Calculation을 Copy로 두겠다.

 

마지막으로 Gas Linear Combination을 추가해 임시로 만들었던 tempdiv를 지워주도록 하겠다.

 

결과를 보기위해 tempdivmult 값에 1을 넣어준다. 너무 빠르게 커지는 관계로 다시 tempdivmult 값에 0.2을 넣어보겠다.

의도했던대로 빠르게 팽창하는 결과가 나왔지만 끝도 없이 팽창하는 것을 원한건 아니다.

tempdivmult에 Animation을 주어 처음 시작할때는 팽창을 빠르게 하고, 점점 팽창하는 속도가 들다가 팽창하지 않도록 해주겠다.

결과를 보면 초반에 팽창을 하고 그 뒤로는 그냥 올라가기만 하는 모습을 볼 수 있다.

tempvelmult 값을 추가해주어 Noise를 넣어서 같이 보겠다. 연기가 폭발하면서 올라가는 듯한 느낌이 든다.

오늘까지 이 과정을 다루어보면서 어떤 맥락으로 어떻게 Field를 다루는지 이해가 가야한다. 애매한 느낌이 든다면 다시 복습하도록 하자.

 

이제 Volume Visualization에서 색을 바꿔보겠다.

Smoke에는 density 정보를, Emission에서는 temperature 정보를 이용하겠다.

Density Scale과 Shadow Scale을 변경해준다.

폭발하는 느낌이 들도록 Emission에서의 파라미터를 변경해주겠다.

폭발 안쪽의 불과 같은 느낌을 주기 위해서 Color Ramp의 색을 붉게 변경해주었다. 

Smoke 탭에서 주변에 있는 연기의 색을 좀 더 어둡게 만들어 매연 느낌이 나도록 만들어준다.

우리가 가진 temperature의 값이 0~1 사이의 값만 있는 것이 아니기에 Emit Range 값을 변경해주도록 하겠다. Scene view에서 Smoke 색을 관찰하면서 천천히 바꿔주도록 한다.

 

이제 voxel size를 낮춰 해상도를 높이고, Dop Network의 Cache Memory를 높여 결과를 보겠다. 디테일이 괜찮게 결과가 나왔다.

하지만 아쉽게도 수정해야할 부분이 몇 군데 보인다.

Smoke가 팽창하는 순간 Bounding Box가 그 속도를 쫓아가지 못해서 연기가 네모난 느낌이 난다.

또 하나 아쉬운 건 폭발이 일어난 뒤에 아래에 Source가 남아있는 부분이다. 폭발이 일어난 뒤에 굳이 Source가 남아있을 필요가 없어 보인다. Multiply에 Animation을 주어 해결해주겠다.

그리고 폭발을 지면과 함께 있을 때 더욱 폭발처럼 보인다. 구 모양이 아닌, 지면에 의해 반달모양으로 커지는 느낌을 원한다. Ground Plane으로 해결해줄 예정이다.

 

다시 작업을 위해 voxel size을 높여주도록 한다.

먼저 우리가 tempdiv에 주었던 Animation을 density에도 제공해주겠다.

density의 Volume Vop에서 Parameter를 Multiply해준다. Parameter에 tempdiv와 동일한 Animation을 준다.

이 상태로 결과를 보면, 폭발 이후의 source 부분이 아직 남아 있는 것을 볼 수 있다. 이 부분은 temperature가 살아 있기 때문에 발생하는 문제이다.

 

temperature에도 Animation을 주려한다. 손쉽게 density에서의 Volume Vop의 위치를 바꿔 temperature도 해당 Volume Vop의 영향을 받도록 해주었다.

결과를 보면 폭발 후 아래에 더 이상 남아있는 것이 없는 것을 볼 수 있다.

 

Dop Network 안에서 Ground Plane을 달아주도록 하겠다.

결과를 보면 올바르게 팽창이 되었으나 위로 올라가지 못하고 연기가 꺼지는 모습을 볼 수 있다.

Smoke Solver에서 Cooling Rate 값에 의해 온도가 계속 줄어들고 있기 때문에 추가적인 온도를 제공해주지 못해 온도가 사라지면서 연기가 흩어지는 것이다.

Cooling Rate 값을 0으로 해준다. Blur도 필요 없으므로 Temperature Diffusion 값도 0으로 해준다.

Buoyancy에 의해 Smoke가 올라가기 때문에 초기 속도 값인 vel을 {0,0,0}으로 해준다. 속도가 떨어진만큼 Buoyancy의 값은 올려주도록 한다.

 

씹혀있는 부분이 있음

결과를 보면 초반에 연기가 씹혀 있는 부분이 보인다.

Transform으로 Sphere의 위치를 높여 지면보다 조금 더 위에서 Smoke가 발생하도록 변경해주겠다. 

 

연기의 가장자리 부분이 너무 어둡게 묘사되어 아쉽다고 느껴진다.

Volume Visualization의 Smoke 탭에서 어두워서 사라질 부분의 value 값을 높여주었다.

그리고 색이 너무 어둡기 때문에 Diffuse Ramp에서 0에 가까운 부분이 검은색보다는 회색에 가깝도록 해주었다.

결과를 보면 아래쪽의 연기들이 살아있는 것을 볼 수 있다.

 

이제 완성된 Smoke의 값들을 여러가지로 변경해보겠다.

Pre_source를 Sphere에서 Torus로 바꿔준다.

vel의 초기속도를 {3,-2,0}으로 해주겠다. 오른쪽으로 이동하면서 지면과 충돌하는 연기를 볼 수 있다.

결과를 정면, 위, 오른쪽에서 보았다. 뜨거운 연기 속에 디테일이 살아 있는 것을 확인할 수 있다.

위쪽에서 보면 아래쪽으로 준 vel 값에의해 중간이 뻥 뚫려있는 것을 볼 수 있다.

 


3. Attribute Wrangle로 Keyframe Animation 다루기

 

이제 지금까지 만들어준 Solver의 세팅들을 정돈 해주려한다.

앞에서 사용하였던 Keyframe Animation을 모두 제거해주려한다.

언제부터 언제까지 값이 존재하다가 사라질지를 매번 Keyframe Animation으로 수정해주는 것이 까다롭다고 느껴졌다. 이보다 더 효율적인 방법을 만들어 써보겠다.

 

조금 이론 설명을 하고 들어가겠다.

지금 정보를 컨트롤하고 싶은 방법은 이러하다. 파라미터를 생성해 Start Frame과 End Frame에 원하는 값을 넣기만 한다면, Dop Network에서 알아서 작동이 되었으면 한다.

SF에는 값을 1, EF에는 값을 0을 줄 수 있다. 이때 density와 같은 정보를 조금 더 세게 쓰고 싶다면 다른 어떠한 Multiply를 만들어 조절해줄 수 있을 것이다.

이때 chramp를 이용해 SF과 EF 사이의 값들을 조절해줄 예정인데, 이를 위해서는 SF과 EF 안의 값들이 0~1 사이의 숫자로 표현되어야한다.

이를 (Frame - SF)/(EF - SF)의 식을 통해 표현해주도록 하겠다.

이때 SF이 현재 Frame보다 작아서 음수값이 되는 것을 방지하기위해서 Clamp function을 사용해줄 예정이다.

 

Add node 아래에 새로운 Attribute Wrangle을 달아준다.

필요한 정보인 float sf,ef,play 그리고 f@denapply를 정의내려준다.

sf과 ef에 chf을 달아준다.

play는 (@Frame - sf)/(ef - sf)으로 정의내려준다.

play의 음수값을 없애주기 위해서 0~1 사이의 값으로 clamp해주도록 하겠다.

@denapply를 play 값을 기반으로 한 chramp로 정의해주었다. Ramp 파라미터의 모양을 변경해 density가 발생할 구간을 정해줄 수 있다.

해당 Attribute Wrangle을 복사해 denapply를 tempapply와 divapply로 변경해준다.

전부 divsize 아래로 연결해준다.

제일 아래의 Control의 Geometry Spreadsheet을 보면 정보들이 잘 들어와있는 것을 볼 수 있다.

 

방금 만든 정보들을 조절할 수 있는 Controller를 따로 만들어주겠다.

divsize 위에 null을 새로 달아주겠다.

Edit Parameter Interface에서 방금 만든 SF과 EF, Ramp의 파라미터들을 density, temperature, divergence 각각 생성해 폴더로 분류해주겠다.

Para에서의 파라미터들을 Copy Paramter해 정보들에 연결해주겠다.

Density에서의 값과 Temperature에서의 값은 Copy Parameter로 동일시해주겠다.

 

이제 방금 만든 정보들을 실질적인 내용들과 연결해주려한다.

density의 Volume Vop에서 densitymult의 내용에 point function을 이용해 @denapply 정보를 넣어준다.

똑같은 작업을 tempmult, tempdivmult에도 해주도록 한다.

mult로써 만들어둔 Parameter는 언제 시작해서 언제 끝나는지, 그리고 그 값은 어떤 식으로 곡선을 가질지를 판단해준다.

값들의 세기를 조절하기 위해서 새로운 Parameter를 하나 더 생성해 곱해주도록 한다. density, temperature, divergence 전부 해당 작업을 해주도록 한다.

그리고 para에서 이러한 extramult에 관한 새로운 파라미터들을 생성해주도록 한다.

 

이제 para에서의 값들을 변경해 완성된 결과를 보려 한다.

density와 temperature에서의 Ramp는 0~1로 갈수록 그 value가 점점 작아지도록 해주었다.

divergence는 점점 커지다가 0.8쯤에 value가 최대값을 찍고 다시 0에 가까워지도록 만들어주었다. 끝 부분에 조금 더 폭발적인 느낌을 주기 위해서 EF을 density보다 늘려주었다. divergencemult 값은 Bounding Box를 건드리지 않는 선에서 값을 키워주었다.

 

결과를 보면 중간부터 폭발적으로 커지는 연기를 볼 수 있다.

모든 Smoke Solver 세팅이 완료가 되었다. 지금까지의 구조가 앞으로의 수업에서 연기 작업을 할 때의 골격이 된다.

이제 강의 초반에 이러한 과정을 다시 만들지 않고 복사해서 쓸 예정이다.

오늘 수업했던 내용이 기억에 나지 않는다면 완벽하게 따라해보는 복습 시간을 가져보도록 하자.