TWA Houdini1/Rigidbody

TWA 후디니 1 RIGIDBODY_17 : mixamo 캐릭터로 충돌조건 만들기

yiss09 2023. 4. 26. 18:39

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

 

HOUDINI1_ RIGIDBODY

3️⃣ 출동 SIMULATION 기초 이론부터 심화된 내용을 공부합니다. 또한 자동차를 이용한 리깅 시뮬레이션 BASIC을 훈련합니다.

www.twahoudini.com

 

Rigidbody17에서는 지금까지 다루지 않았었던 물체의 충돌에 대한 컨셉들을 몇 가지 더 이야기해보겠다.

 

이전 Volume 강의에서는 물체를 충돌 조건으로 이용하기 위해서 SDF를 이용했었다.

하지만 Rigidbody에서는 기본적으로 Pack된 자료를 이용하기 때문에 다른 방법이 필요하다.

그리고 지금까지의 작업 방식과 달라야 하는 결정적인 이유는 16일차까지는 각각의 조각의 모양이 아예 바뀌는 녀석은 없었다. 그런데 오늘처럼 캐릭터가 충돌하기를 바라는 작업에서는 Deforming이 되는 것처럼 모양이 계속 바뀌게 된다.

이 상태로는 Convex Hull로 작업하기도 어렵고, Concave로 작업하기에는 시간적 효율에 좋지 않다.

이와 같은 이유로 새롭게 Rigidbody에서 이용하기 좋은 새로운 충돌 조건 2가지를 배워볼 것이다.

 

목차

1. active가 0일때의 충돌 조건 세팅

2. active가 1에서의 충돌 조건 세팅

 

 


1. active가 0일때의 충돌 조건 세팅

 

가져온 캐릭터를 많은 Sphere로 바꾸는 방식을 이용할 것이다.

그리고 Point Deform을 활용해 Sphere로 이루어진 캐릭터가 Animation에 맞게 움직이게 해줄 예정이다.

 

먼저 캐릭터를 Unpack해준 뒤, VDB from Polygons와 새롭게 VDB to Spheres를 꺼내주겠다.

우리는 Point Deform을 활용해서 Animation에 따라 Sphere들이 움직이게 만들 예정이다.

이때 기준으로 잡을 순간에 캐릭터가 웅크리고 있어 겹치는 면이 많아진다면 Point Deform이 예쁘게 작동하지 않을 수 있다. 움직임에 따라 결과가 찢어지는 것처럼 보일 수 있다.

그래서 캐릭터가 최대한 몸을 펴고 있는 상황에서 작업을 해주도록 하겠다.

Frame을 천천히 넘겨 관찰해보면 33 Frame에서 가장 넓게 자세를 잡고 있는 것으로 보인다.

TimeShift로 33 Frame에서의 움직임을 포착해주도록 하겠다.

그 다음 VDB from Polygons로 SDF 볼륨 정보로 변환해주겠다.

 

이제 VDB to Spheres를 연결해주면 우리가 만들어준 캐릭터 안쪽으로 Sphere가 생성된 것을 볼 수 있다.

이때 이 Sphere들이 Simulation에서 사용할 충돌 조건이 될 것이다.

그런데 지금 캐릭터를 보면 손끝 부분이 채워지지 않아 그 부분은 충돌하지 않는 것처럼 묘사될 것이다.

그래서 캐릭터를 Sphere로 얼마나 꼼꼼하게 채우는지가 핵심이 될 것이다.

VDB to Spheres의 파라미터에서 가장 중요한 부분은 Max Spheres와 Point Count의 밸런스가 될 것이다.

Point Count는 얼마나 많은 Volume 정보를 활용하여 제공받은 Volume 정보를 분석하고 그 안을 Sphere로 채울지이다.

즉, Point Count가 높다면 보다 고르게 캐릭터의 안쪽을 Sphere로 채우는 결과를 얻을 수 있을 것이고, 너무 낮다면 기대한 것보다 고르지 않게 Sphere들이 배치가 될 수도 있다.

Max Spheres는 최대 몇 개까지 Sphere를 쓸 것인가이다. Point Count의 값을 아무리 높여 분석률을 높인다고 하더라도 이용가능한 Sphere의 갯수가 50개로 제한이 된다면, 속을 꽉 채우는데에 무리가 있을 것이다.

 

Max Spheres의 갯수가 작을 땐 큰 Sphere로  먼저 채워주고 그 다음 여유가 생기면 작은 Sphere들로 남은 공간을 채워주게 된다.

