dte*_*ech 4 qt components caching image qml
编辑:原来的问题仍然包含在下面,但我决定重新命名为一个表单,该表单在各种情况下对开发人员更有用,其中一些在我的回答中描述,因为原始问题的解决方案变成了提供更广泛的应用领域。
我有一组应用程序的灰度图标,并且要求用户可以更改图标颜色。
因此,显而易见的解决方案是使用Colorize
中的库存元素QtGraphicalEffects
。
效果本身有一个cached
属性 - 缓存该特定效果的结果,以便它不会连续计算。但是,这仅适用于该效果的特定实例,这意味着如果有多个图标实例,并且每个图标实例都有着色效果,则该缓存不会在不同实例之间共享。
显然,考虑到所有图标都具有相同的大小和颜色,并且可以重用 VRAM 中的数据,从而节省 VRAM 和 GPU 时间,单个缓存就足够了。
因此,最大的问题是如何重用该单一效果的单一缓存并多次显示它而不产生任何开销。
另外,上一个问题是关于我当前学习的图标着色课程。但是,我可能缺少另一种方法。
当然,效率是关键,但简单性也是需要的,我的意思是我可以想到几种低级方法来非常有效地做到这一点,但它们都需要更复杂的低级实现,它们在 QML 中不可能做到。
结果发现解决方案出乎意料地简单。
在这种情况下,特定于 OP - 即着色图标,最有效的方法是简单地使用ShaderEffect
带有简单片段着色器的自定义 - 设置gl_FragColor
为所需的颜色,作为 avec4
和来自源图像的 alpha 值传递。实际上不需要缓存任何东西,因为着色器非常简单且快速,尽可能快。
只有一件事需要考虑 - QML 场景图可能会在纹理图集中分配原始图像,默认实现会将纹理从图集中复制到另一个纹理。我们不希望这样做,因为它违背了目的 - VRAM 使用量将会上升,因为这将为每个“实例”完成,并且新分配的纹理也有可能比它们需要的更大,因为在某些平台上,纹理的大小是有限制的,在这种情况下我们谈论的是图标,所以它们不会那么大。
解决方案是显式设置supportsAtlasTextures
为 true。这意味着您还必须传递图集中纹理的偏移量并计算偏移量 - 开销仍然很小。这将确保效率,来自图集的纹理不会在内存中重复,此外,渲染引擎实际上允许使用来自同一图集的不同纹理在一次调用中批量处理不同的着色器效果。
类似的方法可用于缓存几乎所有内容,并使用该缓存来显示“图像” - 使用 aShaderEffectSource
来“捕获”所需的图像,然后将 aShaderEffect
与更简单的片段着色器一起使用 - 只需从源采样器。我立即想到了几个非常有用的用例:
ShaderEffectSource
s 和ShaderEffect
s 可以按任意顺序链接它可以用作图像,由复杂的 QML 组合生成Item
- 这些实际上对 RAM 的占用很大,想象一下这样的场景:您有 1000 个对象,每个对象都由 20 个不同的 QML 项组成 - 矩形,文本、图像、上帝禁止动画,内存中有 20000 个对象 - 根据我的测试,这相当于 500 MB 的 RAM 使用量,但如果它们相同,则可以使用单个对象来提供缓存,而所有其他对象只能使用显示该缓存的单个着色器效果。它对 CPU 时间也有影响 - 假设你的设计必然会改变值 - 这是一个非常常见的场景,如果内存中有 20000 个对象,那就是 20000 个评估的绑定 - 即使对于简单的表达式,这在移动设备上也可能需要几秒钟,在此期间冻结屏幕。缓存将冻结时间减少 1000 倍,几乎不存在。
它还可以用于缓存和实例化动画,显着减少所需的 CPU 时间,并且还可以处理视频
归档时间: |
|
查看次数: |
2209 次 |
最近记录: |