TWA Houdini1/Rigidbody

TWA 후디니 1 RIGIDBODY_18_01 : 콘크리트 - 치핑

yiss09 2023. 4. 28. 00:50

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

 

HOUDINI1_ RIGIDBODY

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

www.twahoudini.com

 

후디니1 강의에서 다뤄볼 재질은 콘크리트, 나무, 유리, 철 총 4가지이다. 

재질을 예쁘게 묘사하는 핵심은 얼마나 조각을 예쁘게 준비하느냐, 얼마나 어울리는 Constraint 규칙을 활용하느냐에 달려있다.

 

Rigibody18_01에서는  재질 중 가장 먼저 콘크리트 재질에 대해서 배워볼 예정이다.

콘크리트 재질을 가장 먼저 배우는 이유는 Constraint 표현이 제일 쉽기도 하고, 유독 콘크리트 묘사에서 조각을 내는 것에 대해 할 이야기가 많기 때문이다.

 

앞으로의 수업의 큰 흐름은 이러하다.

조각을 먼저 준비해줄 것이고, 조각이 모두 준비되었다면 그때 충돌할 물체를 최대한 단순화하여 Simulation을 먼저 진행해보고 다른 물체로 충돌해도 되겠다고 판단이 선다면 이후에는 Brute의 도끼와 자동차를 가지고 콘크리트 벽에 충돌을 일으켜볼 예정이다.

 

목차

1. 이론 설명

2. 치핑

3. Simulation 세팅

4. @area

 

 


1. 이론 설명

 

콘크리트 묘사에 들어가기 전 우리가 어떤 전략을 가지고 작업에 임해야 할지, 또 상황에 따라 어떤 접근이 옳을지 같이 이야기하고 직접 만들기 시작하겠다.

사진의 조각들은 우리가 작업을 하게 될 과정의 순서이기도 하면서, 어떤 단계까지 콘크리트처럼 묘사할지에 대한 선택지이기도 하다.

선택지라고 표현한 이유는 이러하다.

위와 같이 조각들의 큰 골격이 동일한 상황일 때, 무엇을 작업하느냐에 따라 필요한 디테일의 양이 달라지게 된다.

조각난 면의 디테일이 다 보여야하는 작업이 있는 반면 먼 거리에서 촬영함으로써 디테일을 적당히 타협하는 작업도 존재한다. 작업하는 내용의 스케일에 따라 디테일을 얼마나 살릴지, 디테일을 얼마나 포기하고 Simulation 속도를 올릴지를 고민해주어야 할 것이다.

즉, 의도를 가지고 어디까지 디테일 작업을 할 것인지 직접 판단을 내릴 수 있어야 할 것이다.

 

이제 디테일을 올리는 각각의 단계에 대해 말해보겠다. 이때의 과정은 Procedural하게 진행될 예정이다.

1. 그냥 Box에 Voronoi Fracture를 한 결과이다. 디테일을 살리기 전 기본적인 흐름을 잡아준 모습이다.

2. 큰 조각의 모서리 끝부분이 랜덤하게 부러지게 해주려 한다. 모든 모서리가 부러지길 원하는 것이 아니라 어떠한 random 값에 의해서 부러지는 모서리가 계속 바뀔 수 있도록 해주겠다. 또한 부러지는 조각의 크기, 깊이, 각도도 조절해줄 것이다.

이러한 과정들을 치핑이라 하겠다.

3. Noise를 활용해 조각을 내줄 것이다. 첫번째에 단면이 구불구불한 것을 볼 수 있다. 이를 노이징이라 하겠다.

4. 치핑과 노이징을 동시에 적용하여 디테일이 많아진 결과이다.

두 가지 스킬을 잘 다룸으로써 콘크리트를 만들어낼 수 있다.

 

 


2. 치핑

 

치핑에 들어가기 전 우선 기본 골격을 마련해주려 한다.

간단하게 Box를 Voronoi Fracture로 쪼개주겠다.

