В настоящее время я пытаюсь реализовать трассировщик пути внутри фрагментного шейдера, который использует очень простую BVH
Код пересечения BVH основан на следующей идее:
bool BVHintersects( Ray ray ) {
Object closestObject;
vec2 toVisit[100]; // using a stack to keep track which node should be tested against the current ray
int stackPointer = 1;
toVisit[0] = vec2(0.0, 0.0); // coordinates of the root node in the BVH hierarcy
while(stackPointer > 0) {
stackPointer--; // pop the BVH node to examine
if(!leaf) {
// examine the BVH node and eventually update the stackPointer and toVisit
}
if(leaf) {
// examine the leaf and eventually update the closestObject entry
}
}
}
Проблема с приведенным выше кодом состоит в том, что при втором отскоке света происходит нечто очень странное, если предположить, что я рассчитываю отскок света следующим образом:
vec3 color = vec3(0.0);
vec3 normal = vec3(0.0);
// first light bounce
bool intersects = BVHintersect(ro, rd, color, normal);
vec3 lightPos = vec3(5, 15, 0);
// updating ray origin & direction
ro = ro + rd * (t - 0.01);
rd = normalize(lightPos - ro);
// second light bounce used only to calculate shadows
bool shadowIntersects = BVHintersect(ro, rd, color, normal);
Второй вызов BVHintersect будет выполняться бесконечно,потому что цикл while никогда не завершается, но из многих тестов, которые я сделал для этого второго вызова, я уверен, что stackPointer в конечном итоге успешно возвращается к 0, фактически, если я помещаю следующий код сразу под циклом while:
int iterationsMade = 0;
while(stackPointer > 0) {
iterationsMade++;
if(iterationsMade > 100) {
break;
}
// the rest of the loop
// after the functions ends it also returns "iterationsMade"
переменная "iterationsMade" всегда меньше 100, цикл while не работает бесконечно, но с точки зрения производительности это похоже на то, как если бы я делал "100" итераций, даже если "iterationsMade" никогда не больше, чем, скажем, 10 или20. Увеличение жестко закодированного значения «100» до большего значения может линейно ухудшить производительность
Что может бытьвозможные причины такого поведения?Какова возможная причина для того, чтобы второй вызов BVHIntersect застрял внутри цикла while, если он никогда не выполняет более 10-20 итераций?
Источник для функции BVHintersect: https://pastebin.com/60SYRQAZ