Не можете получить доступ к массиву отсеченных плоскостей, хранящихся в одном UBO OpenGL? - PullRequest
0 голосов
/ 06 мая 2019

Как описано в постобработке вершин OpenGL https://www.khronos.org/opengl/wiki/Vertex_Post-Processing В разделе «Пользовательское вырезание» я пытаюсь обрезать каждую отправленную вершину на плоскости в вершинном шейдере. Предоставляя только индекс для каждой вершины, чтобы я мог получить доступ к данным UBO, которые содержат информацию о плоскости отсечения, определенную и отправленную до фактической передачи больших данных.

"... Можно смягчить это, используя UBO для хранения массива областей отсечения, при этом каждая вершина просто указывает целочисленный индекс в этом массиве ...."

Проблема в том, что каким-то образом я не могу получить доступ к UBO с помощью простой индексации, потому что отправленный вместе буфер индекса индекса просто отказывается работать, хотя данные полны и верны. (Проверено в NSight).

Графический процессор просто думает, что я хочу получить доступ только к первому прямоугольнику отсечения. (ClipIndex всегда равен нулю); Так что это работает только для первого окна в моем простом imgui.

Итак, я слышал, что OpenGL не принимает индексацию начиная с версии 1.2 или чего-то в этом роде. Это причина ??? Они даже установили жесткое ограничение на размер UBO (я думаю, 6 КБ). Какова же причина, по которой я не могу получить доступ к своим данным? Я могу получить тексель из любой точки текстуры, но не могу получить некоторые простые данные с буфером постоянного размера.

Он компилируется чисто, я проверил ошибки и проверил программу. Также ссылки в порядке. Если я установлю его в вершинный шейдер, он будет работать нормально. Это означает, что если я хочу обрезать только для первого окна (Clip.Rects [1]), нет проблем. Когда я представлю один непрерывный массив индексов, мы вышли из игры. Массив всегда обрабатывается так, как если бы он был заполнен нулями.

Я знаю, что код не может быть оптимальным. Пока мы пытаемся достичь рабочей фазы.

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

Альтернативы, на мой взгляд, состоят в том, чтобы нарисовать 6 или менее вершин на прямоугольник, и каждый раз, когда мне нужно обрезать плоскость, делайте это вручную, изменяя glScissor () или glClipPlane (). И второе, что приходит на ум, это использовать текстуру для хранения данных, что мне не нравится, потому что это не текстура: D.

