为什么游戏中纹理的分辨率始终是2的幂(128x128、256x256、512x512、1024x1024等)?保存游戏的文件大小并使其纹理完全适合UV解包模型是否明智?
如果纹理不是2的幂,会发生什么?
具有256x512或512x1024之类的纹理会不正确吗?还是会引起非二次幂纹理可能引起的问题?
为什么游戏中纹理的分辨率始终是2的幂(128x128、256x256、512x512、1024x1024等)?保存游戏的文件大小并使其纹理完全适合UV解包模型是否明智?
如果纹理不是2的幂,会发生什么?
具有256x512或512x1024之类的纹理会不正确吗?还是会引起非二次幂纹理可能引起的问题?
Answers:
为什么游戏中纹理的分辨率始终是2的幂(128x128、256x256、512x512、1024x1024等)?
正如Byte56所暗示的,“(两个)的幂”大小限制是(每个)尺寸必须独立地为两个的幂,而不是纹理必须是正方形且尺寸为两个的幂。
但是,在现代卡以及哪种现代图形API上,此“限制”已得到显着放松,以使纹理尺寸在合理范围内可以满足您的所有需求。然而:
保存游戏的文件大小并使其纹理完全适合UV解包模型是否明智?如果纹理不是2的幂,会发生什么?
通过确保纹理尺寸是2的幂,图形管线可以利用与2的幂进行效率相关的优化。例如,以两倍的幂进行除法和乘法运算可能会更快(绝对距离我们拥有专用GPU和极其聪明的优化编译器还早了几年)。在管道中使用两个简化的操作进行幂运算,例如mipmap的计算和使用(一个为2的幂将始终平均分成两半,这意味着您不必处理必须四舍五入的情况您的mipmap尺寸向上或向下)。
的确,您可以通过这种方式“浪费”一些空间,但是通常需要额外的空间来弥补渲染性能。另外,还有一些技术,例如将多个图像压缩或打包到单个纹理空间中,可以减轻一些存储浪费。
为什么纹理总是平方为2的幂?
纹理并不总是 正方形,也不总是 是2的幂。它们之所以倾向于是2的幂,通常是为了提高与施加该限制的旧显卡的兼容性。对于非正方形纹理,通常不是问题。总结一下:
D3DPTEXTURECAPS_SQUAREONLY
功能,但是即使在较旧的硬件中我也可以使用非正方形纹理,也没有问题。它与显卡优化有关。它们被设计为以这种方式处理它们。如今,大多数卡将允许您加载尺寸不是2的幂的纹理,但可能会对性能产生负面影响。很有可能在加载时实际上会进行转换,这会浪费您的加载时间,并且不节省任何内存。只要非正方形纹理的尺寸均为2的幂,通常就可以。
处理奇数大小纹理的一种方法是使用“ 纹理图集”。基本上,您将多个纹理放在一起形成单个纹理,并使用顶点的纹理坐标来引用所需的特定图像。这还具有其他性能优势,因为它可以避免状态更改。这种方法的常见用法是将接口的所有元素放置在单个纹理中,这意味着,如果您将接口顶点分批处理到单个缓冲对象中,则可以通过一次调用绘制整个对象,而不用切换纹理多次,并为每个单独进行抽奖。
问题是某些硬件对没有二维功能的纹理的支持有限。
例如,查看http://msdn.microsoft.com/zh-cn/library/windows/desktop/ff476876%28v=vs.85%29.aspx的底部,然后在此处阅读脚注3和4。
3在功能级别9_1、9_2和9_3上,显示设备支持使用二维纹理的尺寸在两种情况下都不是2的幂。首先,每个纹理只能创建一个MIP映射级别,其次,不允许纹理的环绕采样器模式(即D3D11_SAMPLER_DESC的AddressU,AddressV和AddressW成员不能设置为D3D11_TEXTURE_ADDRESS_WRAP)。
4在要素级别10_0、10_1和11_0上,显示设备无条件支持使用尺寸不是2的幂的2D纹理。
图形硬件针对矩阵运算,片段运算和矢量运算进行了优化。简单地说,平方矩阵更易于处理,因为可以在块中进行计算(称为片段),针对块操作对硬件进行了优化,这就是为什么存在诸如文件缓冲区之类的原因,RAM blit直到块之后才对磁盘进行blit已被填充。图形内存也是如此。
帧缓冲器由正方形的片段组成。例如,在分辨率为800x600和RGB颜色空间(0-255)的屏幕中,有800x600点,每个通道3个字节,总共3x800x600 = 1,440,000字节要在帧缓冲区中寻址。这意味着有1,875个可寻址片段,即256x256x3字节。由于纹理数据是正方形的,因此使用双三次缩放可以极大地简化从GRAM矩阵到屏幕缓冲区矩阵的映射,而如果不是正方形,则较长边的偏差将在需要时花费更多时间来计算。被缩放。
许多图形API会接受非方形纹理数据,因为它们接受UV映射坐标作为浮点数据,但是,一旦将其发送到GPU,便会向纹理数据中添加填充,因为图像的实际比例不会更改映射似乎不受影响,但是将填充添加到纹理数据中,因为GPU喜欢将其寻址为一个完美的正方形。
因此,如果使用100x1024的图像,而使用1024x1024的图像,则意味着浪费了946,176个字节。如果要进行合成,则更是如此,因为将需要添加alpha通道以指示填充数据不应影响合成纹理。