3D美术实时渲染最佳实践(6):纹理

2020/09 19 13:09

原文档:Arm® Guide开发人员指南 V4.1 – 移动平台游戏图形优化

图集、采样、Mipmap图集( Texture atlas, filtering, and mipmap texture atlas )

A texture atlas is an image that contains data from several smaller images that have been packed together. Instead of having one texture for one mesh, you have a larger texture that several meshes share.
A texture atlas can be created before making the asset, which means the asset is UV unwrapped according to the texture atlas. This requires some early planning when creating the texture.
The texture atlas can also be created after the asset is finished by merging textures in painting software.
However, this also means that the UV islands must be rearranged according to the texture.

A UV island is a connected group of polygons in a texture map.

the image highlights which 3D objects use one texture set

为什么要使用图集

图集可以为共享该图集和相同材质的静态对象进行合批,合批减少了DrawCall个数,当游戏是CPU-bound时,较少的DrawCall可提高性能。Unity引擎可以将对象标记静态合批,无需手动合并对象。由于纹理被打包在一起,因此在游戏内部需要的纹理也更少。通过压缩,这有助于降低纹理几存

Mipmapping

Mipmap是以较低分辨率保存的副本。因此可以将mipmapping视为“细节级别(LOD)”,基于片元阶段占用多少纹理大小,选择适当的级别进行采样。当物体离摄像机较远时,将应用较低分辨率的纹理。当物体离相机更近时,将应用更高分辨率的纹理。

最佳实践

确保使用mipmapping,因为它可以提高性能和质量。 Mipmapping可以提高GPU的性能,因为GPU在渲染远离相机的物体时,不需要在屏幕上渲染全分辨率纹理。 

Mipmapping还可以减少纹理混叠并提高最终图像质量。
纹理混叠会在距离相机更远的区域上产生闪烁效果。

纹理大小

Textures can be different sizes. Reducing the size of certain textures that require less detail, helps to reduce bandwidth levels. For example, the diffuse texture can be set to 1024×1024 and the roughness, or metallic, map to 512×512.
减少细节少的纹理大小,有助于减少带宽
例如漫反射纹理可设为1024×1024,粗糙度或金属度可设为512×512

Selectively reduce the texture size and check if any of the visuals have been degraded afterwards.
选择性地减小纹理大小,然后检查是否有任何视觉效果下降

颜色空间

Use diffuse textures in the sRGB color space.
Textures that are not processed as color must not be in the sRGB color space. Examples include, but are not limited to: metallic, roughness, and normal maps.
The reason being that maps are used as data, not color.
Using sRGB in these maps results in the wrong look, or visual, on the material.

推荐尝试以下操作: 
•漫反射纹理在sRGB颜色空间中处理; 
•非颜色的纹理不得在sRGB空间中,包括但不限于:金属贴图,粗糙度贴图、法线贴图。理由:
1、它们是被映射用于数据,而非颜色
2、在这些贴图中使用sRGB会导致材质的外观或者视觉错误

请注意:不要在Unity的Inspector窗口中,为粗糙度、金属贴图、法线等数据贴图设置为sRGB!

以下屏幕截图显示了将sRGB错误地应用于这样的纹理时会发生什么:

纹理压缩

Texture compression is an image compression that is applied to reduce texture data size, while minimizing the loss in visual quality. In development, we export textures using a common format, such as TGA, or PNG. These formats are more convenient to use and major image software programs support them. These formats must not be used in final rendering because they are slower to both access and sample, when compared to specialized image formats. For Android, there are several options such as Adaptive Scalable Texture Compression (ASTC), Ericsson Texture Compression (ETC) 1, or ETC2.

最佳实践

We recommend that you use the ASTC technology that Arm created. Here several reasons as use ASTC:
建议使用Arm创建的ASTC技术。这里有几个使用ASTC的原因:

•ASTC具有与ETC相同的内存大小,可以提供更好的质量
•ASTC提供相同质量的纹理要比ETC小得多
•ASTC比ETC需要更长的编码时间,并使游戏打包过程更长。如果这是一个问题,那么最好在游戏的最终包装中使用ASTC。
•通过允许设置块大小,ASTC可以在质量方面进行更多控制。虽然没有最佳的块大小默认值,但是将块大小设置为5×5或6×6是一个很好的值。

