Unity 검색

다루는 주제
공유

Is this article helpful for you?

Thank you for your feedback!

비주얼 이펙트 그래프(Visual Effect Graph)를 사용하면 노드 기반 동작과 GPU 기반 컴퓨팅 능력을 활용하여 차세대 시각 효과를 구현할 수 있습니다. 처음 사용하는 분들을 위해 이전에 게시한 블로그를 통해 에디터의 기초 내용을 간략하게 설명했습니다. 또한 유나이트 LA 2018에서 최초로 프리뷰를 공개한 이후로 GitHub 저장소에 다양한 샘플 VFX를 지속적으로 퍼블리싱하고 있습니다. 샘플을 살펴보고 원하는 효과를 빌드하는 데 사용해 보시기 바랍니다!

이 샘플을 통해 간단한 파티클 시스템부터 특정 동작이 적용된 보다 복잡한 시스템에 이르기까지 비주얼 이펙트 그래프가 처리할 수 있는 다양한 제작 시나리오를 확인할 수 있습니다. 모든 효과는 별도의 씬으로 분리되어 있으므로 원하는 효과를 찾아서 학습할 수 있습니다.

샘플 다운로드

이 샘플을 다운로드하기 전에 먼저 Unity 2018.3을 사용하고 있는지 확인해야 합니다. 2018.3 에디터 버전 중 최신일수록 좋습니다. Unity Hub에서 최신 버전을 확인하여 다운로드하시기 바랍니다. 비주얼 이펙트 그래프 샘플은 Windows와 Mac 에디터에서 모두 사용 가능합니다.

적합한 에디터 버전을 연 상태에서 샘플 프로젝트를 가져옵니다. 비주얼 이펙트 그래프 릴리스 GitHub 페이지에서 소스 코드 zip 또는 tar.gz 아카이브 중 하나를 다운로드할 수 있으며, 정기적으로 업데이트하려는 경우에는 저장소를 클론할 수도 있습니다.

샘플 프로젝트 구조

각 샘플은 Assets/Samples 디렉토리의 하위 디렉토리에 있습니다. 플레이어를 빌드할 때 사용되는 기본 씬은 /Assets의 루트입니다. 이 씬은 Build Settings 창에서 씬 빌드 목록에 선언된 모든 샘플을 순서대로 로드할 때 사용합니다.

플레이어를 빌드해야 하는 경우 빌드 설정에서 VisualEffectsSamples 씬을 포함하고 인덱스를 0으로 설정해야 합니다. 그런 다음 반복할 다른 씬을 모두 추가하면 됩니다.

샘플 1 – 유니티 큐브

이 샘플은 비주얼 이펙트 그래프 초기 버전을 사용하여 프로토타입을 작성한 초기 효과 중 하나이며, 입체 유니티 큐브 주변으로 움직이며 40만 개의 파티클을 끌어당기는 방출 소스로 구성된 시스템을 보여줍니다.

방출 스피어와 해당 모션은 효과에 자체적으로 포함되어 있으며, 포지션은 축별 sin(Time) 조합을 사용하여 애니메이션됩니다. 이 계산에서 흥미로운 점은 사용자가 기존 프레임 사이에 서브 프레임의 위치를 결정하여 스피어 포지션의 이산화를 줄일 수 있다는 것입니다. 이 옵션을 토글하면 두 모드 사이의 차이를 확인할 수 있습니다. 아래 예에서 시간만 사용하는 경우 스피어가 너무 빠르게 움직여서 셰이프가 공간에서 이산되는 것이 보입니다. 하지만 파티클별 총 시간을 사용하는 경우 이러한 결함은 완전히 사라집니다.

파티클이 스피어에서 방출되면 파티클을 유니티 큐브로 이끄는 벡터 필드와 파티클이 끌려가는 동안 모션을 강화하는 노이즈인 벡터 필드로 구동됩니다. 또한 파티클은 방출 스피어와도 충돌합니다.

파티클 컬러는 두 가지의 그레디언트로 나타납니다. 하나는 움직이는 방출 스피어에 근접한 파티클에 적용되며 5초마다 주기가 반복됩니다. 다른 그레디언트는 파티클이 살아있는 동안 파란색에서 분홍색으로 이어집니다.

이 마스킹 기법을 사용하여 방출 소스가 근처에 있는 모든 파티클에 약간의 가짜 조명 효과를 주는 것을 시뮬레이션합니다.

샘플 2 – 모핑 페이스

