我正在尝试使用着色器实现Fruchterman Reingold模拟。在着色器中实现计算部分之前,我在javascript中编写了它。它完全按照我的预期工作,如下所示:
http://jaredmcqueen.github.io/gpgpu-force-direction/canvas_app.html
在着色器中实现计算部分时,我得到一个在屏幕上随机漂移的稳定结构。我无法弄清楚是什么排斥力/吸引力导致我的图形以不可预测的方式浮动:
http://jaredmcqueen.github.io/gpgpu-force-direction/gpgpu_app.html
物理学的核心来自排斥/吸引功能:
//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,基于模拟的着色器看似随机行为的见解都将非常感激。
答案 0 :(得分:0)
它似乎并不随机,建筑在看似正确的状态稳定并向不断的方向移动。
看起来你在着色器中应用了force然后在CPU端更新模型的位置,这个全局模型位置应该保持不变,或者应该被另一个值更新。
从我在代码中看到的,我建议消除浮点数比较( compareNodePosition.w == -1.0 || 0.0 )和继续运算符。请说它是否有帮助。我还没有研究算法逻辑。
答案 1 :(得分:0)
事实证明我错误地迭代了边缘。这是我的新边缘迭代:
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++;
}
}
}