Случайные скорости при использовании симуляционного шейдера

Я пытаюсь реализовать симуляцию 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, шейдеры, основанные на симуляции, ведут себя на первый взгляд случайным образом, будет с благодарностью.

2 ответа

Решение

Оказывается, я неправильно перебирал грани. Вот моя новая краевая итерация:

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++;


        }
    }

}

Это не кажется случайным, конструкция стабилизируется в, казалось бы, правильном состоянии и движется в постоянном направлении.

Похоже, что вы применяете силу в шейдере, а затем обновляете позицию вашей модели на стороне ЦП, и эта глобальная позиция модели должна оставаться постоянной, либо должна была быть обновлена ​​другим значением.

Из того, что я видел в коде, я рекомендую исключить компиляцию с плавающей запятой (compareNodePosition.w == -1.0 || 0.0) и продолжить оператор. Скажите, пожалуйста, помогло ли это. Я еще не изучал логику алгоритмов.

Другие вопросы по тегам