버추얼 텍스처 시스템에는 크게 두 종류의 GPU 메모리 할당이 있습니다. 바로 페이지 테이블 메모리와 물리적 메모리 풀입니다.
- 페이지 테이블 메모리(Page Table Memory) 는 텍스처 좌표에서 텍스처 데이터로 인디렉션을 제공하며 온디맨드 방식으로 할당됩니다. 이 메모리는 시간에 따라 증가할 수 있고, 보통 모든 콘텐츠가 해제되지 않는 한 메모리에서 해제되지 않습니다. 사용자는 이 메모리 타입에 대해 컨트롤할 수 없습니다.
- 물리적 메모리 풀(Physical Memory Pool) 은 현존 상주하는 텍스처 데이터를 포함하며 여러 개별 풀로 구성됩니다. 버추얼 텍스처 시스템에서 보이는 각 텍스처 포맷에는 각자 해당하는 메모리 풀이 있습니다. 각 풀은 해당하는 포맷에 따라 버추얼 텍스처를 최초로 인스턴스화할 때 할당됩니다. 풀의 크기는 고정되어 있어 증가하지 않습니다. 사용자는 각 풀의 크기를 컨트롤할 수 있습니다.
이 문서에서는 버추얼 텍스처의 물리적 메모리 풀을 정의하고 디버깅하는 방법을 설명합니다.
물리적 메모리 풀의 동작 이해하기
물리적 메모리 풀은 각각의 페이지로 구성됩니다. 페이지마다 하나의 버추얼 텍스처 타일에 대한 데이터가 들어 있습니다. 풀은 사용된 지 가장 오래된(least recently used) 캐시 역할을 합니다. 버추얼 텍스처 시스템에서 타일을 요청하면 타일이 풀의 가용 페이지로 스트리밍되거나 렌더링됩니다. 사용 가능한 페이지가 없으면 확인한 지 가장 오래된(least recently seen) 타일이 포함된 페이지를 삭제하여 새 페이지를 위한 공간을 확보합니다.
버추얼 텍스처 메모리 풀에 들어갈 수 있는 것보다 뷰에 보이는 버추얼 텍스처 타일의 수가 더 많으면 시스템이 뷰를 올바르게 렌더링할 수 없습니다. 이 경우 버추얼 텍스처 메모리 풀 크기를 데이터 사용에 맞춰 조정해야 합니다.
물리적 메모리 풀 환경설정
버추얼 텍스처링의 메모리 풀 크기는 프로젝트 세팅(Project Settings) 의 엔진(Engine) > Virtual Texture Pool 에서 설정됩니다. 이러한 세팅에는 2개의 환경설정 배열이 포함되어 있습니다.

- 고정된 풀(Fixed Pools) 은 마지막에서 처음으로 반복작업하는 시리얼라이즈된 세팅으로, 처음에 찾은 일치하는 환경설정을 사용합니다. 이러한 세팅은 에디터 세션 간에 유지됩니다.
- 트랜션트 풀(Transient Pools) 은 런타임에 탐지되고 풀 자동 증가(Pool Auto Grow) 시스템에서 사용되는 환경설정입니다. 버추얼 텍스처 물리적 풀은 풀에서 환경설정 세팅을 검색하기 전에 환경설정을 검색하여 일치하는 환경설정을 찾습니다. 트랜션트 풀은 현재의 에디터 세션에서만 유지되지만 쿠킹된 프로젝트에 필요한 고정된 풀 크기의 양호한 추정치로서 시리얼라이즈된 풀에 복사될 수 있습니다.
풀 설명은 고정된 풀 배열 세팅에 저장되고 각각의 설명에는 텍스처 포맷(Texture Format) 및 타일 크기(Tile Size) 가 포함됩니다. 아래 예시에는 텍스처 포맷 DXT1, DXT5, BC5 각각에 대한 구체적인 풀 설명이 있습니다.

아래 예시와 같이 고정된 풀 에서 인덱스를 확장하고 크기(MB)(Size in Megabyte) 를 설정하여 DXT1이 포함된 버추얼 텍스처 메모리 풀을 100MB(메가바이트)로 설정할 수 있습니다. 메모리 풀의 크기는 대략적인 숫자이며, 시스템은 100MB미만의 크기가 가장 크며 페이지 수(정수)에 맞는 제곱수를 풀 크기로 할당합니다.

환경설정에 해당하는 항목이 없는 포맷은 디폴트 크기(MB)(Default Size in Megabyte) 의 풀 크기를 사용합니다.
또는 텍스처 포맷이 할당되지 않은 고정 풀 에 항목을 정의하여 디폴트 풀 크기를 표현할 수 있습니다.
일부 풀에는 각자 자체 포맷이 있는 여러 레이어가 포함되어 있습니다. 이는 대부분의 런타임 버추얼 텍스처 구성에 해당됩니다. 이 경우 풀 설명에서 포맷(Format) 배열이 올바르게 지정되어야 합니다. 예를 들어 머티리얼에 베이스 컬러(Base Color), 노멀(Normal), 러프니스(Roughness), 스페큘러(Specular) 타입을 사용하는 런타임 버추얼 텍스처는 2개의 DXT5 텍스처를 사용하여 데이터를 저장합니다. 구성은 다음과 같습니다.