이때 쪼개지는 위치를 조금 더 랜덤하게 해주기 위해서 Scatter의 Relax Iterations를 꺼주도록 하겠다.

Exploded View로 확인해보면 잘 분리되어 있는 것을 볼 수 있다.

그 다음 Assemble에서 Packing 해주도록 하겠다. 이때 Packing을 해주는 이유는 Dop Network에서 이용하기 위해서가 아니라 각각의 조각을 따로 편하게 작업해주기 위해서이다.

 

 

치핑을 쉽게 이해하는데에 Voronoi Fracture가 어떻게 작동되는지 아는 것이 도움이 된다.

작업에 들어가기 전 간단하게 Voronoi Fracture에 대해 설명해보겠다.

Voronoi Fracture에서 Fracture는 조각을 낸다를 뜻하고, Voronoi는 공간에 기준을 잡는 방식 중에 하나이다.

MeanposNearpoint function을 떠올리면 작동방식을 이해하는데 도움이 될 것이다.

간단하게 말하자면 어떤 공간상에 주어진 두 점 중에 좀 더 가까운 곳을 영역으로 나누는 것이 바로 Voronoi Fracture이다.

하지만 어디가 어느 점에 더 가까운가만을 생각해서는 Voronoi Fracture를 가지고 원하는 곳에 제대로 커팅하기가 어렵다.

좀 더 추가적으로 설명하자면, Voronoi Fracture에서 쓸 점 두개를 직선으로 이어주었을 때 그 직선의 중심을 수직으로 가르는 면이 공간이 갈라지는 경계가 된다.

만약 중심이 되는 점이 있고 그 외의 점이 사각형 외부에 위치해 있다면 그로 인해 모서리가 커팅되게 된다.

 

Box를 생성해 Add로 점을 제외한 모든 면을 지워주겠다.

그렇게 얻은 점과 {0,0,0} 위치의 점을 Voronoi Fracture의 Input2에 넣어주겠다.

결과를 보면, 원점과 모서리의 점들에 의해 쪼개진 Box를 볼 수 있다.

이때 Transform의 Uniform Scale 값을 건드려 모서리의 점들의 위치를 변경해준다면, 이에 따라 조각들의 크기도 변하게 된다.

또한 Attribute Randomize로 P 정보에 랜덤한 정보를 더해주게 되면, 조각들의 위치 각도가 바뀐 결과가 나오게 된다.

점의 거리가 멀어진 조각은 그 크기가 작아졌고, 반대로 가까워진 조각은 그 크기가 커진 것을 볼 수 있다.

 

이제 원래의 작업으로 돌아와준다.

For-each Primitive로 각각의 조각에 대해서 작업해주기 전 먼저 Blast로 한 점을 떼어내어 작업해주도록 하겠다.

이 조각을 Voronoi Fracture로 쪼개주기 위해서 각 모서리의 점과 중심점을 구해주려 한다.

Pack 되어 있는 조각을 Unpack해준 뒤 Add로 점만을 남겨주겠다. 모서리점들이 구해졌다.

이제 중심점을 얻기 위해서 평소처럼 Bound를 이용해주겠다. 하지만 결과를 보면 무언가 구해진 점이 조각의 중심처럼은 보이지 않는다.

 

그리하여 새롭게 Extract Centroid node를 사용해주겠다.

Method가 Center of Mass로 구해준 점은 무게 중심을 활용해 구해준 중심점이다. 결과를 보면 Bound로 얻어낸 점과는 위치가 다른 것을 볼 수 있다.

Method가 Bounding Box Center로 구해준 점은 Box를 기준으로 한 Bound에서의 중심점과 같다.

이때 조각의 중심점을 Center of Mass로 구해주도록 하겠다.

 

Voronoi Fracture에서 중심점과 모서리점들로 큰 조각을 쪼개주겠다.

이제 작은 조각들의 사이즈를 줄여주기 위해서 모서리점에서 중심점을 빼주도록 하겠다. 그리고 그 값을 각 points에 더해주겠다. 거기에 chf값을 곱해주어 멀어지는 간격을 조절해주도록 하겠다.

