본문 바로가기

VFX/Niagara

[Udemy] 88~94강. Rain FX

Rain Drop을 만들려면 위와 같은 것들이 필요하다

 

 

 

*M_LiquidMaster

Surface, Translucent, Unlit에 Refraction은 IOR로 했음. Refraction은 원래 안켜져있는데 리프렉션 메서드를 IOR로 해주면 켜짐.

우선 캐시데이터

Seam은 Refraction 쪽에서 LiquidRefractionMask를 이용해주니 없어졌다. 그냥 IOR인 1.33을 넣어주면 Plane의 Seam 그대로 나옴. IOR이 1이면 굴절현상이 없어진다. 그래서 Mask와 Lerp를 이용해서 Seam을 없애주고, 물방울 모양의 굴절도 더 정확하게 표현함. 그리고 Refraction이 제대로 나올려면 Normal맵을 연결해줘야 함!

Fresnel을 물방울모양에 적용함. Fresnel에도 노말맵을 적용하려면 반드시 Tangent Space를 World Space로 바꿔줘야 함! 안그러면 정확하지 않은 노말맵이 들어감. 

 

 

 

 

*Cloudy Sky

구름낀 하늘을 만들려면 SkyAtomosphere의 Mie Scattering Scale(미애 스캐터링 스케일)을 만져주면 된다. 이 값은 맵의 메인이 되는 라이트의 밝기에 따라 결정된다. 그래서 밝을수록 이 값도 커져야 한다.

보통 이 값은 1이 넘어야 cloudy한 하늘을 만들 수 있다.

 

 

 

*Collision & Kill Particle

이제 빗물이 어딘가에 부딪혔을 때, 파티클을 삭제되도록 하려고 한다

일단 Collision 모듈을 추가해보면, 빗물이 튕긴다..! 

이번엔 Kill Particle 모듈을 보면 이것이 bool 값에 의해 작동되는 것을 알 수 있다

콜리전이 작동했을 때, Kill Particle의 bool값을 true로 해주려면 어떻게 해야할까?

그러기 위해서 일단 Collison의 파라미터 쓰기 값을 둘러보았다.

빗물 파티클의 Collison 모듈에 이용된 파라미터들이다. 여기서 저 HasCollided(Particle)이라는 파라미터를 이용하면 될 것 같다!

 

그래서 이 값을 Kill Particles에 넣어주었다. 잘 작동함!

이제 이 값을 이용해서 콜리전이 작동될 때, Splash 파티클이 생성되게 하면 될 것 같다!

 

 

 

*Generate Collision Event 모듈

콜리전이 작동될 때 파티클이 생성되게 하려면 Generate Collision Event 모듈과 Event HandlerRecieve Collision Event 모듈을 이용하면 된다.

당연히 정보를 보내줄 모듈은 Rain에 넣고, 정보를 받을 이벤트 핸들러는 Splash에 넣어줘야 한다..

우선 저 모듈을 넣어주면 오류가 뜬다! 나이아가라 로그를 보니 Requires Persistent ID를 켜주라고 한다. 걍 프로퍼티 모듈로 가서 켜주면 된다.

프레임당 최대 이벤트를 0으로 하면 엄청 많이 생성될 것임. 일단 1로 놓고 전체적으로 더 많이 생성하고 싶으면 이걸 늘리면 됌.

스폰 수는 충돌했을 때 그 자리에서 몇 개의 파티클을 생성하겠냐는 것임. 1로 해주기

 

이 두 모듈을 추가하고 사진처럼 해주면 된다. Recieve Collision Event는 추가만 하고 값은 아무것도 안건드렸다.

이렇게 하면 알아서 스폰됌! 그러니깐 Simple Sprite Burst는 삭제해주면 된다.

 

 

*Collision Radius 수정

지금 콜리전 발생될 때 나타나는 파티클 종류가 엄청 많은데, 서로 축이 맞지 않는다. 어떤 것은 땅에 바짝 붙어서 생기고 어떤 것은 땅의 살짝 위에서 스폰되고 있다.

이것의 이유는 Collision Radius가 너무 크기 때문. 현재 1로 되어있는데 0.4 정도로 줄이면 괜찮아진다.

 

 

 

근데 문제가 생겼다! 평평한 땅에서는 잘 작동하는데 경사가 있거나 울퉁불퉁한 곳에서는 맞지 않는다!

Ripple이 Slope를 따라 생성되지 않는다!

그래서 일단 이렇게 경사진 곳에서는 파티클을 다 Kill 하려고 한다. 이렇게 하려면 어떻게 해야할까?

 

Collision Event를 받는 아무 이미터에 들어가서 Recieve Collision Event 모듈을 봐보자. 그러면 디테일 창에 여러가지가 뜨는데 우선 Position이 Apply로 되어있다.

