텍스처 지원 및 설정

엔진과 하드웨어적인 측면 둘 다에 있어서의 텍스처 지원 관련 정보입니다.

Windows
MacOS
Linux

디지털 프로젝트의 메모리 사용량에 있어 큰 부분을 차지하는 것 중 하나는, 사용되는 텍스처의 크기와 양에서 옵니다. 다행히도 언리얼 엔진 4 에는 모든 프로젝트에 걸쳐 사용되는 텍스처 크기를 비파괴적으로 줄이는 데 사용되는 매우 탄탄한 시스템이 있습니다. 다음 부분에서 이 시스템을 살펴보고, 이를 통해 프로젝트의 텍스처 메모리 요구량을 줄이는 법을 알아보겠습니다.

텍스처 해상도

언리얼 엔진 4 는 1x1 에서 .ini 파일에 약간의 수정을 통해 8192x8192 까지의 텍스처 해상도를 지원합니다. 현재의 DirectX 비디오 어댑터와 게임 콘솔들은 1x1 에서 2048x2048 까지, 그리고 최대 8192x8192 까지의 다양한 텍스처 해상도를 지원하고 있습니다. 특정 하드웨어 장치에 의해 지원되는 최고 텍스처 해상도는 제조 업체, 모델, 가용 텍스처 메모리에 따라 다릅니다. 언리얼 엔진 4 에는 월드 지오메트리나 유저 인터페이스같은 다양한 영역에 렌더링되는 텍스처 해상도 관리용 기능 및 설정이 다수 있습니다.

엔진 텍스처 해상도 한계

언리얼 엔진 4 는 텍스처 밉의 최대 수를 13 으로 제한하는 것을 기본으로 하고 있습니다. 이것은 렌더링 가능한 최대 텍스처의 크기를 사실상 8192 으로 제한합니다 (1x1 에서 8192x8192 까지가 14 밉입니다).
즉 8192 텍스처를 임포트해도 4096 의 mip1 까지만 렌더링된다는 부작용이 있습니다. 엔진의 소스 파일에서 13 으로 기본 설정된 상수 값 MAX_TEXTURE_MIP_COUNT 는 8192 텍스처 렌더링을 지원하기 위해 14 로 변경 가능합니다. 이 상수는 다음의 소스 파일에 정의되어 있습니다 (2009년 3월 이후 버전이며, 다른 QA 버전의 경우 별도로 확인하시기 바랍니다).

Src\D3D10Drv\Src\D3D10Device.cpp   
Src\Engine\Inc\RHI.h   
Src\Engine\Inc\UnTex.h   
Src\Engine\Src\RHI.cpp   
Src\Engine\Src\TextureCube.cpp

UE 4.8 이후 프로젝트의 BaseDeviceProfiles.ini 파일에 다음 텍스트를 추가하고 MaxLODsize 를 8192 로 설정해 주면 C++ 코드 변경 없이도 8192 까지의 텍스처를 사용할 수 있습니다.

[/Script/Engine.TextureLODSettings]
TextureLODGroup_World=(MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point)

크기를 늘리고자 하는 섹션을 추가했으면, 파일을 저장하고 에디터를 재시작합니다. 에디터 재시작시 8192 크기로 임포트된 텍스처는 이제 LOD 1 크기가 4096 으로 제한되지 않고 8192 로 표시됩니다. 다음 예제 이미지에서 프로젝트에 BaseDeviceProfiles.ini 파일을 수정하여 크기가 최대 8192 인 텍스처 사용을 가능하도록 했습니다. 텍스처 Texture_8k_Test 가 로드되면 텍스처의 임포트된 크기와 표시되는 크기 모두 8192 임을 볼 수 있습니다.

이미지를 클릭하면 원본을 확인합니다.

압축된 텍스처 메모리 요구량

DXT 는 픽셀들을 팔레트 색상 및 보간 색상을 가진 4x4 블록으로 묶는 것을 기반으로 하는, 손실 압축을 사용합니다. 그 결과 8:1 DXT1 및 4:1 DXT5 는 불변 압축 파일 크기가 됩니다. 비디오 메모리 및 텍스처 풀의 리소스는 특정 플랫폼이나 하드웨어에 대해 고정되어 있기 때문에, 텍스처의 해상도와 리소스의 사용 사이에 균형이 이루어져야 합니다. 아래의 표는 완전한 밉(1x1 에서 완전 native mip0 까지)을 가진 여러가지 일반적인 해상도에서의 DXT1 과 DXT5 에 대한 메모리 요구량의 목록입니다. 메모리 요구량은 텍스처 해상도 비율의 상수에 가까운 배수이며, DXT5 의 메모리 요구량은 DXT1 의 두 배에 가깝다는 점에 유의하시기 바랍니다.

