2015-10-20 20 views
0

我的算法对于聚类很简单,它就是这样。GPU中的对象聚类

第一个对象被所有其他对象组成,它们之间的距离越低X. 然后我们转到第二个对象,如果没有包含在第一个组中,我们对其他对象运行相同的算法不包括在第一组, 等等......

我想在GPU中使用片段着色器做这个算法。 首先,我将所有位置设置为RGBA浮动纹理。为每个像素设置位置(x,y) - z和w现在是空闲的。然后我使用着色器绘制结果纹理我的计算结果。最后,我将读取结果纹理的像素并执行我的代码。

尝试了很多代码的变化,并且为了执行我的算法绘制了多个阶段,但我对时间表现并不满意。

问题是, 有没有办法让一个人跑过纹理来执行我的愿望(单绘制阶段)?

我最新的尝试是这样的算法 - 我的片段着色器

precision highp float; 

uniform sampler2D locs; 
varying vec2 coord; 
uniform float clusterDistance; 
const float textureSize = 64.; 

void main() 
{ 
    // Getting my location 
    vec4 currData = texture2D(locs, coord); 
    float offsetPix = 1./textureSize/2.; 
    vec2 coordIdx = (coord - offsetPix) * textureSize; 
    // Getting the index of my location 
    float myIdx = coordIdx.y * textureSize + coordIdx.x; 
    int clusterIdx = 0; 
    float clusterNum = 0.; 
    // Running over all the other locations until me and finding the first close object to me 
    for (float i=0.;i<textureSize*textureSize;++i) 
    { 
     clusterNum = i +1.; 
     // Which mean that we didn't find any closed object to me so we stop 
     if (i == myIdx) 
     { 
      break; 
     } 
     else 
     { 
      vec2 pntLoc = vec2(mod(i, textureSize), floor(i/textureSize))/textureSize+offsetPix; 
      vec4 pnt = texture2D(locs, pntLoc); 
      if (distance(currData.xy, pnt.xy) <= clusterDistance) 
      { 
       break; 
      } 
     } 
    } 

    // Print the result 
    gl_FragColor = vec4(currData.x, currData.y, clusterNum, 1.); 
} 

但这里的问题是,结果可能会导致链集群。例如。如果我们的数据是{0,0},{4,0},{8,0},并且组的最大距离是4,那么我们的数据是第一个数据库。然后第一个数据库关闭到第二个数据库。然后第三个接近第二个但不是第一个。根据我的算法,它返回的是第二个索引,尽管第二个索引不在图片中,因为它是按第一个对象分组的,而第一个是距离的参考对象。

在写入结果纹理时可以读取结果纹理吗?

这将解决我的问题,因为那样比较距离时,我可以检查结果的Z值..

回答

0

不,你不能读取和写入到同一通纹理(标准WebGL和我不要以你打算的方式思考)。你的算法看起来相当连续,不太适合GPU/SIMD执行,但我可能会误解你的意图。请记住,GPU可能会一次运行多个数据点(在这种情况下为片段/像素)的着色器程序,并不知道其他人的结果。 您也无法摆脱SIMD体系结构上的for循环。 for循环只会继续迭代,尽管这些变化不会写入碎片中。换句话说,没有速度优势。如果中断条件对所有片段评估的值相同,则情况会有所不同。

您可能想要查看其他聚类方式,如k-means。

+0

有关从外观上的突破的良好信息。不知道。对于我知道的其他问题。这种情况是否存在适合GPU的不同算法。关于K-means,我已经考虑过了,但我的客户希望根据距离而不是群体数量来建立群集。 (如果我正确理解K-means) –

+0

K-means的确使用距离作为基础,但它也需要你定义起始质心(聚类中心,你可以随机选择一个数据点)。还有其他的算法,但我必须承认,我不认识他们。 编辑:你可能想看看[this](https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set),尤其是引言。 –