무슨 말인지 설명을 읽어보니 Apply는 다른 이미터에서 Generate Collision Event 모듈로 보낸 정보를 받아서 내 파티클의 position에 적용해준다고 적혀있다.

반면에 Output은 보낸 정보를 받아서 (Output)(RecieveCollisionEvent)Vector_1 이라는 파라미터에 저장만 해놓는다고 적혀있다. 이걸 나중에 쓸 수 있게

이벤트 핸들러가 이런식으로 작동되고 있었다!

그래서 이 Position과 Collision Normal의 값을 이용하여 경사가 있는 경우 파티클을 Kill 하려고 한다.

 

방법은 Dot Product로!

닷연산의 결과가 0.99보다 크다는 것은 평면이라는 뜻이니깐 이때는 파티클을 살려두면 된다

 

이제 이것을 Niagara Module Script로 구현해보자

위 사진처럼 평평한 땅의 벡터는 (0,0,1)일 것이다. 이것을 Collision이 적용된 오브젝트의 Normal값과 Dot연산해서 이것이 0.99일 때 파티클을 살려두면 될 것이다.

파티클을 Kill할지 살려둘지에 관한 파라미터는 이미 있다! (DATA INSTANCE)Alive를 쓰면 된다!

짜증나는 점. 노드 검색할때 한글로 검색하면 잘 안된다! 머티리얼 그래프는 되는데 NMS는 안되는거 많다!!!! Dot도 내적으로 쳐야 나오고, Make Float도 한글로 플로트 이렇게 쳐야 나온다!!!!

 

 

그다음 이벤트 핸들러 쪽에 NMS 모듈을 추가해주면 된당

CollisionNormalToCheck에는 뭘 넣어야할까..? 잠깐 머리가 하얘졌지만 아까 했던거를 생각해보면 된다

 

아까 Receive Collision Event 모듈에서 봤던거! 여기서 Collision Normal을 Output으로 바꾸고 이걸 이제 CollisionNormalToCheck에 넣어주면 된다

 

이제 경사진 곳에는 안생김! (Rain은 끄고 Splash 하나만 켜놓은 상태임)

이제 모든 Splash Emitter에 방금 만든 Emitter 넣어주면 된다

 

근데 좋은 방법은 아님

그러면 Slope일 경우 파티클을 Kill하는 옵션 / Slope의 Normal대로 파티클을 Align하는 옵션을 둘 다 만들고 Enum을 이용하여 내가 둘 중에 고를 수 있게 만들어보자

 

 

*Enum

Enum은 옵션을 고를 수 있는 드롭다운같은거라고 생각하면 된다

 

그래서 이런 로직으로 구현해보려고 한다

 

Enum의 생성방법은?

Enum을 만들고 Project Setting에서 Niagara Enum List에 만든 enum을 추가해줘야 한다고한다.

(블루프린트 enum은 이렇게 하지 않아도 된다! 그냥 그 자체에서 만들고 쓰고 할 수 있다고 함)

 

Enum... 한국말로 열거형.. 구리다

 

저 버튼을 눌러 enum을 추가해주면 된다

 

그다음 프로젝트 세팅에 나이아가라라고 친 다음 추가 파라미터 열거형에 추가해주면 된다

그리고 언리얼 껐다가 재시작해야한다...

 

그리고 다시 콜리전 노말 체크하는 NMS에 가서

Static Swith 생성 후 사진처럼 설정해주기. 스태틱 스위치라고 한글로 쳐야 나옴; 짜증나서 그냥 영어 버전으로 바꿈

Input Parameter Name에는 실제 NS에서 보여질 이름 지어주면 되고

Static Switch Type는 원래 Bool로 되어있는데 내가 만든 Enum으로 바꿔주기. enum이 2개씩 나오는게 있는데 그냥 언리얼 상의 오류인 듯

 

그다음 Static Switch에 +버튼을 눌러서 NiagaraParameterMap 클릭! 그럼 저렇게 된다

Map Get과 Map Set은 여러개 생성할 수 있다! 오옹 몰랐음

그래서 Kill Particle / Align Particle의 결과에 맞는 Map Set을 각각 Static Switch 파라미터의 NiagaraParameterMap에 연결해주면 된다

 

그리고 다시 NS로 가서 세팅해주면 됌. 중요한 건 Align Particle로 할거면 Sprite Renderer에서 Custom Alignment로 해줘야 한다는거!

 

 

엥 Align 안되는데..?

라고 생각했지만 이유가 있었음

왜냐면 Facing Mode를 (0,0,1)로 해뒀기 때문임.... ripple은 하늘을 봐야 하니깐

그러면 강사가 그냥 ripple만 Kill Particle로 해놓으면 된대

 

생각해봤는데 Ripple만 데칼로 놔두면 되지 않을까

그러면 경사진 곳에서도 잘 나올텐데

 

 

쨋든 완성~