优化基于OpenGL的动画/可缩放2D UI渲染的策略

时间:2013-05-04 22:56:48

标签: opengl-es 2d gpu mipmaps

我为我的应用UI建立了一个基于场景图的渲染系统(http://audulus.com如果你很好奇)。应用程序的用户界面是程序性的,很多都是动画的。预渲染图像很少。

目前,它在mipmapped纹理中缓存不变的drawable组。我使用mipmap,因为UI是可缩放的。总的来说,这是一个巨大的表现胜利,但有几个缺点:

  1. 构建mipmap(通过glGenerateMipmap)需要时间,当UI的一部分从动画变为静态时,会降低帧速率。

  2. 纹理缓存几何体之间的视觉差异,导致轻微闪烁。 (可以通过我的路径渲染代码更聪明来解决这个问题,但似乎很难)

  3. 所有纹理的内存使用情况(我可以转储屏幕外纹理,但这会加剧问题1)

  4. 我想到的几种替代方法:

    1. 而不是纹理缓存,将静态路径合并到更大的路径中。我的路径已经基于VBO / VAO,但这可能会减少GL呼叫的数量。 (当关闭纹理缓存时,我的性能主要是CPU限制的)。内存使用率大赢。这种方法的主要问题是:使我的路径渲染着色器复杂化(因为它必须在一次调用glDrawArrays的过程中处理具有不同属性的路径),不处理其他原语(如文本)的缓存,以及更多的GPU负担而不是简单地渲染纹理。

    2. 仍然使用纹理,但避免使用mip-mapping。随着UI的缩放,纹理可以调整大小(尽管这可能必须延迟,因为在缩放期间重新渲染整个UI太昂贵了)。删除屏幕外几何体的纹理。当然,缺点是在UI缩放期间纹理放大/缩小较差。

    3. 更新

      我试过(2)。调整纹理的大小非常慢,因此我阻止UI在缩放期间调整它们的大小。这种方法运行得相当不错,但是从缩小开始时放大率看起来很糟糕:

      Poor magnification

      请注意,某些模块不是纹理缓存的,因为它们被标记为动画。

      更新2

      我开始研究方法1,所以我停用了纹理缓存。

      虽然我受CPU限制,但实际上我所有的GPU端负载来自我的路径抗锯齿片段着色器。以下是性能的表现:

      Performance with Path-AA shader active

      关闭它:

      Performance with Path-AA shader deactivated

      因此,进一步优化这将是GPU方面的一大胜利。我尝试放弃它并使用4倍超级采样,但这看起来像垃圾,提醒我为什么我花了相当多的时间在路径渲染着色器上工作。

1 个答案:

答案 0 :(得分:0)

方法(1)是一个很大的胜利。它与纹理缓存具有基本相同的性能,但没有任何可视化工件或大量内存使用。

enter image description here