모핑 페이스(Morphing Face)는 파티클의 초기 포지션을 설정하고 노멀과 같은 기타 속성도 저장하는 포인트 캐시(Point Cache)의 사용을 보여줍니다. 샘플에서는 Houdini에서 베이크한 포인트 캐시에서 파티클이 무작위로 생성됩니다. 원한다면 포인트 캐시 베이크(Point Cache Bake) 툴(Window/Visual Effects/Utilities/Point Cache Bake Tool)을 사용하여 Unity 메시에서 이 포인트 캐시를 생성할 수도 있습니다.

포인트 캐시 파일이 Unity로 임포트되면 속성당 하나의 텍스처(속성 맵)가 포함된 에셋이 생성됩니다. 그런 다음 포인트 캐시 노드를 사용하여 이 에셋을 레퍼런스하면 모든 속성 맵을 채우고 속성당 하나의 커넥터를 표시합니다. 그 후 이를 Attribute from Map 블록에 추가하여 해당하는 값을 가지고 올 수 있습니다. 위 예에서는 이 포인트 캐시에서 포인트를 무작위로 샘플링하여 파티클을 생성했습니다.

파티클이 생성되면 공간에서 이동하지 않고 노화되거나 사라지지 않으므로 시뮬레이션에서 파티클이 업데이트되지 않습니다(시스템에 업데이트 컨텍스트 없음). 대신에 출력 컨텍스트(위 이미지에서 녹색/빨간색으로 표시된 부분 참고)에서 시간에 따른 마스크만 계산합니다.

이 마스크를 사용하면 작은 비메탈릭(non-metallic) 큐브와 긴 메탈릭 막대의 두 상태를 블렌딩하여 다양한 파티클 파라미터를 제어할 수 있습니다. 뿐만 아니라 정렬된 큐브와 무작위로 놓인 막대 간 방향도 블렌딩됩니다.

또한 이 씬에서는 움직이는 광원을 사용하여 마스크를 애니메이션하는 동안 머티리얼이 변경되는 것을 보여줍니다.

샘플 3 – 나비

나비 샘플에서는 하나의 파티클을 렌더링하는 데 여러 출력을 사용하는 예를 보여줍니다. 이 샘플에서는 중앙의 수직축을 기준으로 맴도는 나비 떼를 시뮬레이션합니다. 각 나비는 하나의 파티클 요소로 정의되며, 업데이트 컨텍스트에서 궤도만 시뮬레이션됩니다. 아래 예에서는 나비 파티클이 빨간색 점으로 강조 표시됩니다.

그 다음 날개와 몸통의 애니메이션은 세 가지 다른 출력 컨텍스트(각 날개에 하나씩, 몸통에 하나)로 계산됩니다.

나비의 방향을 설정할 때 포워드(속도) 벡터와 뒤쪽으로 살짝 기울이는 상향 벡터를 조합하여 사용하므로 몸통이 궤도에 정렬되지 않고 머리가 배보다 상단에 위치합니다. 각 나비마다 임의의 빈도값을 가진 사인(sine)을 사용하여 몸통을 애니메이션합니다. 날개의 각도 또한 동일한 빈도값을 가진 사인(sine)을 사용하여 애니메이션되지만 시간을 약간 오프셋하여 몸통의 제동 및 관성을 시뮬레이션합니다.

샘플 4 – 바람에 흔들리는 풀

바람에 흔들리는 풀(Grass Wind)은 일반적인 파티클과 완전히 다른 파티클의 시뮬레이션을 보여주는 예로, 터레인의 잔디를 보여줍니다. 터레인 데이터에서 생성된 포인트 캐시를 사용하여 터레인 노멀에서 블렌딩된 상향 벡터와 월드 상향 벡터를 적용하여 터레인에 목초지를 생성합니다.

모든 요소는 플레이어의 캐릭터 값을 기반으로 하며 위치, 반지름, 속도 파라미터를 효과에 전달하여 플레이어와 상호작용합니다. .

그 후, 시뮬레이션은 다음과 같은 규칙을 기준으로 이루어집니다.

  • 플레이어 범위 안에 있는 목초는 플레이어의 이동 방향으로 휩니다
  • 이미 휘어진 목초는 더 이상 영향을 받지 않으므로 이러한 목초는 밟아도 영향이 미치지 않습니다
  • 목초는 시간이 지나면서 원래 방향으로 되돌아옵니다