이때 Point Count와 Max Spheres를 높게 둔 상태에서 Max Spheres의 갯수를 점점 줄여 적당한 용량에서의 예쁜 결과를 얻어주도록 하겠다. 너무 용량이 크지도, 부피가 작지도 않은 Max Sphere 2500을 사용하겠다.

 

그런데 이때 앞에서 제공한 SDF Volume 정보를 넘어서서 Sphere가 존재하는 것은 아니기에 닿았음에도 충돌하지 않는 현상이 어색하게 느껴질 수도 있다.

오히려 캐릭터보다 충돌 조건의 사이즈가 작은 것보다 조금 더 큰 것이 낫다고 판단된다.

Convert VDB를 달아 IsoValue 값을 조절해 SDF의 영역을 조금 더 넓혀주도록 하겠다.

다시 SDF Volume 정보로 변환해준 뒤 Sphere로 치환해주면 이전과는 조금 다른 결과가 얻어지는 것을 볼 수 있다.

 

이제 Point Deform에 필요한 정보들을 연결해주겠다.

Sphere들이 충돌조건으로써 움직이는 것을 볼 수 있다.

 

이때 왼쪽 팔에 Sphere가 크게 남아있는 것을 볼 수 있다.

이는 간단하게 Point Deform에서의 Radius 값을 조절해줌으로써 해결해줄 수 있다.

그 다음 Assemble node를 달아 Sphere들을 각각 Pack해주고 이름을 붙여주겠다.

 

Dop Network 안에서 캐릭터를 불러와주겠다.

결과를 보면 중력에 의해 부서지는 Sphere들을 볼 수 있다.

aad 세팅을 잡아줌으로써 Dop Network 안에서 캐릭터의 움직에 맞게 Sphere들이 움직이도록 해주겠다.

이때 Sphere가 Simulation에서의 영향을 받지 않길 원하기에 @active 값은 0으로 잡아주겠다. 그리고 움직임을 따라가도록 @deforming 값은 1로 해주겠다.

결과를 보면 충돌조건인 Sphere가 무너지지 않고 움직임을 가지는 것을 볼 수 있다.

 

충돌 조건의 움직임을 잡아주었으니 이제 캐릭터의 움직임에 부딪혀서 부서질 물체를 만들어주도록 하겠다.

Box를 만들어 IsoOffset으로 Fog Volume으로 만든 뒤, Scatter로 점을 뿌려주겠다.

그리고 그 점의 위치에 따라 Box들을 Voronoi Fracture로 쪼개주도록 하겠다.

그 다음 바닥에 고정되도록 active 세팅을 잡아주겠다.

Constraint 세팅은 Connect Adjacent Pieces로 간단하게 잡아주었다.

Dop Network 안에서는 Glue Constraint Relationship으로 고정되도록 해주었다.

결과를 보면 캐릭터의 팔에 부딪히면서 부서지는 Box를 볼 수 있다.

 

그런데 예상했던 것보다 훨씬 강력한 힘에 의해 부서지는 것을 볼 수 있다.

어떻게하면 충돌이 과하지 않게 발생되도록 할 수 있을까?

일반적으로 지금까지 충돌조건을 다룸에 있어 충격의 양을 조절할 때 다루어주었던건 물체의 질량이었다.

충돌이 더 약하게 발생하기를 원하기에 mutant의 Density 값을 줄여보도록 하겠다.

그런데 결과를 보면 전혀 Density 값에서의 변화에 영향을 받지 않는 것처럼 보인다.

Density가 아닌 Mass를 이용하여도 영향을 받지 않는다.

이렇게 힘조절이 원하는대로 되지 않는 것은 지금 사용중인 충돌 조건을 만드는 방식에서의 가장 큰 문제점이다.

일반적으로는 질량이나 속도를 활용하여 충격량에 대한 문제를 해결에 왔었다.

이때 mutant를 수정하지 않고 col에서의 Glue Constraint의 Strength를 조절해주는 것으로 충격량의 조절에 대한 묘사가 가능하지만, 이는 근본적인 해결책이 아니다. 

 

그리고 하나의 문제점이 더 있다.

바로 Frame과 Frame이 이동하는 그 사이에 물체가 존재한다면 통과해버리는 현상이 발생할 수도 있다.

