UE4场景流程规范-纹理压缩设置(美术版/程序版)
在目前所做的一个大世界项目的开发中,整体场景的制作会涉及到很多的方方面面,也会有很多问题产生,每个方面都需要理一个比较清晰易懂的标准出来,让整个项目组有关的人员能快速达成共识,也减少沟通的成本。
比如项目中发现对于贴图格式的设置和使用还是有些错误,故以此为开始,逐步整理一些有关的说明给项目美术人员看看,顺便解答自己的一些疑惑,文中分为三个版本,分别是
太长不看版:直接看结果,那种贴图用哪个格式
美术版:除了结果,稍微介绍一下每种格式的细节
程序版:主要解答我自己以下几个疑问,如果你也有这些疑问,可以看看
NormalMap 是如何选择使用 BC3 还是 BC5 压缩的?
普通 Texture 导入进来,引擎会不会自动判断是否有 alpha 通道,从而选择使用 BC1 还是 BC3?
当然第二个问题很容易看出来,引擎确实会,但它执行逻辑的地方在哪里?
引擎真正执行压缩的地方在哪里?使用的什么来执行压缩?
目录
太长不看版
美术版
BaseColor(Default DXT1/DXT5 BC1/BC3)
NormalMap
Masks(MSRA:roughness,specular,metal,ao )
Alpha/GrayScale
HDR (RGB, no sRGB) / HDR Compressed (RGB, BC6H, DX11)
BC7 (DX11, optional A)
Ohthers
合理 使用TextureGroup
程序版
太长不看版
BaseColor等就一般使用BC1或者BC3(有 alpha 用 BC3,没有就用 BC1),一般勾选 sRGB,如果错误导入进来 alpha,可以勾选 Compress without alpha,在引擎里面禁用掉
NormalMap使用BC5,也就是选项里的 normal map选项,取消勾选 sRGB
MSRA 使用 Masks模式,并且取消勾选 sRGB
HDR环境贴图使用BC6,推荐使用 HDR Comressed,也就是使用 BC6 压缩,如果选择 HDR ,它的 format 是 floatRGBA 一个通道 32bit,非常大
单通道的贴图 可以使用 Alpha 或者 GrayScale,GrayScale 相当于不压缩,使用 G8 的format,也就是 一个 Pixel 是 8 bit,4*4 16个pixel 占 128bits,Alpha 使用BC4 压缩 4*4 16个pixel 占 64bits,小一半,所以 GrayScale 适合不是本身不是很大的贴图,否则比较大,还是使用 alpha 选项,BC4压缩一下
LUT 就不需要自己选了,选一下引擎的 LoopUpTable 的 texture group,它会自动帮你设置好,默认引擎的配置是不压缩的
美术版
BaseColor(Default DXT1/DXT5 BC1/BC3)
如果导入的 BaseColor 贴图带了 alpha,但其实不需要,可以勾选 Compress Without Alpha,避免把alpha 压进来
DXT1/BC1: 有8:1 的压缩比,24bit*16 变成 64 bit(6:1),(32bits*16 / 64 = 8,所以8:1)
NormalMap
normal map 勾选 without alpha,BC5,并且没有 sRGB,根据系统配置可以强制选择 BC3压缩
具体逻辑在 Texture.cpp FName GetDefaultTextureFormatName()
FString UseDXT5NormalMapsString;if (EngineSettings.GetString(TEXT("SystemSettings"), TEXT("Compat.UseDXT5NormalMaps"), UseDXT5NormalMapsString)){ bUseDXT5NormalMap = FCString::ToBool(*UseDXT5NormalMapsString);}...else if (FormatSettings.CompressionSettings == TC_Normalmap){TextureFormatName = bUseDXT5NormalMap ? NameDXT5n : NameBC5;} ...
如果导入不小心带了 alpha,也可以勾选 without alpha 去掉
Masks(MSRA:roughness,specular,metal,ao )
另外那张 roughness,specular,metal,ao 等等的贴图 MSRA,这类不是用来存储 color或者 vector,而是独立的4种信息(相当于4种 grey scale),都可以归类为 Mask,使用Mask,no sRGB,实际使用的是 DXT5,也就是 BC3的压缩,每个 4*4 的块压缩为 128 bits,所以基本能看到比选择 default BC1 的 texture size大一倍,注意 128 bits 里面 64bits 用于 rgb color,64 bits用于 alpha,所以这四个里面选择也是把 比较重要的那个放在 alpha channel里面
Alpha/GrayScale
同样 Masks 模式,这张 heightMap
自动检查到没有 alpha,所以使用了 DXT1
但能看到这种模式下由于压缩带来的 锯齿 很严重,所以换用别的压缩模式 grayScale,R8的format,适合本身就是 8 bits 灰度,由于 R8是直接没压缩的,所以适合 texture 不止单通道,本身也不是很大的那种,否则还是用压缩,BC4吧
这里注意原本是 RGBA 8 的 贴图,进来强行只使用 单通道,选择 alpha 或者 gray scale 是不可以的,原来不是单通道,切换到 Alpha 或者 GrayScale 会变成 BGRA8.
HDR (RGB, no sRGB) / HDR Compressed (RGB, BC6H, DX11)
HDR环境贴图使用BC6,如果选择 HDR ,它的 format 是 floatRGBA 一个通道 32bit,非常大,推荐使用 HDR Comressed,也就是使用 BC6 压缩
BC7 (DX11, optional A)
特别重要的使用 BC7,4:1 压缩比,相比 BC1,两倍占用,alpha 也可以有
Ohthers
其他的类型的 用法都包含在名字里了
Displacement Map (8 / 16bit):G8 ,单通道的 置换贴图
Vector Displacement Map (RGB8):BGRA8,支持四个通道的置换贴图
User Interface 2D (RGBA):BGRA8,UI 上的贴图都选这个,注意复用,不要太大
Distance Field Font (R8):用于 sdf font 的 贴图,只用存单通道距离就行,所以 G8 就够
合理 使用TextureGroup
配置好 group,可以减少美术出错几率,只要一开始配置好 config,后面所有贴图资源的 format 都可以统一管理
程序版
在 Texture 修改属性之后,一般会调用到 Texture 的 UpdateResource();
里面会调用
CachePlatformData(); 重新生成 DDC(生成压缩纹理),
ClearAllCachedCookedPlatformData(); 清理cook data
而 压缩的逻辑就在 CachePlatformData()
GetBuildSettingsForRunningPlatform() 获取各种配置和 压缩format,出来判断ddc 的key是否已经有了,如果没有,就重新cache 生成
里面会调用
GetTextureBuildSettings,获取 texture 的各种配置,就是 那个窗口的配的各种属性
CurrentPlatform->GetTextureFormats,各个平台选择各自需要的压缩格式
Android:FAndroidTargetPlatform::GetTextureFormats
FName GetDefaultTextureFormatName,这里就是 官方解释 压缩格式的文档里写明的格式
Windows:GenericWindowsTargetPlatform.h,调用 default,
FTexturePlatformData::Cache 如果DDC 里没有找到,开始 Cache
Texture 生成ddc key 的方法
开始cache,先 找到 ITextureCompressorModule 纹理压缩的 module 作为 Compressor 压缩器,由 Compressor 生成 task,这里可以异步
Compressor 里面根据不同的 format,分给不同的 format 压缩器,比如 DXT 格式就是 FTextureFormatDXT
const ITextureFormat* TextureFormat = nullptr;ITargetPlatformManagerModule* TPM = GetTargetPlatformManager();if (TPM){TextureFormat = TPM->FindTextureFormat(BuildSettings.TextureFormatName);}
然后 DXT 的format 里再处理,比如上面如果是 AutoDXT 的 format,这里就是再根据是否有alpha 选择使用 DXT1 还是 DXT5
然后同样这个方法,下面就执行 Compress,DXT 目前默认使用 NVTT,Nvidia 的一个纹理压缩器,压缩之后返回是否成功,如果成功,就缓存到到 DDC 里面
Reference: