나이아가라의 대규모 월드 좌표 지원

나이아가라의 대규모 월드 좌표 시스템 사용 방법을 살펴봅니다.

Choose your operating system:

Windows

macOS

Linux

이제 언리얼 엔진 전반에 걸쳐 대규모 월드 좌표(Large World Coordinates) 를 구현할 수 있게 되었습니다. 메인 엔진에서 구현된 내용을 살펴보려면 대규모 월드 좌표 페이지를 참고하세요. 간단하게 요약하자면 FVector 데이터 타입은 이제 float 대신 `double`이 사용됩니다.

나이아가라에서의 구현은 메인 엔진에서의 구현과 다릅니다. 계산은 CPU에서든 GPU에서든 효율적으로 수행되어야 하므로 `double`로 작업하는 데 제한이 있습니다. 대신에 나이아가라에서는 새로운 방식을 통해 위치 데이터를 저장합니다.

충분히 큰 규모의 월드는 타일 그리드로 나뉩니다. 공간에서의 위치를 생각할 때 타일 단위 내 상대적 위치와 월드에서의 타일 위치를 가집니다. 이것이 나타내는 모양을 개념적으로 표현하면 아래의 다이어그램과 같습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

이전에 나이아가라 위치는 벡터로 교체될 수 있었으며, 월드 원점에서 멀어지는 방향 및 거리로 정의되었습니다. 이제는 의미있는 정보를 확보하기 위해 이미터가 있는 타일에 대해 상대적인 이미터의 위치를 지정하는 추가 데이터가 필수입니다.

UE5에서는 원점에 대해 상대적인 위치뿐만 아니라 시스템이 속한 타일의 정보를 모두 저장하기 위해 새로운 데이터 포맷이 필요합니다. 이러한 방식을 통해 다른 벡터 타입과 이 추가 데이터를 보유한 위치를 구분할 수 있습니다.

UE4 및 UE5의 위치 데이터

UE4와 UE5가 다른 중요한 점은 파티클의 위치 데이터, 즉 `Particles.Position`을 저장하는 방식입니다.

UE4

UE5

Particles.Position 타입

벡터

위치

로컬 스페이스 이미터

`Particles.Position`은 게임에서 나이아가라 시스템의 원점에 대해 상대적입니다

`Particles.Position`은 게임에서 나이아가라 시스템의 원점에 대해 상대적입니다(변경 안 됨)

월드 스페이스 이미터

`Particles.Position`은 게임의 원점(0,0,0)에 대해 상대적입니다

`Particles.Position`을 활성화하면, 시스템의 위치에 대해 상대적입니다. 소규모 좌표의 경우 이는 여전히 게임의 원점이며, 대규모 좌표의 경우 임의의 숫자일 수 있습니다.

나이아가라의 대규모 월드 좌표의 활성화 또는 비활성화 방법

프로젝트의 대규모 월드 좌표

기본적으로 새로운 프로젝트에서는 대규모 월드 좌표가 켜집니다. 시스템은 UE5에서 프로젝트를 열 경우 해당 프로젝트를 자동으로 변환합니다.

프로젝트가 대규모 월드 좌표 지원이 필요한 만큼 크지 않은 경우 편집(Edit) > 프로젝트 세팅(Project Settings) 에서 완전히 끌 수 있습니다. 이렇게 하려면 플러그인(Plugins) > 나이아가라(Niagara) 에서 해당 프로젝트에 대한 대규모 월드 좌표 시스템 지원(System Support Large World Coordinates) 세팅으로 이동하여 비활성화합니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

시스템의 대규모 월드 좌표

프로젝트에 대한 대규모 월드 좌표는 켜고 특정 개별 시스템에 대해서는 비활성화해야 할 수 있습니다. 이 경우 나이아가라 에디터(Niagara Editor)에서 나이아가라 시스템을 편집할 수 있습니다. 시스템 프로퍼티(System Properties)렌더링(Rendering) 섹션에서 대규모 월드 좌표 지원 을 비활성화할 수 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

나이아가라에서 대규모 월드 좌표를 테스트하는 방법

UE4에서 UE5로 프로젝트 파일을 처음 업데이트하는 경우 또는 해당 시스템의 테스트를 시작하는 경우, 해당 나이아가라 시스템이 대규모 월드 좌표에서 적절하게 동작하는지 유효성을 검사하는 것이 좋습니다. 나이아가라 시스템이 대규모 월드 좌표에서 제대로 동작하는지 테스트하기 위해서는 시스템을 첫 번째 타일 밖으로 이동시켜야 합니다. 이렇게 하려면 아래에 설명된 것과 같이 다양한 방식을 사용할 수 있습니다.

이펙트를 아주 멀리 이동

