gpt4 book ai didi

optimization - 在像素着色器中实现卷积过滤器的最有效方法是什么?

转载 作者:行者123 更新时间:2023-12-03 15:27:16 29 4
gpt4 key购买 nike

在像素着色器中实现卷积对于非常多的纹理提取来说有些昂贵。

实现卷积过滤器的一种直接方法是使用每个片段的两个循环对每个片段进行 N x N 次查找。一个简单的计算表明,使用 4x4 高斯内核模糊的 1024x1024 图像需要 1024 x 1024 x 4 x 4 = 16M查找。

对此我们能做些什么?

  • 可以使用一些需要较少查找的优化吗?我对像 Gaussian 那样的内核特定优化不感兴趣(或者它们是内核特定的?)
  • 至少可以通过以某种方式利用像素的局部性来更快地进行这些查找吗?

  • 谢谢!

    最佳答案

    高斯内核是可分离的,这意味着您可以先进行水平传递,然后进行垂直传递(或相反)。这将 O(N^2) 变成 O(2N)。这适用于所有可分离过滤器,而不仅仅是模糊(并非所有过滤器都是可分离的,但许多过滤器是可分离的,有些是“一样好”)。

    或者,在模糊过滤器(高斯或非高斯)的特殊情况下,它们都是“加权和”,您可以利用纹理插值,这对于小内核尺寸可能更快(但对于大内核尺寸绝对不是) )。

    编辑:“线性插值”方法的图像

    The "linear interpolation method"

    编辑(根据 Jerry Coffin 的要求)总结评论:

    在“纹理过滤器”方法中,线性插值将根据从样本位置到纹素中心的反距离产生相邻纹素的加权和。这是由纹理硬件免费完成的。这样,16 个像素可以在 4 次提取中求和。除了分离内核之外,还可以利用纹理过滤。

    在示例图像中,在左上角,您的样本(圆圈)击中了纹素的中心。你得到的和“最近的”过滤一样,你得到那个 texel 的值。在右上角,您位于两个纹素之间,您得到的是它们之间的 50/50 平均值(由较浅的蓝色着色器显示)。在右下角,您在 4 个纹素之间进行采样,但与左上角更接近一些。这为您提供了所有 4 个的加权平均值,但权重偏向左上角(最深的蓝色阴影)。

    以下建议由 友情提供datenwolf (见下文):

    “我想建议的另一种方法是在傅立叶空间中操作,其中卷积变成傅立叶变换信号和傅立叶变换内核的简单乘积。尽管在 GPU 上实现傅立叶变换本身非常繁琐,至少使用 OpenGL 着色器是这样。但是在OpenCL中很容易完成。实际上我使用OpenCL实现了这些东西,现在,我的3D引擎中的很多图像处理都发生在OpenCL中。

    OpenCL 专为在 GPU 上运行而设计。快速傅立叶变换实际上是维基百科 OpenCL 文章中的一段示例代码:en.wikipedia.org/wiki/OpenCL,是的,性能提升是巨大的。 FFT 最多执行 O(n log n),反之亦然。可以预先计算滤波器内核傅立叶表示。方法是 FFT -> 与内核相乘 -> IFFT,归结为 O(n + 2n log n) 操作。请注意,那里的实际卷积只是 O(n)。

    在可分离的有限卷积(如高斯模糊)的情况下,分离解决方案将优于傅立叶方法。但是在广义的、可能的不可分离内核的情况下,傅立叶方法可能是可用的最快方法。
    OpenCL 与 OpenGL 很好地集成,例如您可以将 OpenGL 缓冲区(纹理和顶点)用于 OpenCL 程序的输入和输出。”

    关于optimization - 在像素着色器中实现卷积过滤器的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5243983/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com