Оптимизация обхода BVH с помощью графического процессора

Я создал ограничивающую иерархию томов, которая генерируется каждый кадр. Из-за его использования каждый узел должен иметь двух дочерних элементов, ни больше, ни меньше.

Обход - единственное самое дорогое вычисление для моей программы на данный момент, и он предотвращает запуск больших сцен (>2k треугольников) с приемлемой частотой кадров. Я в недоумении относительно того, как это может быть выполнено быстрее. Простой квадрат с 16 треугольниками вносит заметное падение кадра, когда через него проходит много лучей.

Чтобы обойти это, я использовал концепции, приведенные в статье по этой ссылке, где каждая нить пересекает следующий код.

Что можно сделать, чтобы увеличить скорость?

На данный момент эта функция используется в гораздо более крупном ядре. Поможет ли его изоляция внутри собственного вызова диспетчеризации за счет использования большего объема памяти для хранения выходных данных?

//o= origin , d =direction, bestT = the intersection distance

bool FindBVHIntersect(vec3 o, vec3 d,inout float bestT){ 

//starting at the root of the bvh(0) the locations of the two children are found (near , far)

uint current=0;
uint last=0;
uint near=uint(bvh[current].w);
uint far=uint(bvh[current+1].w);

//max distance to test intersection
float distance=4294967295.0f;
bool success=false;
bool run= true;

while(run){

//update the children's location
near=uint(bvh[current].w);
far=uint(bvh[current+1].w);

//traversing up from the last child

//ending
if(last==far&&current==0){
run=false;
continue;
}
//go to the parent of the node
else if(last==far){
last=current;
current=bvhAtomics[current/2].y;
continue;
}

//depending on the last position, pick a child
uint tryChild= (last==bvhAtomics[current/2].y)?near:far;

bool delve;
//test the AABB
if(tryChild==near){
delve=FindAABBIntersect(bvh[current].xyz,bvh[current+1].xyz,o,d,0.0f,distance);
}
else{
delve=true;
}

//if the child is a node and needs to be delved.  A triangle intersection test.
if(delve&&tryChild>=(nodeSize-1)*2){

    float pt;
    float ob1;
    float ob2; 

    uint bvhPos=uint(bvh[tryChild+2].x);
    uvec3 indPos=indices[bvhPos].xyz;

    bool tr = FindTriangleIntersect(vertices[indPos.x].xyz, vertices[indPos.y].xyz,     vertices[indPos.z].xyz, o, d, pt, ob1, ob2 );
        if(tr){ 
            distance=pt;
            float t = pt;

            if (t > 0 && t < bestT) {
                bestT = t;
                success=true;
            }

        }

last=tryChild;
}

//switching children or setting up for climbing up the tree
else if(delve){

last =current;
current=tryChild;

}
else{       

last=far;
}


}

return success;
}

Я пытался минимизировать доступ к памяти в контексте алгоритма, однако расхождение, которое, как я полагаю, является проблемой, кажется невозможным преодолеть препятствие.

0 ответов

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