이펙트를 원점에서 아주 멀리 이동시킨 후 이펙트를 플레이하고 동작에 대한 유효성을 검사할 수 있습니다. 이는 엔진 코드 자체를 전혀 변경하지 않고 테스트할 수 있는 유일한 방법입니다. 예를 들어 시스템을 원점에서 3,000,000유닛만큼 멀리 이동시키고, 이 시스템을 원점 타일 밖에 있는 타일에 배치할 수 있습니다.

타일 크기에 대한 상수 변경

상수 정의에 있는 대규모 월드 좌표 타일에 대한 타일 크기를 변경할 수도 있습니다. 예를 들어 Engine/Source/Runtime/Core/Private/Misc/LargeWorldRenderPosition.cpp`에서 UE_LWC_RENDER_TILE_SIZE`를 10유닛 정도의 매우 작은 크기로 변경합니다. 이제 해당 레벨의 이펙트를 원점에서 10유닛 이상 떨어지도록 멀리 배치할 경우 이펙트는 새로운 타일에 포함되게 됩니다.

기존 프로젝트 업데이트

HLSL의 Particles.Position

프로젝트의 HLSL에서 커스텀 스크립트를 작성한 경우 대규모 월드 좌표에서 올바르게 작동하려면 이러한 스크립트를 업데이트해야 합니다. 이전 버전에서는 HLSL을 사용하여 `Particles.Position`을 고정된 값으로 직접 설정해야 했습니다. 이러한 작업은 대규모 월드 좌표에서 작동하지 않습니다.

대신, 해당 에셋에 대한 대규모 월드 좌표 지원을 비활성화하거나 월드스페이스 벡터를 위치로 변환할 수 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

어떤 타일에 속해 있는지 확인해야 하는 경우 해당 정보는 `Engine.Owner.LWCTile`에 저장되어 있습니다.

커스텀 모듈

나이아가라 스크립트 에디터(Niagara Script Editor) 또는 스크래치 패드(Scratch Pad) 를 사용하면 자체 커스텀 모듈을 생성할 수 있습니다. 이전 버전에서 이미 커스텀 모듈을 생성한 경우 대규모 월드 좌표를 사용하여 프로젝트를 변환하면 명시적으로 작동되지 않을 수 있습니다.

그 이유는 타일 정보를 포함하고 있는 위치 데이터와 타일 정보를 포함하고 있지 않은 노멀 벡터 간의 차이점 때문입니다. Particles.Position`과 같은 핵심 파라미터는 자동으로 타입 position`으로 변환되지만, 이와 연결된 커스텀 벡터 입력은 자동으로 변환되지 않습니다.

다음 예시에서 박스 원점(Box Origin)Particles.Position 을 디폴트 바인딩으로 사용합니다. 단, 그 자체로는 position 타입이 아닙니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

이전 버전과의 호환성을 유지하기 위해 기존 연결을 유지하고 위치 타입을 노멀 벡터 타입으로 변환합니다.

기존 벡터 입력 타입 변경

나이아가라 스크립트(Niagara Script)에 기존 모듈이 있는 경우 일부 파라미터를 position 타입으로 업데이트할 수 있습니다. 기존 벡터 입력 또는 출력 타입을 위치 타입으로 변경하려면 다음 단계를 따릅니다.

  1. 나이아가라 스크립트 에디터 에서 모듈 스크립트를 엽니다.

  2. 파라미터(Parameter) 탭에서 변경하려는 타입의 파라미터를 우클릭합니다.

  3. 컨텍스트 메뉴에서 타입 변경(Change Type) > 위치(Position) 를 선택합니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

파라미터를 위치 타입으로 변경하여 다른 타입의 파라미터와 연결되는 경우 핀 연결이 이슈가 될 수 있습니다. 이렇게 하면 다음에 수행할 작업을 결정할 수 있습니다. 즉, 다른 파라미터 타입으로 변경할지 데이터를 하나의 타입에서 다른 타입으로 변환할지 결정할 수 있습니다.

이 스크립트에서 소유한 파라미터만 변경할 수 있습니다. 외부에서 파라미터를 상속받는 경우 해당 파라미터가 잠기고 해당 타입은 변경될 수 없게 됩니다.

노드 그래프에서 벡터와 위치 간 변환

노드 그래프에서 vector`와 position`을 함께 연결하는 경우 시스템은 Position-> Vector 또는 Vector-> Position 변환 노드에 추가합니다. 하지만 원점 타일 외부에서 이를 수행할 경우 대규모 월드 트랜스포메이션에 상관없이 해당 값을 복사한다는 점에 유의해야 합니다. 이 경우 중요한 정보가 손실될 수 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

