【问题标题】:Proper Implementation of Texture Atlas纹理图集的正确实现
【发布时间】:2013-05-06 20:34:42
【问题描述】:

我目前正在开发一款软件,该软件通过拍摄多张图像然后将它们平铺到游戏地图中来生成游戏地图。现在我正在使用 OpenGL 来绘制这些地图。如您所知,在 OpenGL 中切换状态并进行多次绘制调用的成本很高。我决定实现一个纹理图集系统,这将允许我在一次绘制调用中绘制整个地图,而无需状态切换。但是,我在实现纹理图集时遇到了问题。首先,将每个 TILE 存储在纹理图集中还是图像本身更好?其次,并非所有图像都保证是正方形的,甚至是 2 的幂。我是否将它们填充到最接近的 2 次方、平方或两者?我担心的另一件事是图像可能会变得非常大,我担心超过 OpenGL 对纹理的大小限制,这将迫使我将地图拆分,破坏整个概念。

这是我到目前为止的概念:

-生成纹理

-绑定纹理

-生成足够大的图像以容纳纹理(考虑填充?)

-对纹理进行排序?

-将子纹理上传到空白纹理,存储偏移量

-解绑纹理

【问题讨论】:

  • 这是一个很常见的问题,为什么不使用可用的工具呢?我认为 NVIDIA 提供了一些。

标签: c++ opengl texture2d


【解决方案1】:

这不是一个直接的答案,但我无法直接回答,因为您一次要问很多问题。我会尽力为您提供有关相关主题的尽可能多的信息。

以下是您的注意事项列表,可让您重新考虑您的优先事项以及您希望如何执行它们。

首先,根据我的经验(!!),使用纹理数组比使用纹理图集容易得多,并且性能大致相同。纹理数组完全按照您的想法执行,您可以根据变量名称和索引在着色器中对它们进行采样,而不仅仅是名称(即:mytexarray[0])。一大缺点包括数组中所有纹理的纹理大小相同,优点是:子纹理的轻松索引和一次绘制调用中的绑定。

其次,始终使用 2 的幂。我不知道最近的一些系统是否允许完全没有问题的非 2 纹理,但是(再次根据我的经验)最好在任何地方使用 2 的幂.我在 500*500 纹理中遇到的问题之一是在绘制带纹理的四边形时出现黑线,这些黑线恰好是填充到最接近的 2 次幂所需的大小(x 和 y 上的 12 个像素)。所以即使在最近的硬件上,OpenGL 也会给你带来这个问题。

第三(这甚至是英文吗?),关于大小。你所有的问题似乎都是处理图像、纹理。您可能想查看纹理缓冲区,它们允许将大量数据流式传输到您的 GC,并且比纹理更容易更新(这允许 LOD 贴图系统)。如果您使用纹理但只需要用颜色表示其中的数据,而不是直接用颜色表示,这将非常好。

最后你可能想看看“纹理飞溅”,这是一种在不增加数据的情况下增加细节的方法。我不确切地知道你在做什么,所以我不知道你是否可以使用它,但它很容易并且在游戏行业中被大量使用。您可以创建一组随处使用的纹理(岩石、沙子、草等),并创建一个大纹理来跟踪哪个较小的纹理应用在何处。

我希望我在这里写的至少一件事能帮助你, 祝你好运!

PS:openGL 纹理大小限制取决于用户的显卡,因此请注意大于 2048*2048 的大小,即使您的计算机运行良好,其他人也可能会遇到严重问题。安全值最大为 1024*1024。

PSS:请原谅任何语法错误,如有需要请要求澄清。另外,这是我第一次回答,请原谅我缺乏协议。

【讨论】:

  • 好吧,纹理缓冲区(或缓冲区纹理)对于常见的纹理用途完全没有用,因为它们不允许标准化访问、过滤或超过 1 维。它们根本与纹理没有任何关系,只是将缓冲区对象作为线性数组访问的一种方式(因此是一种“shader storage buffers lite”)。
  • 克里斯蒂安·劳是正确的。然而,我的意图是提到一种在没有纹理的情况下缓冲数据的用途,因为我不清楚线程问题的目标。
  • 我应该对纹理数组做更多的研究;这似乎正是我所需要的。我假设我应该将所有纹理填充到最大纹理的大小(我将填充到 NPO2)?
  • 是的,所以我建议保持各个尺寸彼此接近,以减少多余的填充数据。顺便说一句:你确定你不能订购固定尺寸的地图吗?它简化了一切:)
  • 你是什么意思“固定尺寸的碎片”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 2020-01-08
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多