고정된 풀 환경설정 항목에는 다음 세팅도 있습니다.
메모리 풀 환경설정 세팅 | 설명 |
---|---|
사이즈 스케일 허용(Allow Size Scale) | 확장성 콘솔 변수 r.VT.PoolSizeScale 을 통해 풀 메모리 크기에 추가 스케일 인수를 적용합니다. |
레지던시 밉맵 바이어스 활성화(Enable Residency Mip Map Bias) | 이 풀이 과등록되었을 때 버추얼 텍스처에 밉맵 바이어스를 적용하는 비헤이비어를 활성화합니다. |
최소 스케일된 크기(MB)(Min Scaled Size in Megabyte) | r.VT.PoolSizeScale 에 대한 콘솔 변수 값이 적용된 후 풀에 할당할 크기의 하한을 설정합니다. |
최대 스케일된 크기(MB)(Max Scaled Size in Megabyte) | r.VT.PoolSizeScale 에 대한 콘솔 변수 값이 적용된 후 풀에 할당할 크기의 상한을 설정합니다. |
에디터에서 풀 자동 증가(Pool Auto Grow in Editor) 세팅이 활성화되면 가장 높은 풀 레지던시를 수용하기 위해 풀 크기가 증가합니다. 풀 레지던시가 100%인 것으로 탐지되면 크기가 증가하고 알림 팝업을 통해 에디터에서 이 변경 사항을 알 수 있습니다. 자동으로 증가한 풀 크기에 대해 세팅에서 탐지된 변경 사항은 트랜션트 풀 배열 환경설정에 저장됩니다.
이러한 세팅은 에디터 세션 간 프로젝트 세팅에 유지되지 않고 손실됩니다. 즉, 프로젝트에 과등록된 풀이 있고 에디터에서 풀 자동 증가(Pool Auto Grow in Editor) 가 활성화된 경우, 에디터를 시작할 때마다 풀이 증가하는 것을 확인할 수 있습니다. 에디터 세션 간에 유지되도록 트랜션트 풀 세팅과 고정된 풀 세팅 간에 항목을 복사하고 붙여넣어 이를 방지할 수 있습니다.
에디터에서 풀 자동 증가 세팅은 쿠킹된 빌드에 영향을 미치지 않지만 r.VT.PoolAutoGrow
를 설정하여 쿠킹된 빌드에서 풀 크기를 조정할 수 있습니다.
물리적 메모리 풀의 레지던시
버추얼 텍스처 메모리 풀의 현재 사용량을 레지던시(Residency) 라고 합니다. 풀의 모든 페이지가 현재 보이는 타일에 할당되면 레지던시는 100%가 됩니다.
레지던시가 100%면 풀이 과등록되고 표시된 타일의 데이터를 드롭합니다. 이 경우 원치 않는 IO가 발생하여 텍스처 데이터가 메모리에서 반복적으로 로드 및 삭제되면서 화면이 깜빡거리게 됩니다.
메모리 풀이 과등록되면 화면 알림이 표시되는 기능을 활성화할 수 있습니다. 알림을 활성화하는 콘솔 명령어는 r.VT.Residency.Notify 1
입니다.

이 경고는 환경설정 파일에서 메모리 풀 크기를 늘리거나 버추얼 텍스처 또는 머티리얼을 변경해야 한다는 의미입니다. 이러한 유형의 문제를 해결하는 팁은 아래 섹션을 참조하세요.
레지던시 밉맵 바이어스
bEnableResidencyMipMapBias
세팅을 활성화한 상태로 풀을 환경설정하면 과등록 시 레지던시를 줄일 수 있도록 밉맵 바이어스가 설정됩니다. 이 설정은 버추얼 텍스처 렌더링 해상도를 낮추는 대신 원치 않는 IO 발생과 화면 깜빡임을 막아 줍니다.
레지던시 과등록이 아주 드물게 발생하여 굳이 메모리를 할당할 필요가 없다면 이렇게 설정하는 것이 유용합니다. 화면에 표시되는 과등록 메시지에는 적용된 밉맵 바이어스가 포함됩니다.
레지던시에서 나오는 밉맵 바이어스는 글로벌입니다. 모든 물리적 메모리 풀의 최대 현재 바이어스는 모든 버추얼 텍스처 샘플링에 적용됩니다.
물리적 메모리 풀 헤드업 디스플레이
메모리 풀 크기를 적절하게 설정하는 것은 레지던시를 모니터링하고 과등록 발생을 줄이는 데 중요합니다. 화면의 헤드업 디스플레이(HUD)를 사용하여 각 버추얼 텍스처의 물리적 메모리 풀에 대해 현재 레지던시를 볼 수 있습니다.
활성화하려면 r.VT.Residency.Show 1
을 사용합니다.

