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