콘크리트 묘사 두번째 시간
콘크리트 조각의 치핑을 적용하면서 거기에 더해서 조각의 절단면에 노이즈를 추가해보자.
노이즈가 들어간 조각의 constraint는 어떻게 잡아야 할지도 알아보자.
난이도가 높다.(!!!!)
- 지금까지 해왔던 작업 중 가장 꼼꼼하게 챙겨야 할 부분이 많다.
- Attribute 관리가 중요해진다.
- voronoi fracture에 대해 기존에 만들어놨던 constraint system 노드로 constraint 세팅을 마무리지을 수 있었지만, 절단면에 노이즈가 들어가는 순간, 이것만으로 해결할 수가 없다. 또 다른 방식의 constraint 세팅이 필요해진다.
- 대신에 voronoi에 특화된 방식이라서 기존에 사용했던 constraint system 방식보다 더 빠르게 작동한다.
이번에 원하는 것은 노이즈를 주기 전의 voronoi 결과와, 노이즈를 추가한 voronoi 결과의 큰 흐름이 같았으면 하는 것이다.
조각과 조각 사이의 노이즈를 주는 방법.
일단 기본적인 voronoi fracture가 적용된 box를 만들어준다.
작업의 기조는, "voronoi만 적용된 케이스와, 절단면에 노이즈가 들어간 케이스는 따로 작업을 진행하되 결과의 큰 흐름은 비슷해야 한다" 이다.
절단면에 노이즈를 주기 위해서는 remesh 등으로 면을 늘려줄 필요가 있다.
일단 voronoi fracture가 적용된 결과에 어떠한 정보가 있는지 확인이 필요하다.
interior group : 물체를 조각낼 때 만들어진 면들에 대해서 기입된 이름의 그룹으로 정리를 해두겠다 라고 이해하면 된다.
exterior group : 물체가 조각난 외형을 그룹으로 정리해둔 것
조각을 내는 단계에 따라 안쪽과 바깥쪽의 그룹을 따로 저장해주기 위해서 짚고 넘어가는 것이다.
치핑의 단계는 조각을 내는 두번째 사이클이다.
그래서 처음 조각을 내는 지금은 Ain / Aout 으로 그룹을 만들어주도록 한다.
두번째 조각을 내는 단계(치핑 단계)에는 Bin / Bout 으로 그룹을 만들어줄 예정이다.
새로운 노드를 사용해보자.
RBD Interior Detail Node
- Fracture의 안쪽을 꾸며주는 노드
- Interior Group : Fracture 노드의 Interior Group과 이름을 맞춰줘야한다.
- Detail Size : 안쪽에 생성되는 추가적인 면의 간격(사이즈)을 조절해주는 parameter
- Noise Amplitude : 안쪽에 생성되는 면의 노이즈의 세기를 조절해줄 수 있다.
만약, RBD Interior Detail 노드의 Interior Group에 Exterior Group 이름을 적는다면 어떻게 될까?
아쉬운 부분이 있다면, 내부의 면은 노이즈가 먹는데, 잘려나간 모서리 부분은 칼같이 똑 떨어지는 부분이 아쉽다.
이 부분은 restpos의 개념에 대해 알아야한다.
restpos를 만든다는 의미는 '원래의 위치를 기억시키겠다' 라는 의미이다.
- point가 어떠한 변형에 의해서 위치가 바뀌더라도 원래의 위치가 어디였는지 저장해두는 것이 restpos를 이용하는 의의이다.
만약 작업자가 얻은 결과가 아래의 이미지의 모양 그 자체라면, 위의 이미지 모양으로 돌아갈 수 있을까? 위의 이미지 모양에 대한 데이터가 없다면, 절대로 돌아갈 수 없을 것이다.
그래서 물체의 위치에 대해 변형을 가하기 전, 각 포인트의 현재 위치를 v@restpos 라는 어트리뷰트에 저장해두는 것이다.
원래 위치로의 복원을 원한다면, Attribute Wrangle을 활용해서 각 포인트의 위치에 대해 restpos로 복원을 해주면 될 것이다.
이 내용을 적용해보자.
일단 box를 쪼개기 전, restpos에 현재 위치정보를 저장해준 뒤, box에 노이즈를 추가해주고(포인트들의 위치에 변화가 발생했다) voronoi를 적용시켰다. 그리고 난 뒤 포인트의 위치를 restpos에 저장된 초기의 위치정보로 복구시켜줬다.
restpos로 복구할 때 box의 외부 색이 울긋불긋하게 보이는 부분이 존재한다. 이 부분은 noise가 적용되면서 normal에 변화가 발생하는데 이 때의 normal 정보가 그대로 적용되어서 시각적으로 울긋불긋하게 보이는 것이다. normal에 대해 정리를 해주면 된다.
절단면에 노이즈를 추가해주는 것 끝.
이제 문제는, noise가 적용된 면에 대해 어떻게 constraint를 적용할 것인가이다.
절단면에 noise가 적용된 voronoi fracture와 절단면이 그냥 매끈한 voronoi fracture 둘 다 적용이 가능한 세팅을 만들고 싶다.
constraint system 세팅을 위한 아이디어
예전에는 맞닿는 면이 하나의 면으로 구성되어있어서 그 면의 중심을 사용하면 되었었지만, 절단면에 Noise가 추가된 케이스는 조각과 조각 사이의 맞닿는 면이 매우 많이 존재해서 구체적으로 하나의 맞닿는 면의 중심을 구하기가 어렵다.한다. 지금은 그럴 수가 없다.
그리고, 치핑까지 생각을 한다면, 치핑되어 생성되는 조각들의 이름도 고려해줘야한다. 치핑이 된다고 해서 큰 조각의 이름이 바뀌어서는 안되며, 치핑된 조각들은 각각 떨어져나온 메인조각의 이름을 앞에 쓰고, 중간 네이밍으로 c(혹은 chip) 등의 이름을 기입한 뒤, 몇번째 조각인지 넘버링을 붙여주면 될 것이다.
- ex) 콘크리트 A 덩어리에 치핑을 적용해주면, A_c_0, A_c_1, ... 의 조각들이 생성될 것이다.
우리가 구해줘야할 constraint로는
- 큰 조각들 사이의 관계
- 큰 조각과 큰 조각에 치핑 작업을 적용해서 생성된 작은 조각들 사이의 관계
- 치핑 작업으로 생성된 작은 조각들 사이의 관계
이렇게 구해주는 것이 좋을 것이다.
voronoi의 추가적인 기능을 알 필요가 있다.
1) 포인트가 가지는 @attribute 정보를 조각의 모든 포인트에 넘겨주는 기능
만약 A 조각을 packing을 하면서 Transfer attribute로 @name 정보를 받아오겠다고 하면, A 조각이 packing 되면서 A 조각을 대변할 포인트가 생성되면서 @name 정보를 가지게 된다.
2) primitive에 무언가를 저장하는데, 어떤 조각에 의해 생성된 면인지를 그 어떤 조각의 포인트 번호를 저장해줄 것이다.
ex) 포인트 0과 1을 가지고 voronoi fracture를 생성하는 것으로 조각 A와 조각 B가 있을 때, 조각 A를 기준으로 조각 A / B 가 맞닿은 면은 조각 B에 의해서 생성된 면이다. 이 경우, 조각 A의 primitive에는 조각 B의 포인트 번호(1)가 저장이 된다.
바깥쪽 면의 경우, 누군가의 의해서 절단된 면이 아니기 때문에 이곳에는 -1이 저장된다.
이런식으로 모든 primitive에 숫자정보가 저장되게 된다.
voronoi fracture의 parameter 중 Copy Cell Point Attributes 를 체크해주고 To Piece Points에 name을 기입해주면, 각 조각의 모든 포인트에 대해 조각의 이름정보 @name이 저장된다.
voronoi fracture에 대해 assemble 노드를 연결해줄 때, Transfer Attributes에 위의 @f_name을 기입해주면, packing되면서 생성되는 물체를 대변하는 포인트에도 @f_name이 추가된 것을 확인할 수 있다.
noise가 적용된 케이스에도 적용해보자.
voronoi fracture에 대해 assemble 노드를 연결해줄 때, Transfer Attributes에 위의 @f_name을 기입해주면, packing되면서 생성되는 물체를 대변하는 포인트에도 @f_name이 추가된 것을 확인할 수 있다.
데자뷰가 느껴지는가?
면이 많으나, 면이 적으나 결과는 같게 나오고 있다.
constraint를 만드는데 있어서 가장 중요한 것은?
각각의 조각을 대변하는 포인트가 핵심이다.
현재 packing 되면서 생성된 물체를 대변하는 포인트들은 위치가 매우 아쉽다. 이 부분에 대해서는 조금 퀄리티를 올려줄 필요가 있다.
각각의 조각에 대해서 center of mass(무게중심)을 구해서 포인트로 만들어주고, 물체를 대변하는 포인트로 방금 생성한
무게중심점을 사용하는 것이다.
이제 constraint를 위해서 각 포인트를 연결해줘야하는데 connect adjacent pieces 노드를 사용하게 되면 한계가 드러나게 된다.
위 이미지를 보면 f_2와 f_4는 굳이 연결이 될 필요가 없는 부분이다.
일단은 이 부분은 나중에 정리하게 된다.
잠시, 위에서 언급했던, voronoi fracture에서 절단면을 새롭게 생성되게 하는, 조각의 대변되는 포인트 번호가 primitive에 저장된다는 것에 대해 이야기해보자.
이 정보를 생성해주는 방법은 voronoi fracture 노드의 Output Attributes 항목에서 Primitive Clip Piece를 활성화해주는 것이다.
voronoi fracture가 interior / exterior group을 나누는 기준이 바로 Output Attributes 항목에서 Primitive Clip Piece 정보였다.
- Primitive Clip Piece의 값이 -1 이면 exterior group으로, -1이 아니면 interior group으로 나누는 것이다.
이제 위의 포인트 번호에 해당하는 물체의 이름정보를 가질 수 있도록 세팅해주자.
noise가 적용된 케이스에도 이식해보자.
다시 constraint로 돌아가자.
일단 하나의 line에 대해 이야기를 해보자.
포인트 정보를 확인해보면,
f_name으로 보아 이 line은 f_2 조각과 f_3 조각 사이의 연결관계라는 것을 확인할 수 있다.
조각 뭉치에서 이 line을 만드는 조각들만 떼어내려면 어떻게 할 수 있을까?
각 포인트가 가지는 f_name과 조각 뭉치가 가지는 f_name을 비교해서 같지 않은 조각들을 모두 날려버리면 될 것이다.
이 작업의 의미는 connect adjacent pieces의 line을 활용해서 조각을 불러올 수 있다는 것이다.
조각에 대해 unpack을 해줬을 때 작업자가 얻을 수 있는 정보 중, 절단면이 생성되는데 관여한 반대편 조각의 포인트 번호(를 지금은 반대편 조각의 @f_name을 저장해뒀다)가 있었다.
connect adjacent pieces의 연결관계 중 현재 기준이 되는 조각 말고 다른 조각의 f_name을 가져와서 각 primitive에 저장된 이름과 비교해본 뒤 데이터가 같은 primitive만 남기고 다 지워주게 되면, 두 조각의 맞닿는 면을 구해줄 수 있다.
이렇게 구해준 면에 대해서 extract centroid 노드를 사용해서 무게중심점을 구해주고, 이 포인트를 활용해서 constraint를 만들어준다.
두개의 조각을 대변해주는 포인트로 만들기 위해 attribute copy 노드로 각 조각의 s@f_name 정보를 가져오고, 두 포인트를 add 노드로 연결해서 primitive로 만들어줬다. 또한 area 정보가 있으면 나중에 glue constraint 에서 strength에 활용할 수 있으므로, area 정보를 primitive에 추가해줬다.
위의 작업은 line이 바뀌어도 잘 적용될까?
3번 line을 떼어서 확인을 해보면
이번에는 불필요하다고 생각되었던 line에 대해 확인해보자.
- 현재 line 중 6번 line은 활용하지 않을 듯 싶다.
만들어지는 constraint 가 없다.
이와같은 상황에서 기준이 되는 조각의 반대편 조각의 이름은 f_4이다.
하지만, 절단되면서 생성된 면 중 f_4와 같은 이름을 저장하고 있는 면이 없기 때문에 attribute wrangle에 의해서 면들이 모두 날아가버리고, 이후의 무게중심점을 만들거나 하는 내용도 다 스킵되어버리기 때문에 constraint 세팅은 만들어지지 않는다.
for each primitive 블록을 적용해준다.
이제 noise 가 적용된 케이스에도 이식해보자.
참고로 area 부분에서 문제가 발생한다.
전체 면적을 구해주는 것이 아니고 노이즈로 만들어진 작은 면 한조각의 면적이 구해진다.
area 에서 Accumulate 를 바꿔주도록 하자.
- Throughout으로 바꿔주면 전체 면에 대한 면적이 구해진다.
비상)
버전 문제인지 뭔지 모르겠지만, noise 버전에서 extract centroid로 center of mass 를 구해주면 포인트가 튀어버린다!!
그래서 임시방편으로 measure에서 centroid를 구해주고(전체 면적에 대한 중심이므로, Accumulate는 Throughout으로 해줘야한다.) 점 하나를 만들어서 centroid 값으로 이동시켜주는것으로 적용했다.
이렇게 '한 사이클' 작업을 만들었다.
갈길이 멀다........
그래도 가야지 뭐~
이번에 할 일은 치핑이다.
치핑된 조각에 대해 초반에 언급한대로, 이름을 지어주는 규칙이 필요하다.
- 잘려나가더라도, 잘려나가기 전의 큰 조각의 이름을 유지한다.(위의 이미지의 큰 조각 이름은 f_2 이다)
- 그래야지 다른 큰 조각들과의 constraint를 만들 때 위에서 만들어준 것을 활용할 수 있다.
- 중간 네이밍으로 c(혹은 chip 등)를 붙여준다.
- 마지막 네이밍은 조각을 생성시킨 point number를 뒤에 붙여주기로 한다.
- 각각의 네이밍은 '_' 로 구분짓는다.
- f_2_c_0 / f_2_c_1 / ...
문제가 있다. 제공하는 포인트의 개수와, 치핑 결과로 나오는 조각의 수가 다를 수 있다.
- deep 값에 따라 사라지는 조각이 발생할 수 있다.
이 부분은 voronoi fracture의 primitive clip piece를 구해주는데 오류를 발생시킨다.
- 작업자가 기대한 대로 작동이 안된다.
일단 f_name / f_by / f_by_name 이 잘 만들어져야한다.
조각을 내주고 이름을 만들어주자.
포인트의 활용순서가 가장 큰 조각이 먼저가 아니기 때문에 우리가 원하는대로 작은 조각에 들어가는 f_by가 0이 아니다.
중심점이 맨 앞으로 올 수 있도록, merge에서 순서를 바꿔준다.
일단 f_by는 해결되었다.
이제 f_name을 해결해보자.
큰 조각과 치핑된 조각들을 따로 나눠주고,
큰 조각의 이름 정보를 attribute copy로 가져온다.
치핑된 조각들은 뒤에 붙여주기로 한 중간 네이밍, 마지막 네이밍을 붙여주면 f_name이 완성된다.
이제 f_by_name을 정리해줘야한다.
치핑 조각들에 대한 constraint는 위에서 작업한 내용을 복사해서 연결해주면 잘 돌아간다.
일단 치핑작업을 noise 추가 케이스에도 작업해보자.
조금 고려해줘야할 부분들이 있다.
귀퉁이의 포인트를 add로 떼어내서 voronoi fracture의 절단면을 만드는 포인트로 사용하려 하였으나, noise 데이터가 적요된 조각에 대해서는 포인트가 너무 많아서 어려운 부분이다.
그래서 voronoi에 대해서는 noise가 적용되지 않은 케이스를 기준으로 포인트를 받아와서 절단해준다.
그리고 두번째 사이클이기 때문에, 안쪽 면의 디테일을 높일 경우, RBD Interior Detail의 interior group을 두번째 사이클의 voronoi fracture에서 만들어준 것으로 기입해준다.(여기에서는 Bin 으로 진행하였다.)
노이즈로 인해서 조각의 개수가 다르게 나올수도 있다.(아주 작고 미세한 파편 등으로)
절단을 위해 넣어주는 포인트의 개수와 결과로서 나오는 파편의 개수가 다를 수 있다.
그래도 잘 구해진다.
이곳도 역시나 무게중심점 구해주는 부분이 이상하게 결과값을 도출해서, 위에서 작업했던 measure를 이용한 방법을 다시 사용했다.
이제 for each primitive로 모든 조각에 대해 치핑이 되고 constraint가 구해지도록 해주면 된다.
조각의 수를 늘려도 잘 적용된다. 또한 큰 조각의 절단 흐름도 유사하게 따라간다.
이제 두근두근, rigidbody 세팅을 잡을 시간이다.
기본적인 rigidbody 시뮬레이션 세팅에 충돌체 col과 sop 세팅을 추가해줬다.
이제 noise 적용 케이스도 시뮬레이션을 잡아보자.
일단 for each primitive로 블럭을 잡고, proxy 데이터를 만들어준다.
근데 뭔가 오류가 난것같다.
이런 결과가 나오는 이유로는, 정보가 중간에 유실되는 부분이 존재해서 그렇다.
proxy 데이터를 만드는 이 부분을 수정해줬다.
이제부터 할 일은 지금까지의 작업을 시스템화 해줘서 좀 더 사용하기 쉽도록 해주는 것이다.
sub network에 넣어주고,
control 노드를 만들고 parameter를 생성해준 뒤, 값을 링크시켜줘서 조절이 쉽도록 구성했다.
정리
- 이 작업에서 염두에 두어야하는 부분은 작업자가 스스로 어느 선까지 디테일을 파고 작업을 진행할 것인가 이다.
콘크리트가 이러할 것인데 다른것은 얼마나 어려우려나...ㄷㄷ
중간에 centroid로 center of mass 구하는 부분이 갑자기 데이터가 튀어버려서 ㅠ 다른 방법 찾아내고 적용도 해보고...
예전같았으면 진작에 기브업! 을 외쳤겠지만...
나 조금은 성장한것일까...?
'Houdini > Houdini1_Rigidbody' 카테고리의 다른 글
RIGID BODY_18 재질표현 + 어려움🔥🔥🔥 - Ep18_Part 04. 기둥+벽 박살내보자 (0) | 2023.04.26 |
---|---|
RIGID BODY_18 재질표현 + 어려움🔥🔥🔥 - Ep18_Part 03. 출력준비 (Brute & Car) (0) | 2023.04.25 |
RIGID BODY_18 재질표현 + 어려움🔥🔥🔥 - Ep18_Part 01. 콘크리트 - 치핑 (0) | 2023.04.20 |
RIGID BODY_17 캐릭터의 충돌조건 - Ep17. mixamo 캐릭터로 충돌조건 만들기 (2) | 2023.04.19 |
RIGID BODY_16 CONSTRAINT의 변형 (1) | 2023.04.18 |