5

我已经为我的应用程序的 UI 构建了一个基于场景图的渲染系统(如果您好奇,请访问http://audulus.com )。该应用程序的 UI 是程序化的,其中很多是动画的。很少有预渲染的图像。

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

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

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

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

我想到的几种替代方法:

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

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

更新

我试过(2)。调整纹理的大小非常慢,所以我阻止 UI 在缩放期间调整它们的大小。这工作得相当好,但是从小开始缩放时放大倍率看起来很糟糕:

放大倍率差

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

更新 2

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

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

激活路径 AA 着色器时的性能

关闭它:

禁用路径 AA 着色器时的性能

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

4

1 回答 1

0

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

在此处输入图像描述

于 2014-05-20T18:57:52.700 回答