Траверс октрея с использованием алгоритма Ревелса динамически однородным способом GLSL

Я пытаюсь пройтись по моей октри в моем вычислительном шейдере в GLSL (v450), используя алгоритм revelles с маршированием лучей в режиме реального времени. Мне удалось пройти через него, и я получил изображение, но мой fps очень низкий, около 0-5 кадров в секунду. Поскольку псевдокод алгоритмов является рекурсивным, я преобразовал его в цикл с использованием стека (поскольку GLSL не допускает рекурсию). Проблема в том, что как только я делаю этот цикл не динамически равномерным, я получаю огромное падение частоты кадров около 30-40.

Я могу восстановить этот fps, если я использую атрибут shared в моем стеке, доступный только в вычислительных шейдерах для глобальных переменных:

shared struct stack{

float tx0;
float tx1;

float ty0;
float ty1;

float tz0;
float tz1;

float txm;
float tym;
float tzm;

int currNode;
int node;


}travStack[10];

позволяя ему делиться и использовать его среди всех потоков в моей рабочей группе. Проблема заключается в том, что я не могу синхронизировать их с функциями барьера () и / или memoryBarrierShared(), так как кажется, что они нуждаются в том, чтобы цикл был динамически однородным (см. Общие переменные www.opengl.org/wiki/Compute_Shader). Поскольку я не могу синхронизироваться, изображение становится пиксельным и мерцает.

Есть ли способ преобразовать этот алгоритм в динамически однородный цикл? Почему fps падает, когда цикл становится не динамически однородным?

Ниже мой код основного цикла.

