Glsl 使用模拟着色器时的随机速度

Glsl 使用模拟着色器时的随机速度,glsl,webgl,shader,simulation,physics,Glsl,Webgl,Shader,Simulation,Physics,我正在尝试使用着色器实现Fruchterman Reingold模拟。在着色器中实现计算部分之前,我用javascript编写了它。它的工作原理与我的预期完全一致,如下所示: 在着色器中实现计算部分时,我得到了一个在屏幕上随机漂移的稳定结构。我无法理解是什么排斥力/吸引力导致我的图表如此不可预测地四处浮动: 物理学的核心是排斥/吸引函数: //fr(x) = (k*k)/x; vec3 addRepulsion(vec3 self, vec3 neighbor){ vec3 diff

我正在尝试使用着色器实现Fruchterman Reingold模拟。在着色器中实现计算部分之前,我用javascript编写了它。它的工作原理与我的预期完全一致,如下所示:

在着色器中实现计算部分时,我得到了一个在屏幕上随机漂移的稳定结构。我无法理解是什么排斥力/吸引力导致我的图表如此不可预测地四处浮动:

物理学的核心是排斥/吸引函数:

//fr(x) = (k*k)/x;
vec3 addRepulsion(vec3 self, vec3 neighbor){
    vec3 diff = self - neighbor;
    float x = length( diff );
    float f = ( k * k ) / x;
    return normalize(diff) * f;
}

//fa(x) = (x*x)/k;
vec3 addAttraction(vec3 self, vec3 neighbor){
    vec3 diff = self - neighbor;
    float x = length( diff );
    float f = ( x * x ) / k;
    return normalize(diff) * f;
}

任何关于gpgpu、基于模拟的着色器为何会表现出看似随机的行为的见解都将受到极大的赞赏。

它似乎不是随机的,结构在看似正确的状态下稳定,并以恒定的方向向外移动

看起来您在着色器中应用了力,然后更新了模型在CPU端的位置,并且这个全局模型位置应该保持不变,或者应该由另一个值更新


从我在代码中看到的情况来看,我建议消除浮点压缩(compareNodeDeposition.w==-1.0 | | 0.0)和continue运算符。请说它是否有用。我还没有研究算法逻辑。

结果表明,我对边缘进行了错误的迭代。以下是我的新edge迭代:

float idx = selfEdgeIndices.x;
float idy = selfEdgeIndices.y;
float idz = selfEdgeIndices.z;
float idw = selfEdgeIndices.w;

float start = idx * 4.0 + idy;
float end = idz * 4.0 + idw;


if(! ( idx == idz && idy == idw ) ){

    float edgeIndex = 0.0;

    for(float y = 0.0; y < edgesTexWidth; y++){
        for(float x = 0.0; x < edgesTexWidth; x++){


        vec2 ref = vec2( x + 0.5 , y + 0.5 ) / vec2(edgesTexWidth,edgesTexWidth);
        vec4 pixel = texture2D(edgeData,ref);

        if (edgeIndex >= start && edgeIndex < end){
            nodePosition = getNeighbor(pixel.x);
            nodeDiff.xyz -= addAttraction(currentNodePosition.xyz, nodePosition);
        }
        edgeIndex++;

        if (edgeIndex >= start && edgeIndex < end){
            nodePosition = getNeighbor(pixel.y);
            nodeDiff.xyz -= addAttraction(currentNodePosition.xyz, nodePosition);
        }
        edgeIndex++;

        if (edgeIndex >= start && edgeIndex < end){
            nodePosition = getNeighbor(pixel.z);
            nodeDiff.xyz -= addAttraction(currentNodePosition.xyz, nodePosition);
        }
        edgeIndex++;

        if (edgeIndex >= start && edgeIndex < end){
            nodePosition = getNeighbor(pixel.w);
            nodeDiff.xyz -= addAttraction(currentNodePosition.xyz, nodePosition);
        }
        edgeIndex++;


        }
    }

}
float idx=selfEdgeIndices.x;
float-idy=自边缘属性y;
float idz=selfEdgeIndices.z;
浮动idw=自边缘标识。w;
浮动启动=idx*4.0+idy;
浮动端=idz*4.0+idw;
如果(!(idx==idz&&idy==idw)){
浮动边指数=0.0;
用于(浮动y=0.0;y=开始和边索引<结束){
nodePosition=getNeighbor(像素x);
nodeDiff.xyz-=添加吸引力(currentNodePosition.xyz,nodePosition);
}
edgeIndex++;
如果(边索引>=开始和边索引<结束){
nodePosition=getNeighbor(像素y);
nodeDiff.xyz-=添加吸引力(currentNodePosition.xyz,nodePosition);
}
edgeIndex++;
如果(边索引>=开始和边索引<结束){
nodePosition=getNeighbor(像素z);
nodeDiff.xyz-=添加吸引力(currentNodePosition.xyz,nodePosition);
}
edgeIndex++;
如果(边索引>=开始和边索引<结束){
nodePosition=getNeighbor(像素.w);
nodeDiff.xyz-=添加吸引力(currentNodePosition.xyz,nodePosition);
}
edgeIndex++;
}
}
}

我将重新查看定位代码,看看是否找到了gotchyasOk,我将研究消除浮点比较。我的项目中有很多移动部件,.w值由我在创建位置纹理时设置。它们不会在着色器中被覆盖-我只修改xyz值。如果您在开发控制台打开的情况下运行演示,w应该始终保持原样并提供纹理打印输出。最后一件事——我很确定算法还不错。我觉得我可能对不同的节点和边进行了太多的迭代,这就是我看到的额外速度的原因