이때 Simulation 자체의 Substeps를 높여주어 그 부분을 해결해줄 수 있겠지만, 이 또한 시간이 엄청나게 걸리기에 근본적인 해결책이 되지 못한다.

결과적으로 Substeps를 쓰지 않고도 Frame 사이에 묘사되지 않은 팔의 영향력을 충돌에 올바르게 적용시킬 수 있어야 하고, 다른 물체들에 손을 대지 않고 충돌의 세기를 바꿀 수 있어야 한다.

이를 두 번째 방법에서 해결해주도록 하겠다.

 

 


2. active가 1에서의 충돌 조건 세팅

 

먼저 지금까지 우리가 작업을 해왔던 방식은 물체와 충돌 조건을 최대한 일치 시켜서 Simulation이 끝나고 나면, 충돌 조건이 놓인 곳에 고화질 자료를 대체해주는 방식으로 작업이 진행되어 왔다.

그런데 지금 하고 있는 작업은 이미 결과로 쓰일 캐릭터의 움직임이 정해져 있는 상황이다. 즉, 캐릭터는 충돌을 발생시키기는 입장으로 충돌에 영향을 받는 대상이 아니다.

요약하자면, 이미 정해진 움직임을 따르는 캐릭터의 경우에는 굳이 충돌조건을 캐릭터에 맞추려 할 필요가 없다. 그리고 충돌조건이 연속적으로 Dop Network에 있을 필요가 없다.

 

기존 방법에서는 중력의 영향을 받지 않도록 active를 0으로하고 deforming을 1로 하여 충돌조건이 움직이도록 해주었다.

그런데 이 방식에서는 생각보다 충돌의 힘이 너무 강력했다. 그리고 충격량을 바꿀 때도 충돌조건이 변형의 주체가 되지 못하였다.

그리고 또 다른 약점으로는 Frame 사이에 떠 있는 부분이 존재할 수 있게 된다.

14 Frame과 15 Frame과 같이 간격이 떨어져 있다면 벽에 충돌하지 않고 통과하는 것처럼 묘사될 것이다. 이때 사용할 방법으로 Substeps 또한 옳지 못했다.

 

이제 새로운 방법을 이야기해보려 하는데 이 방법을 앞으로 Fake Collision이라고 하겠다.

Fake Collision인 이유는 충돌 조건이 오직 Dop Network 안에서만 존재하고 실제 출력에서는 비춰지지 않을 것이기 때문이다. 핵심은 Sourcing 과정이 될 것이다.

Simulation 작동 시점부터 이야기해보겠다. 

원래의 방식에서는 active가 0으로써 정해진 움직임에 따라 충돌 조건이 변화하도록 세팅했었다.

하지만 이번에는 active가 1인 상태로써 등장시켜 주겠다. 이에 중력의 영향을 받아 떨어지게 될 것이다.

대신 11 Frame에 등장한는 Sphere는 12 Frame의 위치로 던져지게 될 것이다.

이때 12 Frame에 잘 도착하였지만 중력에 의해 13 Frame으로는 가지 못할 것이다.

이를 해결하기 위해서 12 Frame에 도착한 Sphere를 지워준 뒤 다시 등장시켜 13 Frame으로 던져줄 것이다.

이렇게 계속 새로운 Sphere를 load해주고 다음 Frame에 놓일 자리로 던진 다음 도착한 순간 지워주었다가 그 자리에서 다시 등장시켜 줄 것이다.

이때 active가 1로써 Simulation의 영향을 받기에 충돌의 세기를 질량이나 속도로써 조절하는 것이 가능해지게 된다.

 

새롭게 충돌 조건을 잡아주도록 하겠다.

캐릭터에서 직접적으로 Box와 충돌할 부분인 팔 부분을 Blast로 떼어내주겠다.

그리고 Volume 정보로의 변환 과정을 거친 뒤 Sphere로 대체해주도록 하겠다.

그 다음 Point Deform에 각 정보들을 연결해주겠다.

 

우리는 여기서 Sphere가 전부 필요한 것이 아니라, Sphere들이 놓여있는 위치 정보만이 필요하다.

point 정보만을 남기기위해서 Add로 점만을 남겨주겠다.

point 자체의 사이즈를 맞추기 위해서 @pscale 값을 2배 곱해주도록 하겠다. 

그리고 각각의 point의 원래의 number를 알기 위해서 id를 부여하겠다.

 

잠시 앞으로 일어날 일을 예상해보겠다.

우리가 만들어둔 point들이 다음 Frame에서의 위치로 날아가게될 것이다.