위치 타입을 월드스페이스 벡터로 변환하려면 Position to Vector 함수를 사용할 수 있습니다. 반대로 월드스페이스 벡터에서 위치로 변환하려는 경우에는 Vector to Position 을 사용할 수 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

위치에서 벡터로 또는 그 반대로 변환하는 경우에는 항상 잠재적인 데이터 손실이 발생할 수 있습니다. 이 경우 원점 타일 외부에서 정확성이 떨어지거나 예측할 수 없는 동작이 일부 발생할 수 있습니다. 안전을 위해서 처음부터 끝까지 변환 없이 위치를 사용해야 합니다. 월드 스페이스로의 변환은 데이터 인터페이스 또는 렌더러에서만 수행하는 것이 좋습니다.

파티클 데이터 인터페이스 익스포트

파티클 익스포트(Export Particle) 데이터 인터페이스를 사용하여 위치 데이터를 블루프린트로 전송할 수 있습니다. 이러한 작업을 이전에 이미 진행한 경우 대규모 월드 좌표에 대한 블루프린트를 업데이트해야 합니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

Event Receive Particle Data 노드에 시뮬레이션 위치 오프셋(Simulation Position Offset) 이라는 파라미터가 있습니다. 이 파라미터는 속해 있는 타일에 대한 오프셋 데이터를 저장합니다. 스크립트의 마지막 부분에 이 파라미터를 시뮬레이션 위치에 추가하여 시뮬레이션 스페이스에서 월드 스페이스로 다시 변환할 수 있습니다.

다이내믹 머티리얼 파라미터

위치 데이터는 이러한 정보를 전달하지 않는 벡터에 직접 연결할 수 없는 타일 오프셋에 대한 추가 정보를 전달합니다. 렌더러에 해당 머티리얼을 바인딩하기 위해 동적 입력을 사용하여 머티리얼에 위치 데이터를 익스포트하도록 프로젝트를 구성하는 경우 대규모 월드 좌표에서는 제대로 동작하지 않습니다. 이를 해결하기 위해서는 위치 데이터를 월드 스페이스 벡터로 변환할 수 있습니다.

익스포트된 위치 데이터를 머티리얼로 전환

대규모 좌표의 경우 속해 있는 타일에 대한 추가 오프셋 정보가 손실되어 대규모 좌표에 대한 오버플로가 발생할 수 있습니다.

사용할 머티리얼 바인딩이 아직 있는 경우 `Engine.Owner.LWCTile`에 연결하여 이 오프셋 정보를 다시 추가할 수 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

머티리얼 자체에서 ConvertNiagaraPositionToWorldspace 머티리얼 함수를 사용하여 시뮬레이션 위치에 타일 오프셋을 추가할 수도 있습니다.

이미지를 클릭하면 최대 크기로 볼 수 있습니다.

커스텀 데이터 인터페이스

월드 스페이스 위치에서 작동하는 함수를 포함하고 있는 커스텀 데이터 인터페이스를 생성한 경우 이 인터페이스를 업데이트합니다.

필요에 따라 입력 및 출력에 대해 FVector 대신 FNiagaraPosition 타입을 사용하도록 기존 함수를 대체합니다. `UNiagaraDataInterface::UpgradeFunctionCall`을 오버라이드하여 기존 함수 사용 방식을 업데이트할 수 있습니다.

시뮬레이션 위치를 변환하려면 다음과 같이 시스템 인스턴스에서 헬퍼 오브젝트를 구하면 됩니다.

    FNiagaraLWCConverter LWCConverter = SystemInstance->GetLWCConverter();

GPU 데이터 인터페이스 함수의 경우 셰이더 컨텍스트에 공급되는 `FNiagaraDataInterfaceArgs`에서 시스템의 대규모 월드 좌표 타일을 구할 수 있습니다. 이에 대한 예시가 필요한 경우 카메라 데이터 인터페이스와 같은 기존 사용 방식을 확인하면 됩니다.

커스텀 렌더러

위치 데이터를 읽는 커스텀 렌더러 또한 업데이트해야 합니다. 데이터 인터페이스와 유사하게 시스템 인스턴스에서 컨버터를 구할 수 있습니다. 유일한 차이점은 로컬 스페이스 이미터(localspace emitter) 에 대한 렌더링 여부 또한 확인해야 한다는 것입니다.

    FNiagaraLWCConverter LwcConverter = SystemInstance->GetLWCConverter(bIsLocalSpaceEmitter);

읽는 모든 파티클 위치는 다음을 사용하여 월드스페이스로 변환할 수 있습니다.

    FVector WSPos = LwcConverter.ConvertSimulationPositionToWorld(SimPos);

이것이 구현된 방법에 대한 예시는 기존의 나이아가라 렌더러를 참고하세요.