贴图的支持及设置

本页面的内容:

对于现代游戏项目来说,贴图的大小和使用情况是对内存影响的重大因素之一。 幸运的是虚幻引擎 4 有一个健壮的系统,能够对项目中的所有贴图进行没有破坏性的缩减。 在本页中将会简单说明这些系统,以及如何使用它们来为项目减少贴图的内存占用。

贴图分辨率

只需要对某些 .ini 文件稍作改动,虚幻引擎 4 便能支持的贴图分辨率从 1x1 到 8192x8192。 目前支持 DirectX 的显卡及游戏主机支持从 1x1 到 2048x2048 并最高可能到 8192x8192 的各种贴图分辨率。 硬件设备的最高贴图分辨率根据生产商和模型不同,以及可用的贴图内存的数量不同,最高分辨率都会不同。 在虚幻引擎 4 中提供了很多功能和设置来管理渲染到不同地方的贴图分辨率,比如世界的几何体或用户界面。

引擎贴图分辨率限制

虚幻引擎 4 默认限制贴图 mip 的最大值为 14,它有效地限制了最大渲染的贴图分辨率为 8192(从 1x1 到 8192x8192 是 14 mips)。 有一个问题是当导入的贴图分辨率为 8192 时,它在进行渲染时分辨率最多达到 4096 的 mip 1。 在引擎源代码文件中的常量值 MAX_TEXTURE_MIP_COUNT 默认为 13 在做这个限制,它的值可以被改为 14 来支持分辨率 8192 的贴图渲染。 这个常量是在以下源代码文件中被定义的(从版本 QAMar09 开始,请一定要在其他的 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

在 4.8 的版本后,已经可以无需修改 C++ 的代码便能够支持 8192 的贴图分辨率了。需要将下面这部分添加到项目的 DefaultEngine.INI 文件中,并设置 MaxLODsize8192

[SystemSettings]
TEXTUREGROUP_World=(MinLODSize=1,MaxLODSize=8192,LODBias=0,MinMagFilter=aniso,MipFilter=point)

添加完这个增加大小的文字区块后,保存文件并重启编辑器。重启编辑器后,任何以 8192 导入的贴图将会显示 8192 作为 LOD 1 的尺寸,将不在被压制到 4096。 在下面的图示中,我们在一个使用 4.8 引擎的项目中修改了 DefaultEngine.ini 文件来支持 8192 的贴图,当这个叫做 T_8K_Test 的贴图在虚幻 4 中加载时, 我们可以看到导入分辨率和显示分辨率都已经是 8192 了。

T_Getting_8K_Textures.png

压缩贴图的内存需求

DXT 是一种基于把像素放入到使用了调色板颜色和插值颜色的 4x4 块中的有损压缩。这将导致一个 8:1 DXT1 和 4:1 DXT5 的常量压缩文件大小。 由于一个特定平台和硬件的视频内存和贴图资源池是固定的,所以必须在贴图分辨率和资源分配上寻求平衡。 以下表格列出了 DXT1 和 DXT5 贴图的各种常用分辨率,并列了完整的 mip(以 1x1 为原生的 mip 0)对应。可以注意到,对内存的需求几乎是贴图分辨率比率的常量倍数, DXT5 贴图需要的内存几乎是它们的对应物 DXT1 的两倍。

因为分辨率和压缩比率的比值是常量,所以这里并没有列出贴图分辨率计算后的内存需求,其实只要简单地乘以分辨率比率即可。 比如,一个分辨率为 1024x512 的贴图所需要的内存是 1024x1024 贴图的一半。

下表中的数据来自由 ATI 的 Compressonator 使用 Box-Filter 生成的 mipmap 贴图并经过 DirectX Texture Compression 压缩获得。

分辨率 从 1x1 开始的 Mip 数量 DXT1 DXT5
16x16 5 mip 312 字节 496 字节
32x32 6 mip 824 字节 1.48kb (1,520 字节)
64x64 7 mip 2.80kb (2,872 字节) 5.48kb (5,616 字节)
128x128 8 mip 10.8kb (11,064 字节) 21.4kb (22,000 字节)
256x256 9 mip 42.8kb (43,832 字节) 85.4kb (87,536 字节)
512x512 10 mip 170kb (174,904 字节) 341kb (349,680 字节)
1024x1024 11 mip 682kb (699,192 字节) 1.33MB (1,398,256 字节)
2048x2048 12 mip 2.66MB (2,796,344 字节) 5.33MB (5,592,560 字节)
4096x4096 13 mip 10.6MB (11,184,952 字节) 21.3MB (22,369,776 字节)
8192x8192 14 mip 42.6MB (44,739,384 字节) 85.3MB (89,478,640 字节)

引擎配置的 TextureGroup 属性

游戏中特定的 TextureGroups 支持的最大和最小 LOD (mip) 定义在一些引擎配置文件中。 这些配置的源头都在文件 [Unreal Engine 4 Install Location]\Engine\Config\BaseEngine.ini 中的 [SystemSettings] 部分。

对于开发中的游戏,[your_game]\Config\DefaultEngine.ini 文件也包含了 Engine\Config\ 文件夹下的基本属性的镜像内容, 并且它通常应该是针对项目的做特定修改设置的副本。

请注意,对虚幻编辑器和游戏而言,有不同的 TextureGroup 设置集合的入口。 分别位于在配置文件文件的 [SystemSettingsEditor] 部分和 [SystemSettings] 部分。

在 BaseEngine.ini 文件中的 TextureGroup 设置项看上去和这个类似。注意:较老的 QA 版本可能不是在每个设置中都包括 MinMagFilter 和 MipFilter 属性。

[SystemSettings]
; 请注意这里的任何修改都会影响所有平台!!!

TEXTUREGROUP_World=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_WorldNormalMap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_WorldSpecular=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Character=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_CharacterNormalMap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_CharacterSpecular=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Weapon=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_WeaponNormalMap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_WeaponSpecular=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Vehicle=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_VehicleNormalMap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_VehicleSpecular=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Cinematic=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Effects=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=linear,MipFilter=point)
TEXTUREGROUP_EffectsNotFiltered=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Skybox=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_UI=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Lightmap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Shadowmap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point,NumStreamedMips=3)
TEXTUREGROUP_RenderTarget=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_MobileFlattened=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Terrain_Heightmap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Terrain_Weightmap=(MinLODSize=1,MaxLODSize=4096,LODBias=0,MinMagFilter=aniso,MipFilter=point)
TEXTUREGROUP_Bokeh=(MinLODSize=1,MaxLODSize=256,LODBias=0,MinMagFilter=linear,MipFilter=linear)