이때 속도값을 구해주기 위해서 목표가 되는 타겟위치에서 원래의 위치를 빼주겠다. 그렇게 얻은 dir 정보를 변환하여 v로 사용할 것이다.

그런데 이런 방법을 사용하더라도 조금 비는 느낌이 들 수도 있다.

그래서 Frame 사이에 경로를 만들어줄 예정이다.

직선으로 날아갈 point들이 포물선을 그리면서 경로 정보를 남기도록 해주려 한다.

이를 위해서 Trail node를 사용해주겠다.

 

Trail Length로 얻을 경로의 갯수를 정해줄 수 있다.

Trail Increment를 조절하여 한 Frame에 들어갈 경로 정보의 간격을 정해줄 수 있다.

이 두 파라미터를 조절하여 point들이 어떤 경로로 날아가고 있는지 그 정보를 얻어줄 수 있다.

이때의 Trail로 얻은 경로 정보로 인해 Substeps에서 Frame 사이를 구현해주는 것과 같은 결과를 얻을 수 있다.

또한 여기에 id 정보를 활용해 선으로 만들어준다면 움직임이 어떻게 발생하고 있는지도 확인이 가능하다.

 

그러면 Dop Network에서 Sphere가 날아갈 방향은 어떻게 구하면 될까?

즉, 경로상의 point가 각각 어디를 향하고 있는지를 구해주어야 한다.

For-each Primitive를 꺼내 그 안에서 PolyFrame이나 Resample tangent 값을 구해주면 원하는 방향을 구해줄 수 있다.

Attribute Wrangle로 tangent 값을 불러와 속도로 이용해줄 수 있다. 만약 방향이 반대라면 -1을 곱해주면 된다.

또한 Resample node에서 Length나 Segment 값을 이용해 Sphere를 늘려줄 수 있을 것이다.

 

그리고 Trail로 생성된 Sphere들은 원래의 Sphere만큼 힘이 쎄게 작용할 필요가 없다.

Sphere의 크기가 뒤로 갈수록 점점 작아지도록 만들어주겠다.

id로 만들어진 선을 기준으로 보았을 때 가장 앞의 point는 값이 1, 가장 끝의 point는 값이 0이었으면 한다.

Resample에서 curveU 값을 구해주도록 하겠다.

curveU 값이 pscale 값에 영향을 줌으로써 원하는 느낌으로 점점 사이즈를 줄어들게 해줄 수 있다.

 

이제 Dop Network 안에서 세팅을 잡아주도록 하겠다.

이번에는 충돌 조건이 들어올 그릇을 만들고 바로 불러오는 것이 아니라 Sourcing을 거친 뒤 불러오도록 하겠다.

Sop Network 안에서 그릇과 Geometry 단계에서 만든 point 정보를 불러오겠다.

그리고 이제 내부에서 Sphere를 연결해 이용해주도록 하겠다.

이름은 최대한 겹치는 부분이 없도록 지어주겠다.

정보를 그릇에 합류시켜준 뒤 결과를 보면 팔이 움직이면서 많은 Sphere를 발생시키는 것을 볼 수 있다.

 

life를 count하여 life가 1보다 클 때 모든 points가 사라지도록 해주겠다.

결과를 보면 팔이 휘둘러지며 경로를 남기고 그 경로에 의해 Box에 비는 부분 없이 충돌하는 것을 볼 수 있다.

 

현재 Glue Constraint의 Strength 값은 기본값인 10000으로 지정되어 있다.

충돌이 일어나도 Box가 부서지지 않는 것을 볼 수 있다.

이제 드디어 충돌 조건의 충격량을 조절해보겠다.

무게를 늘려줌으로써 부서지는 Box를 볼 수 있다.

또한 Geometry 단계에서 point 정보 자체의 속도를 조절해줌으로써 충격량의 세기를 조절해줄 수 있다.

 

 

마지막으로 Fake Collision의 역할을 다하기 위해서 Geometry 단계에서 Simulation 결과를 비춰주도록 하겠다.

이때 fakecol 정보는 불러내지 않고 box의 정보만 불러내겠다. 어떠한 보이지 않는 충돌에 의해서 box가 부서지는 것처럼 묘사되고 있다.

여기에 Unpack한 캐릭터를 Merge하여 같이 보게 되면, 최종적으로 캐릭터가 box를 때려 부수는 것 같은 결과가 나오게 된다.