이제 Deep 파라미터로 치핑된 조각의 사이즈를 조절할 수 있게 되었다.

 

이번에는 랜덤하게 point를 골라서 조각의 쪼개짐 유무를 정해주겠다.

새롭게 시드값을 생성해 해당 시드값보다 작은 값을 가진 point들은 지워주도록 하겠다.

결과를 보면 치핑되지 않은 조각과 치핑된 조각이 함께 있는 것을 볼 수 있다.

이때 Limit 파라미터를 조절해줌으로써 치핑될 조각들의 갯수를 고를 수 있다.

 

만들어준 시스템이 다른 조각에도 잘 작동하는지 확인해보겠다.

작동은 잘하고 있지만 고쳐야할 문제가 보인다. 바로 한 꼭짓점에 너무 많은 점이 몰려있는 상황이다.

이때 Deep 값을 조절해보면 한 꼭짓점이 세 갈래로 쪼개진 것을 볼 수 있다.

이러한 현상을 방지하기 위해서 Fuse node를 활용해 꼭짓점을 하나로 뭉쳐주겠다.

Fuse에서의 Snap Distance 값을 올려줌으로써 해결해줄 수 있다. Fuse는 만약 Snap Distance 값이 0.1이라면 0.1보다 작은 거리에 있는 점들을 뭉쳐주는 역할을 한다.

이 정보를 기준으로 모서리점들을 얻어준다면 Deep 값에 상관없이 하나의 꼭짓점의 결과가 나오는 것을 볼 수 있다.

 

이제 위의 시스템을 For-each Primitive에 넣어서 활용해보겠다.

For-each Primitive에서의 결과를 Assemble로 Pack해준 후 Exploded View를 활용해주면 치핑이 만들어진 것을 볼 수 있다.

Scatter에서 점의 갯수를 늘려준다면 더 많이 조각난 결과를 얻을 수 있다.

 

기본적인 치핑이 완성되었다. 여기에 조금 더 추가적인 디테일을 추가해보겠다.

치핑이 되는 각도에 랜덤한 느낌을 추가해줘보겠다. point가 중심으로부터 멀어지는 곳에 랜덤한 느낌을 추가해주겠다.

새로운 float 변수들을 만들어 모든 점에 대해서 랜덤한 값을 가지게 한 다음 하나의 vector 정보로 합쳐주겠다.

이 정보를 @P에 더해줌으로써 각도를 조절해줄 수 있을 것이다. chf 값으로 그 세기를 조절해주겠다.

이때 각도에 대한 변수들이 0~1 사이의 값만을 가지는 것이 아쉽기에 fit으로 그 범위를 확장시켜주겠다.

 

그리고 방금 Voronoi에서 쓰일 point가 약간 다른 방향을 가지고 멀어질 수 있게 규칙에 손을 댄 것처럼 Deep에도 랜덤한 값을 주어 깊게 파이는 정도에도 변화를 주겠다.

이때 추가해줄 랜덤값은 보편적으로 음수값을 가지도록 세팅해주겠다. 왜냐하면 랜덤한 Deep 값이 양수로 커져서 Voronoi에 적용이 되지 않을 수 있기 때문이다.

결과를 보면 Randeep 파라미터를 조절해줌으로써 느낌이 변하는 조각들을 볼 수 있다.

 

 


3. Simulation 세팅

 

이제 완성된 치핑에 Simulation 세팅을 잡아보겠다. 이때 Constraint 세팅을 어떻게 잡느냐가 중요하다.

Constraint를 만드는 방식에 따라 다양한 옵션을 가지고 작업할 수 있는 것이 있고, 그렇지 않은 Constraint 세팅도 존재한다.

일단 Voronoi Fracture를 가지고 작업을 한 것이기에 14-3에서 만든 세팅을 쓸 수 있다. 가져와 Assemble에 붙여주겠다.