Почему мой подход нарушен? И есть ли лучшие способы обрезать один непрерывный массив данных вершин в нескольких плоскостях?

   #version 400 core
   struct rect 
   {
    float X;
    float Y;
    float Width;
    float Height;
   };

   layout (shared) uniform clip_rects
   {
    rect Rects[50];
   } Clip;

   out float gl_ClipDistance[6]; // Clipping each vert to a rectangle plane

   // Skippied some unrelated info colors depth...
   in vec2 RectVBO;
   in int ClipIndex;

   uniform mat4 PCMatrix;

   void main()
   {
         gl_Position = PCMatrix * vec4(RectVBO.xy, Depth, 1.0f);

         //FIRST ATTEMPT (already in -1,1 space)
     vec2 v0 = vec2(Clip.Rects[ClipIndex].X, Clip.Rects[ClipIndex].Y);
     vec2 v1 = vec2(Clip.Rects[ClipIndex].X + Clip.Rects[ClipIndex].Width, Clip.Rects[ClipIndex].Y);
     vec2 v2 = vec2(Clip.Rects[ClipIndex].X + Clip.Rects[ClipIndex].Width, Clip.Rects[ClipIndex].Y + Clip.Rects[ClipIndex].Height);
     vec2 v3 = vec2(Clip.Rects[ClipIndex].X, Clip.Rects[ClipIndex].Y + Clip.Rects[ClipIndex].Height);
         //END OF FIRST ATTEMPT

         //Even this doesn't work!
         //SECOND ATTEMPT

         vec2 v0 = vec2(0.0f,0.0f);
     vec2 v1 = vec2(0.0f,0.0f);
     vec2 v2 = vec2(0.0f,0.0f);
     vec2 v3 = vec2(0.0f,0.0f);
         //NOTE: It only takes the first if block if we set it to 1, 2, 3
         //for example its all set to the above zeroed out vec2s.
         if(ClipIndex == 0)
     {
    v0 = vec2(Clip.Rects[0].X, Clip.Rects[0].Y);
    v1 = vec2(Clip.Rects[0].X + Clip.Rects[0].Width, Clip.Rects[0].Y);
    v2 = vec2(Clip.Rects[0].X + Clip.Rects[0].Width, Clip.Rects[0].Y + Clip.Rects[0].Height);
    v3 = vec2(Clip.Rects[0].X, Clip.Rects[0].Y + Clip.Rects[0].Height);
     }
     else if(ClipIndex == 1)
     {
    v0 = vec2(Clip.Rects[1].X, Clip.Rects[1].Y);
    v1 = vec2(Clip.Rects[1].X + Clip.Rects[1].Width, Clip.Rects[1].Y);
    v2 = vec2(Clip.Rects[1].X + Clip.Rects[1].Width, Clip.Rects[1].Y + Clip.Rects[1].Height);
    v3 = vec2(Clip.Rects[1].X, Clip.Rects[1].Y + Clip.Rects[1].Height);
    } else if(ClipIndex == 2)
    {
    v0 = vec2(Clip.Rects[2].X, Clip.Rects[2].Y);
    v1 = vec2(Clip.Rects[2].X + Clip.Rects[2].Width, Clip.Rects[2].Y);
    v2 = vec2(Clip.Rects[2].X + Clip.Rects[2].Width, Clip.Rects[2].Y + Clip.Rects[2].Height);
    v3 = vec2(Clip.Rects[2].X, Clip.Rects[2].Y + Clip.Rects[2].Height);
    }

         // END OF SECOND ATTEMPT

         //Tried "local" variable indexing still no progress.
        //THIRD ATTEMPT
vec2 v0 = vec2(0.0f,0.0f);
vec2 v1 = vec2(0.0f,0.0f);
vec2 v2 = vec2(0.0f,0.0f);
vec2 v3 = vec2(0.0f,0.0f);

for(int k = 0; k < 3; k++)
{
    if(k == ClipIndex)
    {
        v0 = vec2(Clip.Rects[k].X, Clip.Rects[k].Y);
        v1 = vec2(Clip.Rects[k].X + Clip.Rects[k].Width, Clip.Rects[k].Y);
        v2 = vec2(Clip.Rects[k].X + Clip.Rects[k].Width, Clip.Rects[k].Y + Clip.Rects[k].Height);
        v3 = vec2(Clip.Rects[k].X, Clip.Rects[k].Y + Clip.Rects[k].Height);
    }
}
         //END OF THIRD ATTEMPT

     vec2 VecToVertex0 = gl_Position.xy - v0;
     vec2 VecToVertex1 = gl_Position.xy - v1;
     vec2 VecToVertex2 = gl_Position.xy - v2;
     vec2 VecToVertex3 = gl_Position.xy - v3;

     vec2 v0v1 = v1 - v0;
     vec2 v1v2 = v2 - v1;
     vec2 v2v0 = v0 - v2;

     vec2 v0v2 = v2 - v0;
     vec2 v2v3 = v3 - v2;
     vec2 v3v0 = v0 - v3;

     gl_ClipDistance[0] = dot(v0v1, VecToVertex0);
     gl_ClipDistance[1] = dot(v1v2, VecToVertex1);
     gl_ClipDistance[2] = dot(v2v0, VecToVertex2);

     gl_ClipDistance[3] = dot(v0v2, VecToVertex0);
     gl_ClipDistance[4] = dot(v2v3, VecToVertex2);
     gl_ClipDistance[5] = dot(v3v0, VecToVertex3);


     }
...