OpenGL ES (2.0) Shading Language: Как ввести логическое значение в вершинный шейдер и перейти к фрагментному шейдеру? - PullRequest
9 голосов
/ 14 января 2012

Я пытаюсь передать логическое значение в мой вершинный шейдер впервые; До сих пор я использовал только поплавки.

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

Из спецификации Khronos кажется, что «варьирование» - это единственный способ передать данные в фрагментный шейдер, но неудивительно, что «варьирование bool my_bool»; вызывает синтаксический анализатор, когда он определен в моем вершинном шейдере.

Я передаю логическое значение в мой вершинный шейдер как:

attribute bool a_my_bool;

Я определяю вариацию при попытке перейти к фрагментному шейдеру:

varying bool v_my_bool;
void main() {
    // ...
    v_my_bool = a_my_bool;
}

Может кто-нибудь сказать мне, как я могу достичь того, что я намерен?

Ответы [ 2 ]

18 голосов
/ 21 марта 2012

Начиная с п. 4.3.5 из Язык затенения OpenGL® ES версия 1.0.17 (PDF) :

Можно использовать изменяющий квалификатортолько с типами данных float, vec2, vec3, vec4, mat2, mat3 и mat4 или их массивами.

И из §4.3.3:

Спецификатор атрибута может использоваться только с типами данных float, vec2, vec3, vec4, mat2, mat3 и mat4.Переменные атрибута не могут быть объявлены как массивы или структуры.

Таким образом, вы не можете иметь attribute bool, не говоря уже о varying bool, в соответствии со спецификацией.

Если выдействительно нужно логическое значение для каждой вершины, вы можете использовать 0,0 для ложного и 1,0 для истинного.При тестировании проверьте на x > 0.5.Например:

// vertex shader
attribute float a_my_bool;
varying float v_my_bool;
void main() {
    // ...
    v_my_bool = a_my_bool;
}

// fragment shader
varying float v_my_bool;
void main() {
    if (v_my_bool > 0.5) {
        // my_bool is true
        // ...
    } else {
        // my_bool is false
        // ...
    }
}

Пока все вершины в каждом треугольнике имеют одинаковое значение, это должно работать.Если они не согласованы, то вы получите разные фрагменты для одного и того же треугольника, которые ведут себя по-разному.(Если вы придерживаетесь 0,0 и 1,0, четверть треугольника, ближайшего к «нечетному» углу, будет вести себя иначе, чем остальные.)

4 голосов
/ 14 января 2012

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

В отношении переменных переменных одна из распространенных ошибок - не объявлять переменные в вершинных и фрагментных шейдерах и пропускать один из 2.

Это вызовет ошибку компоновки, и вы все равно заметите это, проверив результаты компиляции и компоновки.

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

...