압축 비율에 대한 해상도는 상수이므로, 이 표에 기재되지 않은 텍스처의 해상도에 대한 메모리 요구량을 계산하려면 해상 비율을 곱하기만 하면 됩니다. 예를 들면, 1024x512 텍스처의 메모리 요구량은 1024x1024 텍스처 메모리 요구량의 절반이 됩니다.

이 표의 데이터는 Box-Filter 밉 생성과 DirectX Texture Compression 을 사용하여 ATI 의 Compressonator 에 의해 작성된 텍스처로부터 컴파일 되었습니다.

해상도

1x1 부터 총 Mip 수

DXT1

DXT5

16x16

5 밉

312 바이트

496 바이트

32x32

6 밉

824 바이트

1.48kb (1,520 바이트)

64x64

7 밉

2.80kb (2,872 바이트)

5.48kb (5,616 바이트)

128x128

8 밉

10.8kb (11,064 바이트)

21.4kb (22,000 바이트)

256x256

9 밉

42.8kb (43,832 바이트)

85.4kb (87,536 바이트)

512x512

10 밉

170kb (174,904 바이트)

341kb (349,680 바이트)

1024x1024

11 밉

682kb (699,192 바이트)

1.33MB (1,398,256 바이트)

2048x2048

12 밉

2.66MB (2,796,344 바이트)

5.33MB (5,592,560 바이트)

4096x4096

13 밉

10.6MB (11,184,952 바이트)

21.3MB (22,369,776 바이트)

8192x8192

14 밉

42.6MB (44,739,384 바이트)

85.3MB (89,478,640 바이트)

엔진 Config TextureGroup 프로퍼티

특정 게임 TextureGroups 에 지원되는 최소 및 최대 LOD (mip) 는 엔진의 환경설정 파일에 정의되어 있습니다.
환경설정 세팅 파일의 소스 세트는 [언리얼 엔진 4 설치 위치]\Engine\Config\BaseDeviceProfiles.ini 파일의 [/Scripts/Engine.TextureLODSettings] 부분에 있습니다.

게임을 개발할 때, [your_game]\Config\DefaultDeviceProfiles.ini 파일에는 Engine\Config\ 폴더에 있는 기본 프로퍼티들의 미러 세트가 들어 있으며, 이것은 보통 여러분이 자신의 게임에 대한 특정 설정의 변경에 사용하는 복사본이 됩니다.

언리얼 에디터 및 게임내에 각각 독립적인 TextureGroup 항목 세트가 있는 것을 주지하십시오. 이 두 세트는 각각 환경설정 파일의 [SystemSettingsEditor] 와 [SystemSettings] 부분에 들어 있습니다.

DefaultDeviceProfiles.ini 파일의 TextureLODGroup 세팅 항목은 아래와 비슷합니다. 오래된 QA 버전에는 각 세팅에 대한 MinMagFilter 및 MipFilter 프로퍼티가 포함되어 있지 않을 수 있습니다.

[/Script/Engine.TextureLODSettings]
; NOTE THAT ANY ITEMS IN THIS SECTION WILL AFFECT ALL PLATFORMS!!!
@TextureLODGroups=Group
TextureLODGroups=(Group=TEXTUREGROUP_World,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldNormalMap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WorldSpecular,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Character,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_CharacterNormalMap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_CharacterSpecular,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Weapon,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WeaponNormalMap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_WeaponSpecular,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Vehicle,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_VehicleNormalMap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_VehicleSpecular,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Cinematic,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Effects,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=linear,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_EffectsNotFiltered,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Skybox,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_UI,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Lightmap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Shadowmap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,NumStreamedMips=3,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_RenderTarget,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_MobileFlattened,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Terrain_Heightmap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Terrain_Weightmap,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Bokeh,MinLODSize=1,MaxLODSize=256,LODBias=0,MinMagFilter=linear,MipFilter=linear,MipGenSettings=TMGS_SimpleAverage)
+TextureLODGroups=(Group=TEXTUREGROUP_Pixels2D,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=point,MipFilter=point,MipGenSettings=TMGS_SimpleAverage)