목초가 휘는 모습을 시뮬레이션하기 위해 사용되지 않은 속성인 속도 및 알파에도 값을 저장합니다.

  • 속도는 목초가 휘는 방향을 저장합니다.
  • 알파는 휘어진 상태를 저장합니다. 알파0은 목초가 바로 서 있는 상태이며, 0.0은 완전히 휘어진 상태입니다. 최소값(-2.0)은 0.0과 동일하며 목초를 더 오랜 시간 동안 휜 상태로 유지할 때 사용됩니다.

목초를 밟으면 알파 속성은 최소값(-2.0)이 될 때까지 지정된 속도로 감소합니다. 목초를 밟지 않으면 값이 1.0이 될 때까지 지정된 속도로 다시 증가합니다. 0.0에서 1.0으로 전환될 때 속도 값은 목초가 다시 수직이 될 때까지 점점 줄어듭니다.

밟히고 휘는 동작의 영향을 받지 않는 목초에 대해서는 모두 출력에 추가적인 바람 노이즈를 적용하여 대기 상태일 때 너무 정적이지 않도록 합니다.

샘플 5 – 볼류메트릭 효과

볼류메트릭 샘플은 다소 단순하지만 고해상도 렌더 파이프라인(High Definition Render Pipeline) 조명과 볼류메트릭 포그의 통합을 보여줍니다. 씬은 분할된 환경으로 설정되었으며 배경 하늘은 단순한 회색입니다. 광원은 주황색 및 파란색 두 가지가 사용됩니다. 그림자를 드리우기 위해 각 광원은 실시간 그림자가 활성화되고 카메라를 향하는 하나의 스폿 광원으로 구성됩니다. 광원을 정확하게 시뮬레이션하기 위해 각 광원에 반대 방향을 향하는 또 하나의 스폿 광원을 구성했습니다.

불투명 파티클(Opaque Particles)은 플립북 텍스처를 사용하여 애니메이션화된 소스에서 생성되어 파티클별로 여러 요소를 시뮬레이션합니다. 이를 통해 여섯 배에 이르는 양의 파티클을 사용할 필요 없이 풍부한 질량 표현을 유지할 수 있습니다. 파티클 질량은 노이즈를 사용하여 발달하며 카메라 근처의 위치를 향해 이동합니다.

파티클은 그림자 드리우기가 활성화된 상태로 렌더링되며, 투과도가 적용된 확산 프로파일이 사용되므로 파티클을 통과해 빛이 새어 들어옵니다.

다음은 이 샘플에서 사용한 조명에 대한 요약 영상입니다.

샘플 6 – 포털

Houdini 튜토리얼을 본 후, Unity에서 CG 패키지의 효과를 재연하고 개선 사항을 추가하고자 했습니다. 또한 RiseFX Houdini 데모 릴에서도 영감을 얻었습니다.

영상을 하나씩 차례로 확인해 보면 이 효과는 단일 파티클 시스템, 내부의 왜곡된 원 및 라인 광원 8개로 생성된 조명 릭(Rig)으로 구성되며 모두 플레이 모드에서 회전합니다.

파티클은 생성 시 빠른 코로나와 충돌 파티클이라는 두 가지 그룹으로 분류됩니다. 물론, 모든 파티클은 지면과 충돌합니다.

샘플 7 – AR 레이더

AR 레이더는 플로트 [0...1] 파라미터인 Initialize를 통해 하나의 타임라인에 내부 시퀀싱과 외부 시퀀싱을 사용할 수 있는, 여러 시스템이 함께 작동하는 복잡한 효과를 선보입니다.

이 파라미터는 다음과 같이 그래프에서 여러 번 사용되며 그리드를 초기화할 때 배치 효과를 제어합니다.

  • 0~0.1: 깜빡이는 점 제어
  • 1~1.0: 그리드 및 환경 배치

적함(Enemy ships)은 기본 효과의 배치가 끝나면 타임라인 VFX 전용 트랙을 사용하여 트리거됩니다. 이 트랙은 이벤트를 여러 번 전송하여 주변에 적함을 생성합니다.

중앙에서 깜빡이는 점은 포지션 파라미터 바인더(Position Parameter Binder)로 제어되어 씬 점 광원과 연결됩니다.

다음은 관련 기술 요약 영상입니다.

샘플 8 – 복셀화된 터레인

복셀화된 터레인(Voxelized Terrain)은 하이트필드(heightfield) 시뮬레이션으로 각각 큐브로 렌더링되는 파티클로 구동됩니다.

각 파티클은 2D 그리드(256×256)상의 점이며 오브젝트 공간 좌표를 기반으로 한 2D 텍스처를 샘플링합니다. 좌표를 조정하여 터레인을 확대/축소하고 상하좌우로 회전할 수 있습니다.

