Alb*_*ore 15 opengl optimization shader glsl
在像素着色器中实现卷积对于非常大量的纹理提取而言有些代价.
实现卷积滤波器的直接方法是对每个片段进行N×N个查找,每个片段使用两个循环.一个简单的计算表明,使用4x4高斯内核模糊的1024x1024图像需要1024 x 1024 x 4 x 4 = 16M查找.
人们可以做些什么呢?
谢谢!
Dam*_*mon 19
高斯核是可分离的,这意味着你可以先进行水平传递,然后进行垂直传递(或反过来).这将O(N ^ 2)变为O(2N).这适用于所有可分离的滤镜,不仅适用于模糊(并非所有过滤器都是可分离的,但许多过滤器都是可以分离的,而且有些过滤器是"一样好").
或者,在模糊滤波器(高斯或非高斯)的特定情况下,它们都是"加权和",您可以利用纹理插值,对于小内核大小可能更快(但最终不适用于大内核大小) ).
编辑:图像为"线性插值"方法

编辑(根据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程序的输入和输出."
| 归档时间: |
|
| 查看次数: |
12764 次 |
| 最近记录: |