[your_game]\Config\DefaultEngine.ini 文件中的 TextureGroup 通常会和这个类似。注意 LOD 设置一般会由游戏本身的设计以及目标平台设置范围限制。

[SystemSettings]
TEXTUREGROUP_Character=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_CharacterNormalMap=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_CharacterSpecular=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_Cinematic=(MinLODSize=256,MaxLODSize=4096,LODBias=0)
TEXTUREGROUP_Effects=(MinLODSize=128,MaxLODSize=512,LODBias=1)
TEXTUREGROUP_Lightmap=(MinLODSize=512,MaxLODSize=4096,LODBias=0)
TEXTUREGROUP_Shadowmap=(MinLODSize=512,MaxLODSize=4096,LODBias=0,NumStreamedMips=3)
TEXTUREGROUP_RenderTarget=(MinLODSize=1,MaxLODSize=4096,LODBias=0)
TEXTUREGROUP_Skybox=(MinLODSize=512,MaxLODSize=2048,LODBias=0)
TEXTUREGROUP_UI=(MinLODSize=512,MaxLODSize=1024,LODBias=1)
TEXTUREGROUP_Vehicle=(MinLODSize=512,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_VehicleNormalMap=(MinLODSize=512,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_VehicleSpecular=(MinLODSize=512,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_Weapon=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_WeaponNormalMap=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_WeaponSpecular=(MinLODSize=256,MaxLODSize=1024,LODBias=0)
TEXTUREGROUP_World=(MinLODSize=256,MaxLODSize=1024,LODBias=1)
TEXTUREGROUP_WorldNormalMap=(MinLODSize=256,MaxLODSize=1024,LODBias=1)
TEXTUREGROUP_WorldSpecular=(MinLODSize=256,MaxLODSize=1024,LODBias=1)
TEXTUREGROUP_MobileFlattened=(MinLODSize=8,MaxLODSize=256,LODBias=0)
r.setres=1024x768

TEXTUREGROUP Properties

Each TextureGroup entry defines the texture properties for a specific texture set as used in the game rendering. Grouping textures into common sets allows for better control over the texture memory pool use by various game texture resources.

Property Description
MinLODSize Minimum mip size that will be rendered, specified in pixels, range of 1 to 8192 as power-of-two's, must be less than MaxLODSize.
MaxLODSize Maximum mip size that will be rendered, specified in pixels, range of 1 to 8192 as power-of-two's, must be greater than MinLODSize.
LODBias A negative or positive value that determines the number of mip levels to offset prior to uploading for render, clamped within MinLODSize and MaxLODSize.
MinMagFilter Specifies the texture filter type when textures are minified or magnified by the GPU. See the chart below.
MipFilter Specifies whether the GPU should blend two mips together when viewing the texture from a distance or at a grazing angle. See the chart below.
NumStreamedMips The number of mips that are allowed to be streamed in or out. If a texture has 10 mips and NumStreamedMips is 2, only the 2 highest mips will be allowed to stream in or out. The texture will therefore have 8-10 mips in memory at any given time. Setting NumStreamedMips to 0 means that no mips will be streamed and the textures using this LOD group will always be fully loaded. Setting NumStreamedMips to -1 means that all mips are allowed to be streamed in or out (there are still other restrictions that apply though). NumStreamedMips is an optional setting that defaults to -1.

Filtering

MinMagFilter MipFilter filter type
point - Point
linear point Bilinear
linear - Trilinear
aniso point Anisotropic Point
aniso - Anisotropic Linear

TextureGroup, LODGroup and LODBias

The TextureGroup and LODBias settings specified in the config ini files, along with the LODGroup and LODBias settings specified in the Texture Properties determine the final set of texture mips used for an individual texture.

An example TextureGroup entry in the [your_game]Engine.ini may look like this:

TEXTUREGROUP_World=(MinLODSize=256,MaxLODSize=1024,LODBias=0,MinMagFilter=aniso,MipFilter=point,NumStreamedMips=3)

Any textures assigned to the TEXTUREGROUP_World LODGroup will use these settings to determine the mip range used for rendering.
The additional LODBias setting in the Texture Properties is additive with the LODBias specified in the config ini file TextureGroup.

The LODBias biases or offsets which mip is chosen for rendering. The LODBias is calculated before the LODGroup Min/Max range. The LODBias in the Texture Properties is added to the LODBias in the TextureGroup to determine the final LODBias value used.
A LODBias of 0 is the main (native) texture resolution. A LODBias of 1 is the first mip down for the texture, a LODBias of 2 is the second mip down, etc. For example, a 1024x1024 texture that has a LODBias of 1 results in the 512x512 mip being chosen for rendering.

The LODBias specified in the Texture Properties for each individual texture can be positive or negative, so that it can offset the TextureGroup's default LODBias to either higher or lower mip values.
For example:

After the final LODBias is calculated, then the texture mip is checked to see that it fits into the TextureGroup's Min/Max LODSize range, and it is adjusted if necessary. This allows a simple config ini file change to effectively clamp a specific TextureGroup to within a set min/max LOD range.

For example, a 1024x1024 texture with LODBias of 1 uses the 512x512 mip, if it is in the TEXTUREGROUP_World LODGroup as shown above, it is then checked to see if it fits within the TextureGroup's Minimum and Maximum LODSize range, which in this case is 256 and 1024. Since each game title will have its own unique TextureGroup settings, artists and level designers should be aware of the MinLODSize and MaxLODSize for each group. It would increase distributable package size with no rendering quality benefit if a game shipped with 2048 textures assigned to a TextureGroup with a MaxLODSize of 1024.

Texture Properties

For an explanation of the meaning of the various texture properties, see the Texture Properties page.