纹理在GPU上占用多少内存?


9

磁盘上的大png可能只占用几兆字节,但我想在gpu上,同一png以未压缩的格式存储,这会占用更多空间。这是真的?如果是真的,有多少空间?

Answers:


16

JPG和PNG文件在磁盘上的大小几乎总是比内存小。它们需要即时解压缩以获取原始RGB数据,因此需要更多的处理能力来进行加载,然后需要更多的RAM。如此众多的现代引擎选择在磁盘上存储与在内存中相同的格式,导致文件的大小与纹理的内存要求相同(但也大于PNG或JPG)。RGB / RGBA和S3TC / DXTn / BCn是使用最广泛的格式,因为它们无需任何处理即可直接读取到内存中(DXT纹理已预压缩)。

因此,这些是不同常用纹理格式的大小:

  • L(亮度,例如灰度):宽度*高度* 1个字节。
  • LA(亮度和Alpha,字体常用):宽度*高度* 2个字节。
  • RGB(彩色,无Alpha):宽度*高度* 3个字节。
  • RGBA(带alpha的颜色):宽度*高度* 4个字节。
  • DXT1 / BC1(彩色,二进制alpha):(宽度*高度* 4个字节)/ 8(压缩比8:1)。
  • DXT3 / BC2(彩色,清晰的alpha)/ DXT5 / BC3(彩色,渐变alpha):(宽度*高度* 4字节)/ 4(压缩比4:1)。

如果将图像与mipmaps一起使用,则纹理将需要4/3的内存。此外,可以在内部将纹理的宽度和高度四舍五入为旧的或性能较差的硬件上的2的幂,并且在某些非常有限的硬件上也必须为正方形。

有关DXT的更多信息:这是一种有损压缩;这意味着在压缩纹理时会丢失一些颜色数据。这会对您的纹理产生负面影响,扭曲尖锐的边界并在渐变上创建“块”;但是好处远胜于缺点(如果您的纹理在DXT中看起来非常糟糕,请保持未压缩状态;其他纹理将弥补尺寸损失)。另外,由于像素是由固定大小的块压缩的,因此纹理的宽度和高度必须是四的倍数。


除了您的第一句话,这是正确的-磁盘上的纹理格式可以是任何高度压缩的格式,因此,除了直接格式化存储格式的磁盘格式外,它在磁盘上的占用空间与VRAM中的占用空间不同。

当然可以,但是可以检查使用Unreal Engine,Source等构建的游戏中使用的资产。通常,它们通常不会压缩在磁盘上,因为如今磁盘空间已足够多,可以不压缩资源。并且节省的空间无法弥补每次加载时解压缩文件所需的额外RAM和CPU时间。
r2d2rigo

1
我想您会发现每个引擎都有所不同。许多较大的引擎(尤其是在控制台上运行的引擎)将使用与内存格式相同或相近的磁盘格式。但是,很容易找到带有PNG或JPEG资源的仅PC游戏。如果您必须进入磁盘进行负载,那么无论如何,这将占据您的大部分时间。另外,Mike特别提到了PNG和JPEG作为磁盘格式。

除RGB格式通常在GPU上实际上不存在外,大多数情况下都是正确的。参见:opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
Maximus

9

显然:这取决于格式。

让我们采用256 x 256像素的正方形纹理。如果它是具有alpha通道的未压缩32位(Color在XNA中),则需要256KB256*256*4字节)。

16位格式(例如:)Bgr565显然是大小的一半-128KB

然后进入压缩格式。在XNA中,您具有DXT1,DXT3和DXT5(也称为S3压缩)。这是一种有损压缩格式。它也是基于块的格式-这意味着您可以从中采样(因为您知道像素位于哪个块中)。它也更快,因为您使用的带宽更少。

DXT1的压缩率为8:1,而DXT3和DXT5的压缩率为4:1。

因此256x256的DXT1图像为32KB。DXT3或DXT5为64KB

然后是mipmapping。如果启用此功能,则会在图形内存中创建一系列图像,每个图像的大小是前一个的一半。因此对于我们的256x256图片:128x128、64x64、32x32、16x16、8x8、4x4、2x2、1x1。具有mipmapping的纹理约为原始大小的133%


4

大多数GPU只能读取非常特定的压缩格式。例如。BC *,DXT *,而不是png等格式。因此,是的,在大多数情况下,.png占用的视频内存空间比磁盘要多。

纹理可以压缩或未压缩形式存储在视频内存和系统内存中。

对于未压缩的纹理,通常的经验法则是,它将在视频内存中占用与在系统内存中以未压缩形式占用的空间相同的空间。

对于DXT1压缩纹理。GPU为纹理中的每个4x4切片存储8个字节。未压缩的数据(每个RGB通道8位)通常为4x4x3 = 48字节,因此压缩率为6:1。对于DXT3 / DXT5压缩纹理,GPU为纹理中的每个4x4切片存储16个字节。那是略低的3:1压缩比。

有一些警告同时包含未压缩和压缩的纹理:

  • 大多数内存分配在固定大小的页面中(页面的大小在GPU之间有所不同)。例如。4KB,通常不会再分配,也不会与其他gpu数据共享。就是 如果您的纹理足迹小于页面大小,则vid mem中的足迹通常仍为页面大小。

  • 一些GPU具有非常特定的对齐要求。过去,某些GPU要求纹理的大小为2的幂。通常需要使用这种方法来支持模糊的表示形式(请参阅Morton Ordering:http : //en.wikipedia.org/wiki/Z-order_ (curve )),以提高从纹理采样时的访问局部性。这意味着将填充奇数大小的纹理以保留这些要求(通常,此填充由驱动程序处理)。尽管现代gpu不一定必须使用morton-order,但可能仍然会出现膨胀以支持gpu的特定要求。

  • 在任何时候,内存中都可能存在纹理的多种表示形式,尤其是在对它们使用丢弃锁的情况下。这可能会消耗大量内存,直到gpu不再使用表示形式(通常比CPU渲染晚几帧)

  • 如果启用mipmapping,则额外的mips将平均消耗基本mip级别的三分之一。基于以上警告的YMMV。


0

AFAIK是图像的宽*高* BPP,如果是PNG,JPG或BMP,则独立。我不知道DDS或其他可压缩格式的布局。

Mip映射将增加对视频内存的需求。

我对这个主题的知识可能有点过时了。我前一阵子放弃了3D。


2
图像还具有间距(或步幅),即一个像素行的末尾与下一像素行的起始之间的字节数。没有人提到这件事,所以我可能会误会。
CiscoIPPhone

1
通常,“间距”是指扫描线的长度(以字节为单位)(如Freetype和SDL),“步幅”是指元素之间的间隔,可以是像素或扫描线(如OpenGL和Python的3rd slice参数)。这两个值都是进行图像处理所必需的,但通常“ pitch” =“宽” *“ bytes_per_pixel”和“ stride” = 0。这些术语经常使用时过于松散和混乱,因此最好检查API文档以了解所选择的库。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.