PC AppCompat 버킷

AppCompat 은 목적 및 시작시에 수집되는 실증적 증거를 바탕으로 다양한 SystemSettings 를 오버라이드하는데 사용됩니다. AppCompat 이 유효화되면 (PC 에 한함), 시스템은 머신의 용량을 측정한 다음 Engine.ini 의 값을 5 개의 "버킷" 가운데 하나로부터 미리 설정된 값으로 덮어씁니다. 이것의 사용 예에 대해서는 Engine\Config\ 폴더의 BaseCompat.ini 를 참고하십시오.

AppCompat 은 오직 게임 (에디터가 아니라) 이 처음 실행될 때 단 한번만 점검되도록 되어 있습니다. 이것은 머신에 대해 이전에 계산된 점수가 들어있는 [game]Engine.ini 에 [AppCompatKR] 섹션이 존재하는지 점검함으로써 탐지됩니다. AppCompat 이 벌써 한 번 적용됐다면, 매번 덮어쓰기 하는 일 없이 사용자에 의한 커스텀 변경이 이루어지도록, 다시 변경되지 않습니다.

에디터에 대해서는 AppCompat 이 명백히 무효화되어 있으므로, 머신의 사양은 개발 중 다양한 머신에서 자산이 어떻게 보여지는지에 영향을 주지 않습니다. 이것이 SystemSettings 과 SystemSettingsEditor 이 분리되어 있는 이유입니다.

Engine.ini 에 있는 [SystemSettings] 에서 모든 버킷을 초기화하도록 하는 빈 DefaultCompat.ini 를 게임에 제공하면 효과적으로 AppCompat 을 무효화할 수 있습니다 (UTGame 의 예 참고). 이 경우 시스템은 AppCompat 이 도입되기 전과 똑같이 동작합니다.

TEXTUREGROUP 프로퍼티

TextureGroup 의 각 항목은 게임의 렌더링에 사용되는 특정 텍스처 세트에 대한 텍스처의 프로퍼티를 정의합니다. 텍스처를 공통의 세트로 그룹화하면 다양한 게임의 텍스처 리소스에 의해 사용되는 텍스처 메모리 풀의 사용을 보다 잘 제어할 수 있습니다.

프로퍼티

설명

MinLODSize

렌더되는 밉의 최소 사이즈. 픽셀 단위로 지정되며 1 에서 8192 범위의 2 의 제곱수입니다. 이 값은 반드시 MaxLODSize 보다 작아야 합니다.

MaxLODSize

렌더되는 밉의 최대 사이즈. 픽셀 단위로 지정되며 1 에서 8192 범위의 2 의 제곱수입니다. 이 값은 반드시 MinLODSize 보다 커야 합니다.

LODBias

렌더용으로 업로드하기에 앞서 오프셋하기 위한 밉 레벨의 수를 결정하는 음수 또는 양수의 값. MinLODSize 와 MaxLODSize 사이로 제한됩니다.

MinMagFilter

텍스처 필터의 타입을 정의합니다. 아래의 도표 참고.

MipFilter

텍스처 필터의 타입을 정의합니다. 아래의 도표 참고.

NumStreamedMips

스트림 인/아웃에 허용된 밉 수입니다. 텍스처에 밉이 10 있고, NumStreamedMips 가 2라면, 가장 높은 두 개의 밉만이 스트림 인/아웃 허용됩니다. 그러므로 텍스처는 언제고 메모리에 8-10 밉을 갖고 있게 됩니다. NumStreamedMips 를 0으로 설정하면 스트림되는 맵이 없으며, 이 LOD 그룹을 사용하는 텍스처는 항상 전체 로드된다는 뜻입니다. NumStreamedMips 를 -1 로 설정하면 (여전히 적용되는 제약은 있지만) 모든 밉의 스트림 인/아웃이 허용된다는 뜻입니다. NumStreamedMips 는 옵션 세팅으로, 디폴트는 -1 입니다.

필터링

MinMagFilter

MipFilter

필터 유형

point

linear

양선형

linear

삼선형

aniso