void traverse(vec3 rayOrigin, vec3 direction){

rayParameter(rayOrigin, direction); //Set parameters
stackRoot = true;
bool backfire = false;

//----
float tx0;
float tx1;

float ty0;
float ty1;

float tz0;
float tz1;

float txm;
float tym;
float tzm;
//----

int v;
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
int v7;

// Test variables
int itrCount = 0;
int itrCheck = 3;
int limit = 200;

stackPointer = 0;
if ((max(max(travStack[0].tx0, travStack[0].ty0), travStack[0].tz0)) < (min(min(travStack[0].tx1, travStack[0].ty1), travStack[0].tz1))){


    travStack[0].currNode = procSubtree(travStack[0].tx0, travStack[0].ty0, travStack[0].tz0, travStack[0].tx1, travStack[0].ty1, travStack[0].tz1, travStack[0].node);

    while (stackPointer >= 0 ){ //itrCount < limit){

        //----
        tx0 = travStack[stackPointer].tx0;
        tx1 = travStack[stackPointer].tx1;

        ty0 = travStack[stackPointer].ty0;
        ty1 = travStack[stackPointer].ty1;

        tz0 = travStack[stackPointer].tz0;
        tz1 = travStack[stackPointer].tz1;

        txm = travStack[stackPointer].txm;
        tym = travStack[stackPointer].tym;
        tzm = travStack[stackPointer].tzm;
        //----



        switch (travStack[stackPointer].currNode){

        case 0:
        {
                  if (!backfire){

                      stackPointer++;
                      int index = travStack[stackPointer - 1].node + a + a4 + a2;
                      v = procSubtree(tx0, ty0, tz0, txm, tym, tzm, treeArray[index]);

                      if (v == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = newNode(txm, 4, tym, 2, tzm, 1);

                      }
                      else{

                          travStack[stackPointer].currNode = v;
                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(txm, 4, tym, 2, tzm, 1);
                      backfire = false;

                  } 
                  break;
        }
        case 1:
        {
                  if (!backfire){

                      stackPointer++;
                      int index1 = travStack[stackPointer - 1].node + (1 - a) + a4 + a2;
                      v1 = procSubtree(tx0, ty0, tzm, txm, tym, tz1, treeArray[index1]);

                      if (v1 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = newNode(txm, 5, tym, 3, tz1, 8);

                      }
                      else{

                          travStack[stackPointer].currNode = v1;
                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(txm, 5, tym, 3, tz1, 8);
                      backfire = false;

                  }  
                  break;
        }
        case 2:
        {
                  if (!backfire){

                      stackPointer++;
                      int index2 = travStack[stackPointer - 1].node + (2 + a) + a4 - a2;
                      v2 = procSubtree(tx0, tym, tz0, txm, ty1, tzm, treeArray[index2]);

                      if (v2 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = newNode(txm, 6, ty1, 8, tzm, 3);

                      }
                      else{

                          travStack[stackPointer].currNode = v2;
                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(txm, 6, ty1, 8, tzm, 3);
                      backfire = false;

                  }
                  break;

        }
        case 3:
        {
                  if (!backfire){

                      stackPointer++;                     
                      int index3 = travStack[stackPointer - 1].node + (3 - a) + a4 - a2;
                      v3 = procSubtree(tx0, tym, tzm, txm, ty1, tz1, treeArray[index3]);

                      if (v3 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--; 
                          travStack[stackPointer].currNode = newNode(txm, 7, ty1, 8, tz1, 8);
                      }
                      else{

                          travStack[stackPointer].currNode = v3;

                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(txm, 7, ty1, 8, tz1, 8);                 
                      backfire = false;

                  }
                  break;

        }
        case 4:{

                   if (!backfire){

                       stackPointer++;
                       int index4 = travStack[stackPointer - 1].node + (4 + a) - a4 + a2;
                       v4 = procSubtree(txm, ty0, tz0, tx1, tym, tzm, treeArray[index4]);

                       if (v4 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                           stackPointer--;
                           travStack[stackPointer].currNode = newNode(tx1, 8, tym, 6, tzm, 5);

                       }
                       else{

                           travStack[stackPointer].currNode = v4;

                       }
                   }
                   else{

                       travStack[stackPointer].currNode = newNode(tx1, 8, tym, 6, tzm, 5);  
                       backfire = false;

                   }
                   break;

        }
        case 5:
        {
                  if (!backfire){

                      stackPointer++;
                      int index5 = travStack[stackPointer - 1].node + (5 - a) - a4 + a2;
                      v5 = procSubtree(txm, ty0, tzm, tx1, tym, tz1, treeArray[index5]);

                      if (v5 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = newNode(tx1, 8, tym, 7, tz1, 8);

                      }
                      else{

                          travStack[stackPointer].currNode = v5;

                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(tx1, 8, tym, 7, tz1, 8);
                      backfire = false;

                  } 
                  break;

        }
        case 6:
        {
                  if (!backfire){

                      stackPointer++;
                      int index6 = travStack[stackPointer - 1].node + (6 + a) - a4 - a2;
                      v6 = procSubtree(txm, tym, tz0, tx1, ty1, tzm, treeArray[index6]);

                      if (v6 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = newNode(tx1, 8, ty1, 8, tzm, 7);

                      }
                      else{

                          travStack[stackPointer].currNode = v6;

                      }
                  }
                  else{

                      travStack[stackPointer].currNode = newNode(tx1, 8, ty1, 8, tzm, 7);
                      backfire = false;

                  }
                  break;

        }
        case 7:
        {
                  if (!backfire){

                      stackPointer++;
                      int index7 = travStack[stackPointer - 1].node + (7 - a) - a4 - a2;
                      v7 = procSubtree(txm, tym, tzm, tx1, ty1, tz1, treeArray[index7]);

                      if (v7 == -1){ //Go up one level. Either hit empty, an edge or a leaf.

                          stackPointer--;
                          travStack[stackPointer].currNode = 8;

                      }
                      else{

                          travStack[stackPointer].currNode = v7;

                      }
                  }
                  else{

                      travStack[stackPointer].currNode = 8;
                      backfire = false;

                  }               
                  break;


        }



        }

        //itrCount++;
        if (noiseAlpha >= 1.0){
            break;
        }

        if (!(travStack[stackPointer].currNode < 8)){
            stackPointer--;         
            backfire = true;

        }



    }


  }

}

0 ответов

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