조금 수정해줄 부분이 있다면 이 Constraint 세팅에서는 @name이 아닌 @prep_name을 이용하였었다. 이를 Attribute Wrangle로 수정해주도록 하겠다.

결과를 보면 Constraint 세팅에 필요한 Primitive가 조각마다 생성된 것을 볼 수 있다.

 

그 다음 @prep_name을 그대로 이용하지 않을 것이기에 다시 @name 정보로 변환해주는 과정을 거쳐주도록 하겠다.

Attribute Delete로 사용하지 않는 prep_name 정보를 지워주도록 하겠다.

그리고 Constraint type과 name 세팅을 잡아준다. type은 all이다.

 

이제 Dop Network 안에서 Glue Constraint 세팅을 해주겠다.

충돌을 위한 그릇도 만들고 Sop Network에서 Sphere가 48 Frame마다 생성되도록 해주었다.

Sphere의 충돌에 의해 Box가 밀려나는 것이 아쉽다면 Box에 @active에 대한 세팅을 잡아준다.

매 Frame마다 Sphere의 life를 카운트하여 지정된 값을 넘은 후에는 사라지도록 해주겠다.

결과를 보면 충돌에 의해 조각나 부서지는 Box를 확인할 수 있다. 이때 전부 다 부서지는 것이 아니라 어떤 조각은 부서지고 어떤 조각은 부서지지 않는 것을 볼 수 있다. Col의 Denisty를 200으로 설정해둔 결과이다.

 

 


4. @area

 

이번에는 Constraint 시스템이 가지고 있는 부가적인 옵션을 활용해보도록 하겠다.

Geometry Spreadsheet의 Primitive 정보를 보면 @area 정보를 확인할 수 있다.

Geometry 단계에서 @area를 활용하여 Glue Constraint의 Strength 값에 영향을 주겠다.

결과를 보면 조각들이 잘게 부서지는 것을 볼 수 있다.

 

이때의 결과가 @area를 사용하지 않았을 때의 결과와 비교하였을 때 훨씬 많이 부서지는 이유는 무엇일까?

이를 올바르게 이해하기 위해선 @area 값이 절대적인 값이라는 것을 이해하여야 한다.

만약에 작은 유리잔을 깨뜨린다고 생각하고 지금과 같은 식에서 Glue Constraint에 @area 값이 곱해지는 상황이라면, @area 값이 작아짐에 따라 더 약한 고정력을 가지게 될 것이다.

반대로 빌딩과 같이 규모가 큰 조각들을 작업할 때에는 조각의 @area 값이 훨씬 커짐으로써 우리가 기대한 결과보다 많이 딱딱한 결과가 나올 수도 있다.

이를 Strength 값을 1로 고정시켜 Geometry 단계에서 @area 값을 건드림으로써 해결해주겠다.

현재 가지고 있는 @area 값이 Glue Constraint의 Strength가 될 것을 고려하였을 때 비율의 값인 @area에 다른 상수를 곱해줌으로써 Strength 값을 조절할 수 있게 해주겠다.

 

이제 @area 값을 0~1 사이의 값으로 몰아주려 한다.

우리가 만든 @area가 0~0.4 사이의 값으로 분포되어 있는 것을 볼 수 있다.

그래서 지금 가진 @area의 최댓값이 무엇인지 체크할 수 있는 세팅을 만들어줄 필요가 있다.

Sort를 이용해 @area 정보의 값에 따라 순서를 나열해주도록 하겠다.

이 정보를 area_to_strength로 받아 fit으로 @area 값의 범위를 조절할 때 pre_max 값으로 활용해주도록 하겠다.

이렇게 만든 fit 정보가 0~1의 값이기에 chramp로 만들어서 원하는 범위에서의 Strength 값을 조절해주도록 하겠다.

 

Glue Mult 값과 Ramp 값에서 0과 가까운 부분의 Value 값을 높여줌으로써 좀 더 딱딱하게 묘사된 조각들을 볼 수 있다.