Power-of-two textures performance benefits with modern WebGL
我们将 PIXI.js 用于内部使用 WebGL 进行渲染的游戏。时不时地,我偶然提到了二次幂和避免 NPOT 纹理可能带来的性能优势(https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/使用_textures_in_WebGL#Non_power-of-two_textures,https://github.com/pixijs/pixi.js/blob/master/src/core/textures/BaseTexture.js#L116)。令人困惑的是,也有人提到它不再起作用(OpenGL - Power Of Two Textures)。随着 webgl 和浏览器的发展如此之快,很难判断这些信息中的哪一个是准确的。
我特别想知道填充图像以创建 POT 纹理的开销(更长的下载时间,增加的内存使用)是否值得性能优势(如果它们确实存在的话)。我找不到任何比较 POT 与 NPOT 纹理的比较或性能基准,遗憾的是我真的不知道如何自己创建一个。
有没有人有这方面的经验或一些最新的数字?有没有衡量 webgl 性能的好方法?
- 不了解性能,但 NPOT 纹理的主要问题是不支持 mipmapping 和重复。 POT(通常)允许在许多计算中进行优化。我也有一种感觉,GPU 可能会在内部将纹理填充到方形 POT 纹理(基于我所做的不相关测试),但我对此不是 100%。
-
如果任何现代 GPU 在 pot 和 npot 之间的性能存在差异,我真的会感到惊讶。现代我指的是过去 6 年中的任何事物,包括手机。但我只是有预感。如果你想知道你必须在很多 GPU 上进行测试。
-
@Wac?awJasper"我也感觉到 GPU 可能在内部将纹理填充到方形 POT 纹理"这是不正确的,想象创建一个 RGBA8 16384 x 8193 纹理,将其填充到 POT 会导致大约 1 GB 的内存使用而不是?536 MB,抓住您选择的gpu分析器并亲自查看。 Afaik 如果应用了填充,它总是在应用程序端完成,以在旧 GPU 上"填充"NPOT 纹理。
-
至于这个问题,我没有做过任何性能基准测试,但 afaik NPOT 纹理本身不应该更慢,但是根据场景的不同,没有 mipmap 的渲染可能会慢很多。如果您发现需要将纹理优化为 POT,那么您可能希望在客户端上执行此操作以节省网络流量。
我认为您将得到的大多数答案是"取决于硬件/驱动程序/gpu"、"您必须自己测试"或"它不会慢很多(但需要注意的是,您必须测试所有gpus 以确保)".
与其担心将图像填充到 POT 中,不如使用纹理别名(sprite表)。或者请求 Pixi 背后的人来实现它。通过使用具有 POT 尺寸的纹理别名,您真正获得了两全其美:最小的填充浪费,保证 POT 纹理的执行速度不会比 NPOT 纹理慢,以及减少 GL 状态变化。
我无法强调通过减少 GL 状态更改可以获得多大的改进。通过实现纹理混叠和绘制批处理,我基本上可以在现实环境中绘制尽可能多的 2D sprite;也就是说以 60fps 的速度移动、旋转和调整 sprite 的大小约为 150k(受 CPU 约束,以每帧计算每个 sprite 的新变换)
- 这个问题的原因之一是我正在研究 github.com/Gamevy/pixi-packer,它是一个纹理打包器。它已经针对接近 POT 大小的 spritesheets,但大多数时候它们并没有完全填充。我想知道 webgl 是否会从我四舍五入到下一个 POT 或保留 spritesheets 中受益。对不起,我应该在我的帖子中添加一些信息。
-
您可以保留 spritesheets 原样,但在创建 webgl 纹理时,请在 POT 中创建它们。
-
它称为 textureATLAS 不是别名
-
除此之外,图集也有其缺点:坐标环绕需要手动完成(clamp、repeat、mirror),mipmap 需要手动生成以避免在较小的 mip 级别上出现颜色溢出,简单的采样会导致自动 mip 的梯度计算失效级别选择以及仅限于对该图集中的所有纹理进行线性或最近过滤的事实(或者需要手动在像素着色器中手动进行过滤)。
-
Mip-mapping 工作正常,只需要填充边框。package模式实现起来很简单。不了解"为自动 mip 级别选择抛出梯度计算"的部分。 LINEAR_MIPMAP_LINEAR 对我来说很好用。
-
不,它不能"正常工作",填充只会推迟问题,请参阅此答案。关于 GPU 上的 mip 级别选择,请查看此内容。一般来说,最好不要混合 atlasing 和 mipmapping。顺便提一句。这是纹理混叠
-
它工作得很好,因为 a) 大多数sprite(这是 PIXI 所做的,绘制sprite)具有透明边框。 b) 填充解决了大多数用例的问题 c) 即使在最高 mipmap 级别上有一些出血,因为它在屏幕上太小了,它真的有什么不同吗?由于某种原因,您发布的两个链接都没有使用填充,我敢打赌,其中描述的大部分问题都可以通过简单的填充来解决。
-
我在之前的评论中链接到的关于 mip 级别选择的文章准确解释了为什么较低级别的出血会成为一个问题(对于sprite也是如此):当在地图集上使用/模拟 REPEAT uv package时,GPU 选择的 mip 级别太小.此外,我的评论是关于纹理图集的一般注意事项,它可能对您"工作正常"(尽管 LINEAR_MIPMAP_LINEAR 几乎是可用于sprite的最差过滤器)。
-
我在该链接中看到的所有内容,如果您还需要 REPEAT 并且不填充边框,这可能是一个问题。平铺(两个链接)是更糟糕的用例场景,因为平铺之间的接缝看起来非常难看。你当然有权发表你的意见,但对我有用的东西可能对 op(和许多其他人)同样适用