자연환경에서는 물방울이나 입자들과 단단한 물체가 충돌하면 2차 이벤트(현상)이 발생한다. 대개 1차 충돌에서 끝나는 경우는 거의 없다. 가령, 계곡에서 흘러내려오는 물방울들은 끊임없이 바위에 부딪치면서 여러 방향으로 튕겨나간다. CG특수효과의 달인들은 입자간의 2차,3차, ..., n차 충돌을 정밀하게 살려낸다. 그들은 자연현상을 주의깊게 관찰하고 물리적 지식을 세부적으로 적용한다. 



입자간 충돌을 표현하는 'splash'작업은 Maya의 자체기능을 사용하여 쉽게 생성할 수 있다. 만일 파이썬과 mel 스크립트를 사용할 수 있다면 자체적으로 '자신만의 씬'을 만들 수 있


이번 포스팅에서는 자동적으로 구현하는 방법과 스크립트 방식 두가지에 관해 알아보자.



1 emitter 생성 및 rigidbody

omni타입의 emitter를 생성하고, 중력을 받아 땅에 떨어지는 효과를 연출해보자.


스피어를 꺼내어 아래 사진처럼 납작한 돌처럼 만들어준다. 스피어는 nCloth -> create passive collider를 실행하여 rigidbody로 만들어준다. (rigidbody는 n파티클과 반응한다)



2 Particle Collision Event Emitter 실행

n파티클 shape노드를 선택한 이후에 Particle Collision Event Emitter를 실행한다. Particle Collision Event Emitter는 'Event'(사건)가 발생할 때마다 Emitter가 생성되는 기능을 수행한다. 


Particle Collision Event Emitter 설정에서, Num particles 수치를 어떻게 설정하느냐에 따라 충돌이 발생(Event)직후에 생성되는 파티클 수를 조절할 수 있다. 또, spread(퍼져나감)나 velocity(가속도)값에 따라서 생성되는 파티클의 운동량을 조절가능하다.


타임라인에서 시뮬레이션을 실행하면, 아래처럼 n파티클과 1차 충돌 이후 2차적인 입자들이 생성되는 장면을 볼 수 있다.


충돌 이후 생성되는 파티클들의 색상값이나 물리적인 움직임을 조절하려면, 

아래처럼 nParticle2 shape노드의 속성창을 조절하면 된다. (색상을 녹색으로 변경)


Particle Collision Event Emitter 설정에서 'split'을 선택하면, 파티클의 1차 충돌이 발생하자마자 원본 파티클들이 모두 화면에서 사라진다. 만일 충돌로 새로 생겨난 파티클만 구현하려면, 아래와 같이 'split'에 체크하고 시뮬레이션을 실행한다. 



3 충돌 이벤트 파티클 만들기(수동)

파티클들이 충돌후 계속 하강하지 않도록 nucleus노드의 'use plane'에 체크한다. 


nParticle1 노드의 add Dynamic Attribute로 가서 'collisionGeometryIndex'항목을 추가한다. collisionGeometryIndex 항목은 파티클과 rigidbody 오브젝트의 충돌값을 알려주는 노드이다. 


가령, 파티클과 오브젝트(rigid body 설정)의 충돌이 발생하지 않을 때에는 '-1'값을 유지하고 있지만, 충돌이 발생하는 순간 '0'으로 바뀌면서 충돌했다는 '이벤트'를 알려준다. 



4 스크립트 작성

collisionGeometryIndex 값을 활용해서 충돌 이벤트를 감지한 '2차 파티클 생성' 스크립트 코드를 작성해보자. (빨간색 글씨는 주석)


 // 파티클이 오브젝트와 충돌한 후         

if( nParticleShape1.collisionGeometryIndex == 0 ) {     //파티클1 입자들이 rigidbody 오브젝트와 충돌했을 때          

vector $pos = nParticleShape1.position;     // 벡터 변수 $pos를 생성

int $birth = rand( 2 , 6 );                      // 생성되는 파티클 수를 2 ~6 사이로 랜덤하게 생성

for( $i = 0;  $i < $birth;  $i++ ){      // 생성되는 파티클 수만큼 반복

vector $vel = << rand(-2,1), 0, rand(3,-1) >>;   // 생성되는 파티클의 가속도 값을 설정한다.

emit -object point -position ($pos.x) ($pos.y) ($pos.z) -at velocity -vv ($vel.x) ($vel.y) ($vel.z);

}

}


emit 명령어는 파티클을 생성할 때 사용한다. emit 뒤의 -object 플래그를 붙인 후에 파티클 이름인 'point'를 입력한다. -position 플래그 뒤에는 벡터 위치값이 온다. ($pos.x) ($pos.y) ($pos.z)

-at는 attribute 속성을, -vv플래그는 velocity값의 value를 의미한다. 


mel스크립트 하단창에 'nParticle -name point'를 타이핑하여, point 파티클 shape을 미리 생성해둔다. nParticle1shape노드는 lifespan값을 lifespanPP로 설정해둔다. (파티클 하나하나 life 속성을 조절)


nParticleShape1.lifespanPP = -1; 를 넣는다. 만일 lifespanPP = -1로 설정해주면, 물체에 부딪치는 1차 파티클들은 모두 사라진다. 


시뮬레이션을 실행하면, 아래처럼 물체에 부딪치는 1차 파티클들은 모두 사라지고, 2차로 생성된 파티클 shape(point)만 나타난다. 


파티클을 랜더링하는 방법은 간략하게 다음과 같으며,


1] 폴리곤 변환 => 쉐이더 적용 => 아놀드 랜더링

2] 파티클 증가 => 아놀드 랜더링


폴리곤 변환과 쉐이더를 적용하는 방법은 '창문에 흘러내리는 효과' 포스팅을 참고하자.