Доступ к данным VBO/VAO в шейдере GLSL

Как в vertex shader можно заставить функцию в shader обращаться к определенному значению массива атрибутов после буферизации данных вершины в VBO?

В shader ниже функция cmp() предназначена для сравнения юниформ-переменной с vertex i.

#version 150 core

in vec2 vertices;
in vec3 color;
out vec3 Color;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

uniform vec2 cmp_vertex; // Vertex to compare
out int isEqual;         // Output variable for cmp()

// Comparator 
vec2 cmp(){
  int i = 3; 
  return (cmp_vertex == vertices[i]); 
}

void main() {
    Color = color;
    gl_Position = projection * view * model * vec4(vertices, 0.0, 1.0);
    isEqual = cmp();
}

Кроме того, можно ли изменить cmp() так, чтобы сравнение выполнялось параллельно?


person GoofyBall    schedule 08.10.2015    source источник


Ответы (1)


Судя по названию в коде вашего шейдера и формулировке вашего вопроса, похоже, вы неправильно поняли концепцию вершинных шейдеров.

Вершинный шейдер вызывается один раз для каждой вершины. Таким образом, когда ваш код вершинного шейдера выполняется, он всегда работает с одной вершиной. Это означает, что имя вашей переменной in вводит в заблуждение:

in vec2 vertices;

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

in vec2 vertex;

Как только вы поймете, что работаете с одной вершиной, все остальное станет проще. Для сравнения:

bool cmp() {
    return (cmp_vertex == vertex); 
}

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

У вас, вероятно, будет больше проблем с достижением того, что вам нужно. Но я надеюсь, что это поможет вам хотя бы преодолеть начальное препятствие.

Например, следующая переменная out вызывает проблемы:

out int isEqual;

out переменных вершинного шейдера имеют соответствующие in переменные фрагментного шейдера. По умолчанию значение, записанное вершинным шейдером, линейно интерполируется по треугольникам, а фрагментный шейдер получает интерполированные значения. Это не поддерживается для переменных типа int. Они поддерживают только плоскую интерполяцию:

flat out int isEqual;

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

person Reto Koradi    schedule 09.10.2015
comment
Хорошо, но я все еще не уверен, что происходит, когда мой вызов отрисовки использует массив вершин, которые находятся в VBO. GLfloat vertices[] = {-1.0f, 1.0f,..., 1.0f, 1.0f,..., 1.0f, -1.0f,..., -1.0f, -1.0f,..., . . . . . . }; Я знаю, как указать атрибуты массива вершин, но как тогда атрибут вершины обращается к каждой вершине? - person GoofyBall; 09.10.2015
comment
Чтобы уточнить, в моем вызове отрисовки: drawArrays(GL_TRIANGLES, n * 3, GL_UNSIGNED_INT, 0); как vertex соответствует массиву из n * 3 вершин? - person GoofyBall; 09.10.2015