有时,如果必须在设备上快速部署游戏,则使用ETC进行开发可能会更快。可以将ASTC与快速压缩设置一起使用来避免部署时间的增加。 编码时,可以选择权衡速度和质量。对于最终版本,就视觉质量和文件大小之间的平衡而言,ASTC是最佳选择。打包时,引擎会处理纹理压缩。可以选择使用哪个。

以下屏幕截图显示了在Unity中构建Android软件包时在哪里选择ASTC: 

下图显示了ETC和ASTC压缩之间的质量差异以及相应的文件大小: 

UV展开

最好的办法是保持UV islands尽可能地直

A UV island is a connected group of polygons in a texture map.
The reasons for this are:
UV island是纹理图中相连的一组多边形

• It makes packing UV islands easier and less space is wasted.
它使得UV islands更容易,浪费更少的空间

• A straight UV helps reduce the staircase effect happening on textures.
直的UV有助于减少纹理发生阶梯效率

• On mobile platforms, texture space is limited as the texture size is usually smaller than on a games console or a PC. Good UV packing ensures that you get the most resolution from your texture.
在移动平台上,纹理空间有限,纹理大小通常小于主机或者PC,良好的UV填充可以确保从纹理中获得最高的分辨率

• It might be worth having a slightly distorted UV by keeping the UV straight for better quality texture overall.
通过保持UV笔记以获得总体上更好的表现,可能值得稍稍扭曲UV

Place UV seams in places that make them not too visible. This is for visual quality purposes, as the texture seam can look bad on a model. Therefore, split UV islands where the edges are sharp and have a small space between the UV islands. This helps later on to create better normal maps through the baking process.
将UV接缝放置在不太明显的位置。这是出于视觉的目的,因为纹理接缝在模型上看起来可能不好。因此,在边缘较尖锐且在UV islands之间具有较小间距的拆分UV islands。这有助于以后在烘焙过程中创建更好的法线贴图

下图显示了UV展开如何最大化纹理空间

视觉冲击

Make sure that you only create details that can be seen. Phone screens are small, therefore fine grained detail is not visible. Take this into account when creating textures. For example, you do not need a 4K texture with lots of details for a chair that is barely visible in the corner of the room.
The following screenshot shows an example of a small texture on a soldier that has only the required amount of detail needed:
确保只创建可以看到的细节。电话屏幕很小因此看不到细节。创建纹理时要考虑到这一点。例如,您不需要在房间一角几乎看不到的椅子上有很多细节的4K纹理。 
以下屏幕截图显示了一个士兵的小纹理示例,该纹理仅具有所需的详细信息量:

In certain cases, you need to exaggerate and highlight the edges and shading to improve shape readability. Bear in mind that mobile platforms generally use smaller textures. So, it might be hard to capture all of the detail that is needed within this small texture.
在某些情况下,需要夸大并突出显示边缘和阴影以提高表现。注意: 移动平台通常使用较小的纹理。因此,可能很难获得这个小纹理内所需的所有细节。

使用较少的纹理,并将所有其他细节烘焙到一个纹理中。这很重要,因为:

• 手机屏幕很小,最好将某些细节烘焙到漫反射纹理本身上,以确保这些细节可见。


• 可以烘焙诸如环境光遮挡和小的镜面反射高光之类的元素,然后将其添加到漫反射纹理中。
这种方法意味着您不必太依赖Shader和和引擎来获得镜面和环境光遮挡。

以下屏幕截图显示了如何将细节烘焙到纹理中的示例:

将细节烘焙到纹理中的示例

如果可能,使用在Shader着色灰度纹理。这样可节省纹理内存,但要以创建自定义Shader, 但使用此方法并非所有对象看起来都很好。将其应用于具有均匀或相似颜色的对象会更好,也可以使用RGB蒙版,然后应用基于蒙版颜色范围的纹理来完成。

下图展示了将灰度图应用到有色柱子的示例

灰度图示例

纹理通道打包

1、纹理通道打包有助于节省内存,因为3/4合1,可在Shader中可以减少采样
2、这种纹理通常用于将粗糙度或光滑度、金属度 放到一个纹理中
3、使用绿色(G)通道存储更重要的蒙版。绿色通道通常具有更多位(例如RGB565)。这是由于我们的眼睛对绿色更敏感而对蓝色不那么敏感。
4、粗糙度或光滑度贴图通常比金属贴图具有更多的细节,放置在绿色通道中
5、将通道打包的纹理在Inspector窗体中,设置为线性或RGB,而不是sRGB颜色空间


打包示例:

纹理通道打包示例

Alpha通道和法线图最佳实践

