opengl 高纹理与内存位置的宽纹理

opengl tall texture vs wide texture for memory locality

2D 纹理有两个坐标,x 和 y。要在一维内存中存储二维数组,两种可能的格式是 [x + y * width] 和 [x * height + y]。 OpenGL 有各种令人困惑的 row-major/column-major 约定,所以我不确定它使用的是两种格式中的哪一种。这是相关的,因为如果纹理用于存储多个图像,例如在精灵 sheet 或图集中,最好让图像的各个部分在内存中靠近在一起。例如,如果格式是 [x + y * width] 并且我们正在使用非常宽的纹理,那么 GPU 将不得不跳过很长的内存部分来找到它需要的纹素。

因此:是高纹理图集优于宽纹理图集,还是相反?还是 GPU 没有内存位置优势?

纹理图集最重要的方面是它可以容纳多少图像。即使涉及到纹理图集,您也更有可能访问相邻的纹理元素而不是远处的纹理元素。

想一想。假设您渲染 2 个 32x32 精灵。所以这是 2 个四边形,在单个渲染调用中。每个四边形将占用屏幕上的 32x32 像素;那是 1024 像素。

地方很重要;您从 1024 个局部相邻的纹素渲染,然后从另一组 1024 个局部相邻的纹素渲染。

无论如何,OpenGL 不会让您了解 GPU 图像格式的详细信息。您可以要求特定大小的纹素和多个通道。但你不会得到比这更多的细节。您提供的数据将由驱动程序适当地转换为实际的内部 GPU 数据。

通常,GPU 会调配内存中的纹理。这意味着重新排列数据以保留局部性。也就是说,不是将纹素存储为 x + y * widthx * height + y,而是将它们存储在更复杂的排列中。

例如,前 4 个值将是纹素 0,0; 0,1; 1,0;和 1,1。因此,一个 2x2 的纹素块存储在一个连续的内存数组中。这是混合纹理存储如何工作的示例。

但这都是一个实现细节;你无法做任何事情来影响或影响这一点,甚至像 Vulkan 这样的低级 API 也不允许你直接加载预混合的纹素数据。