이방성 점

aniso

이방성 선형

TextureGroup, LODGroup, LODBias

config ini 파일에서 지정된 TextureGroup 과 LODBias 설정은 Texture Properties (텍스처 프로퍼티) 에서 지정된 LODGroup 및 LODBias 설정과 함께 개별 텍스처에 대해 사용된 최종 텍스처 mip 의 세트를 결정합니다.

다음은 TextureGroup 항목의 예로서, [your_game]Engine.ini 에 있는 것입니다:

Group=TEXTUREGROUP_World,MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,MipGenSettings=TMGS_SimpleAverage

TEXTUREGROUP_World LODGroup 에 배정된 텍스처는 모두 렌더링에 사용되는 mip 범위를 결정하기 위해 이 설정을 사용하게 됩니다.
텍스처 프로퍼티의 추가적인 LODBias 설정은 config ini 파일의 TextureGroup 에서 지정된 LODBias 에 첨가됩니다.

LODBias 는 렌더링을 위해 어느 mip 이 선택되는지를 바이어스 또는 오프셋시킵니다. LODBias 는 LODGroup 이 범위를 최대/최소화 하기 전에 계산됩니다. 텍스처 프로퍼티에 있는 LODBias 가 TextureGroup 에 있는 LODBias 에 첨가되어 사용되는 최종 LODBias 값을 결정합니다.
LODBias 값 0 은 주 (native) 텍스처 해상도입니다. LODBias 값 1 은 텍스처에 대한 그 아래 첫 번째의 mip, 그리고 LODBias 값 2 는 그 아래 두 번째 mip 등입니다. 예를 들면 1024x1024 텍스처의 LODBias 가 1 이면 렌더링을 위해 512x512 mip 이 선택되는 결과가 됩니다.

각 개별 텍스처에 대해 텍스처 프로퍼티에서 지정된 LODBias 값은 양수일 수도 있고 음수일 수도 있습니다. 따라서 이는 TextureGroup 의 기본 LODBias 를 더 높거나 더 낮은 mip 값으로 오프셋할 수 있습니다.
예를 들어:

  • TextureGroup 의 LODBias 가 0 이고 텍스처 프로퍼티의 LODBias 가 0 이면 최종 LODBias 는 0 이 됩니다.

  • TextureGroup 의 LODBias 가 0 이고 텍스처 프로퍼티의 LODBias 가 1 이면 최종 LODBias 는 1 이 됩니다.

  • TextureGroup 의 LODBias 가 1 이고 텍스처 프로퍼티의 LODBias 가 1 이면 최종 LODBias 는 2 가 됩니다.

  • TextureGroup 의 LODBias 가 1 이고 텍스처 프로퍼티의 LODBias 가 -1 이면 최종 LODBias 는 0 이 됩니다.

최종 LODBias 가 계산된 다음에는, 이 값이 TextureGroup 의 최소/최대 LODSize 범위에 맞는지 확인하기 위해 텍스처 mip 이 점검되고, 필요한 경우에는 값이 조정됩니다. 이것은 간단한 config ini 파일의 변경으로 특정 TextureGroup 을 효율적으로 최소/최대 LOD 범위 내에 제한할 수 있도록 합니다.

예를 들면, LODBias 가 1 인 1024x1024 텍스처가 위에서 보는 것처럼 TEXTUREGROUP_World LODGroup 에 있는 경우에는 512x512 mip 을 사용합니다. 그 다음에 이것이 TextureGroup 의 최소 및 최대 LODSize 범위 (이 경우에는 256 과 1024) 에 부합하는지 확인하기 위한 점검이 행해집니다. 각 게임의 타이틀에는 그 고유의 TextureGroup 설정이 있기 때문에, 아티스트와 레벨 디자이너들은 각 그룹에 대한 MinLODSize 와 MaxLODSize 를 인식해야 합니다. 게임에 2048 텍스처가 MaxLODSize 1024 의 TextureGroup 에 배정되어 출하된다면 렌더링의 질에는 아무런 도움이 되지 않으면서 배포할 수 있는 패키지의 사이즈만 증가시키게 될 것입니다.

텍스처 프로퍼티

여러가지 텍스처 프로퍼티에 대한 설명은 텍스처 프로퍼티 문서를 참고하세요.

Select Skin
Light
Dark

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