이 하이트맵을 샘플링하고 Scale.y에 값을 저장하면 모든 포인트를 변형하여 실제 샘플링된 높이를 설정하고, 높이에 따라 큐브의 컬러를 지정하고, 머티리얼 프로퍼티(예: 물의 평활도)를 조정할 수 있습니다.

수위뿐 아니라 입력 높이(텍스처로부터 읽기) 및 최종 고도도 조정할 수 있습니다. 이와 같은 모든 파라미터는 글로벌 스크립트(VoxelizedTerrainController.cs)에 표시되고 제어됩니다.

이 스크립트는 마우스/키보드 이벤트를 처리하여 카메라를 상하좌우로 움직이고 확대/축소 및 회전하며, 모든 파라미터를 Visual Effect 컴포넌트로 설정합니다. 이 스크립트는 파라미터의 스트링 값을 캐시하고 Shader.PropertyToID()에서 정수 인덱스를 반환하는 유용한 ExposedParameter 구조를 사용합니다.

dist = Mathf.Clamp(dist, CameraMinMaxDistance.x, CameraMinMaxDistance.y);

           ViewingCamera.transform.position = CameraRoot.transform.position + dist * dir;



           VisualEffect.SetVector2(Position, m_Position);

           VisualEffect.SetVector2(WorldSize, m_WorldSize);



           // Sliders

           float inputHeightMapScale = Mathf.Lerp(InputHeightLevel.x, InputHeightLevel.y, InputHeightMapScaleSlider.value);

           float elevation = Mathf.Lerp(ElevationRange.x, ElevationRange.y, ElevationSlider.value);

           float waterElevation = Mathf.Lerp(WaterElevationRange.x, WaterElevationRange.y, WaterElevationSlider.value);



           CameraRoot.transform.position = new Vector3(CameraRoot.transform.position.x, waterElevation, CameraRoot.transform.position.z);

           ViewingCamera.transform.LookAt(CameraRoot.transform);



           VisualEffect.SetFloat(InputHeightMapScale, inputHeightMapScale);

           VisualEffect.SetFloat(Elevation, elevation);

           VisualEffect.SetFloat(WaterElevation, waterElevation);

샘플 9 – 지니

지니(Genie) 효과는 파라미터 일부를 공유하고 내부 시퀀싱을 사용하여 서로 연결되는 여러 시스템들로 구성된 결과물입니다. 이 샘플은 간단한 스크립트를 사용하여 요술 램프를 클릭하면 효과가 켜지고 꺼지도록 합니다.

이 씬에는 램프에서 마법의 기운이 흘러 나오도록 하는 베지어(Bezier) 점을 정의하는 점 4개가 있습니다. 파티클을 구동하기 위해 속도를 사용하는 대신에 파티클 전체 수명에 걸쳐 위 베지어를 따르는 포지션과 벡터 필드 노이즈에서 계산된 오프셋을 사용합니다.

베지어의 마지막 점은 지니의 포지션을 지정하며 3D 사인 곡선 애니메이션을 사용하여 시각 효과 내에서 애니메이션됩니다. 이렇게 하면 베지어의 마지막 점뿐 아니라 지니의 바디와 눈을 구동합니다.

이 씬은 단일 타임라인 및 전후 컨트롤 릭을 사용하여 설정되었습니다. VFX 이벤트 트랙을 사용하여 파티클 생성의 시작과 중지를 제어합니다. 또한, 이 타임라인은 시네머신 카메라 블렌딩뿐 아니라 간단한 컨트롤 릭도 제어합니다.

기타 시각 효과 및 향후 샘플 공개 계획

새로운 샘플은 모두 비주얼 이펙트 그래프 패키지(5.x.x-프리뷰)의 2019.1 릴리스 트랙에 포함됩니다. 다시 말해서 현재까지 제공된 모든 샘플은 새 릴리스 트랙에 포함되지만 아쉽게도 2018.3 샘플에 업데이트되는 내용은 더 이상 없습니다. 2019.1용 새 샘플 공개를 가장 빠르게 확인할 수 있도록 TwitterFacebook을 계속 지켜봐 주시기 바랍니다.

뿐만 아니라, 곧 Fontainebleau 데모FPS 샘플 저장소에서도 프로젝트에 영감을 줄 시각 효과, 기타 제작 사례 및 솔루션을 제공할 예정입니다.

조만간 더 다양한 시각 효과를 가지고 돌아오겠습니다!

2019년 3월 6일 엔진 & 플랫폼 | 12 분 소요

Is this article helpful for you?

Thank you for your feedback!

다루는 주제