使用A通道
1、如非必要,不要开启A通道,因为这会增加带宽,除非你一定要用它
2、存储Alpha通道的另一种方法是在粗糙度或金属纹理中使用额外的通道。在Unity中,此纹理有时使用三个通道中的两个,即粗糙度(G)和金属(B),使您可以自由使用(R)通道。
3、 存储A通道的另一种方法是在粗糙度或金属纹理中使用额外的通道。在Unity中,此纹理有时使用三个通道中的两个,即粗糙度(G)和金属(B),使您可以自由使用(R)通道。 
4、通过使用剩余A通道存储Alpha蒙版,可以将漫反射纹理保持在16位,从而将文件大小减半。通常可以在diffuse纹理中烘焙环境光AO贴图。

下图展示了在R通道中存储不透明通道

法线图最佳实践

A normal map is a good way to make a 3D object appear to have more detail. It is best used to add smaller details such as wrinkles, bolts, and other details that need lots of triangles to model. The usage of normal mapping can depend on the type and art direction of a game.
法线贴图让3D模型更有细节。最好用来添加小细节,比如皱纹、螺栓和其他需要大量三角形进行建模的细节。法线贴图的使用取决于游戏的类型和风格。

在大多数内部项目中,使用法线贴图性能没有明显的下降。由于大多数演示中都针对高端设备,因此低端设备可能会有不同的结果。

即使成本很小,使用法线图也有成本:
1、法线图是额外的纹理,需要更的带宽
2、低端设备,请谨慎使用法线图;
但如果因为使用了法线图可以减少三角形数量,则是提高了性能

下图展示了应用法线贴图去展示细节

应用法线贴图展示细节

法线图烘焙最佳实践


Using a cage is a great way to always get a high-quality normal map, regardless of what type of surface you are baking. Most normal mapping software makes your cage automatically. If necessary, you can make a normal map from a copy of your low polygon model and then increasing the scale of it slightly.
无论要烘烤哪种类型的表面,使用Cage都是始终获得高质量法线图的好方法。大多数法线图软件都会自动生成Cage。如有必要,可以从低多边形模型的副本制作法线贴图,然后稍微增加其比例。

The cage is a larger version of the low polygon count model, and therefore the model appears pushed out. It must also physically cover the high polygon count model for the baking to work well.

The purpose of using the cage is for the program to change the direction that is used to calculate the normal when baking. This produces far better results on split-normal and hard edges, as shown in the following image:
使用Cage的目的是使程序可以更改烘焙时计算法线的方向。如下图所示,这会在分割法线和硬边上产生更好的结果

有Cage和没有Cage的对比
A mesh cage is used to limit the ray cast distance that is used during normal map baking. A cage can also solve problems with split-normal seams on the normal map, as demonstrated in the following image:

If the baking software supports it, bake by matching the mesh names. This mitigates the problem of creating a wrong normal map projection. When objects are too close with each other, they can unexpectedly project the normal map onto the wrong face. Using this method ensures that baking is only done on the right surface, with a matching name.
如果烘焙软件支持,请通过匹配网格名称进行烘焙。这减轻了创建错误的法线贴图投影的问题。当对象彼此之间的距离太近时,它们可能会意外地将法线贴图投影到错误的面上。使用此方法可确保仅在正确的表面上进行匹配名称的烘烤。

Further information on matching meshes by name is available on the substance3d website along with the Marmoset Toolbag tutorial.
有关按名称匹配网格的更多信息,可在material3d网站以及“ Marmoset工具包”教程中找到

If you cannot match mesh names for baking, then explode the mesh. Exploding a mesh means that you move parts away from each other, so that the normal map does not project onto an unwanted surface.
如果无法匹配要烘焙的Mesh名,请炸开网格。炸开网格意味着将部件移开,这样法线图就不会投影到不需要的表面上

下图展示了如何炸开Mesh

A separate bake for ambient occlusion can sometimes be required with this solution. So split UVs on hard edges, as a continuous UV on hard edges causes visible seams. The general rule is to keep the angle less than 90 degrees, or set it as a different smoothing group. Coincide UV seams with different smoothing groups on the triangles.
此解决方案有时可能需要单独烘烤以设置AO。因此,在硬边上拆分UV,因为在硬边上连续UV会导致可见的接缝。一般是将角度保持在90度以下,或将其设置为其他光滑组。在三角形上重合具有不同光滑组的UV接缝

下图展示烘焙硬边时如何打碎UV

Unity Inspector中的 纹理设置

这部分内容没有营养,略过