버추얼 텍스처의 물리적 메모리 풀 HUD는 각 텍스처 포맷의 현재 레지던시와 할당된 메모리를 보여줍니다.

화면의 각 그래프는 버추얼 텍스처의 물리적 메모리 풀을 나타냅니다. 그래프에는 세 종류의 선이 있습니다.
- 빨간색 선은 현재 풀 점유율을 0~100%로 나타냅니다.
- 노란색 선은 고정된 풀 점유율을 0~100%로 나타냅니다.
- 이 선은 잠김으로 표시된 페이지의 점유율을 보여줍니다. 모든 버추얼 텍스처에는 보통 잠긴 페이지가 하나씩 존재합니다. 로드된 버추얼 텍스처 에셋이 아주 많을 경우, 버추얼 텍스처가 보이지 않아도 사용 가능한 풀 공간이 줄어들 수 있습니다.
- 초록색 선은 레지던시를 100% 미만으로 유지하기 위해 적용된 밉맵 바이어스를 나타냅니다.
물리적 메모리 풀의 레지던시 디버깅
아래는 버추얼 텍스처 메모리 풀이 과등록되었을 때 디버깅과 콘텐츠 확인을 진행하는 영역입니다.
풀 메모리 크기
버추얼 텍스처 풀 크기의 경우 아래와 같은 사항을 확인하는 것이 좋습니다.
- 풀 크기가 예상되는 버추얼 텍스처 데이터 작업 세트 전체를 감당할 수 있을 만큼 여유로운지 확인합니다.
페이지 크기가 크면 풀 크기도 커야 합니다. 예를 들어, 텍스처 포맷이
PF_A32B32G32R32F
인 풀은PF_DXT1
인 풀보다 필요한 메모리가 훨씬 큽니다. 마찬가지로 레이어가 여러 개 있는 풀도 더 많은 메모리가 필요합니다. - 렌더링 출력 해상도가 높으면 풀 크기도 커야 합니다.
- 출력 해상도가 높으면 보통 해상도 밉 타일도 커져야 합니다.
- 타일 크기가 크면 풀 크기도 커야 합니다.
- 스트리밍 버추얼 텍스처의 디폴트 타일 크기는 128텍셀입니다. 하지만 이 값은 오버라이드될 수 있습니다.
- 런타임 버추얼 텍스처의 타일 크기는 최대 1024텍셀입니다. 이보다 타일 크기가 크면 풀에서 메모리 낭비가 발생합니다.
과등록
음수 밉 바이어스를 적용하는 것은 버추얼 텍스처 샘플링 시 과등록을 유발하는 원인 중 하나입니다. 전체적으로 해상도가 높은 밉을 샘플링하려면 더 많은 풀 메모리가 필요합니다. 음수 밉은 머티리얼 그래프에서 텍스처 샘플 노드의 밉 레벨이나 바이어스를 명시적으로 설정할 때 발생합니다.
그레이디언트가 0인 텍스처를 샘플링하는 경우 UV가 트라이앵글이나 메시에 따라 변하지 않는데, 이렇게 예상치 못한 원인으로도 과등록이 발생할 수 있습니다. 아래의 머티리얼 그래프 스니펫이 바로 그 예시입니다. 이 경우 Runtime Virtual Texture Sample 노드의 밉 값 세팅 'Ignore Input WorldPosition'을 사용해 문제를 해결할 수 있습니다.

콘솔 명령어 r.VT.DumpPoolUsage
를 사용하면 밉 바이어스나 기타 문제로 인해 예상보다 풀 공간을 더 많이 차지하는 텍스처를 찾는 데 도움이 됩니다. 이 명령어는 각 버추얼 텍스처 에셋이 현재 각 메모리 풀에 할당한 페이지의 수를 덤프합니다. 이 덤프는 페이지 수를 기준으로 정렬되므로 내용이 올바른지 살펴보려면 첫 번째 항목을 확인해야 합니다.
아래 덤프에서는 첫 번째 항목이 다른 항목보다 훨씬 높습니다. 따라서 모든 밉 바이어스 문제에 대해 T_Ground_Sand_F_basecolor_CANYON
을 참조하는 머티리얼을 확인해야 합니다.
PhysicaPool: [0] DXT1 (136x136):
T_Ground_Sand_F_basecolor_CANYON 1912
T_Rock_Quarry_Y_RAOD 418
ubulehofw_8K_Albedo 324
pcciQ_4K_Albedo 248
T_Rock_Cliff_D_RAOD 187
noise_directional_3 115
T_column_260_B_W 97
T_column_260_B_goldA_RMAOO 97
T_column_260_B_goldA_C 96