Странная шейдерная коррупция - PullRequest
0 голосов
/ 26 сентября 2011

Я сейчас работаю с шейдерами и наблюдаю очень странное поведение. Я загрузил этот вершинный шейдер:

#version 150

uniform float r;
uniform float g;
uniform float b;
varying float retVal;
attribute float dummyAttrib;

void main(){
    retVal = dummyAttrib+r+g+b; //deleting dummyAttrib = corruption
    gl_Position = gl_ModelViewProjectionMatrix*vec4(100,100,0,1);
}

Прежде всего, я визуализирую с помощью glDrawArrays(GL_POINTS,0,1000) с помощью этого шейдера, ничего особенного, просто используя программу шейдера. Если вы запустите этот шейдер и установите размер точки на что-то видимое, вы должны увидеть белый квадрат в середине экрана (я использую glOrtho2d(0,200,0,200)). DummyAttrib - это просто атрибут: мои шейдеры не будут работать, если их нет. Также мне нужно использовать этот атрибут, поэтому обычно я делаю что-то вроде float c = dummyAttrib. Это также первый вопрос, который я хотел бы задать, почему это так.

Однако это было бы хорошо, но когда вы изменили строку с комментарием (retval=...) на retVal = r+g+b; и добавили упомянутую строку для использования attrib (float c = dummyAttrib), происходят странные вещи. Прежде всего, вы больше не увидите этот квадрат, поэтому мне пришлось настроить обратную связь трансформации, чтобы посмотреть, что происходит.

Я установил dummyAttrib на 5 в каждом элементе поля и r = g = b = 1. С текущим кодом результат обратной связи преобразования равен 8 - именно то, что вы ожидаете. Однако его изменение, как указано выше, дает странные значения, такие как 250.128, и каждый раз, когда я каким-либо образом изменяю код (просто изменяю порядок вызовов), это значение изменяется. Как только я возвращаю dummyAttrib в расчет retVal, все магически исправлено.

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

Эти 2 проблемы могут быть связаны. Подводя итог: шейдер не будет работать без какого-либо атрибута, и шейдер будет поврежден, если этот атрибут не используется для установки переменных, которые используются либо в фрагментном шейдере, либо для обратной связи преобразования.

PS: Когда я писал это, мне пришло в голову, что все переменные, которые не используются для перехода на следующую стадию, исключены. Это может также отменить атрибут, и тогда этот шейдер будет без атрибута и не будет работать должным образом. Может ли это быть ошибкой водителя? У меня Radeon 3870HD с текущей версией катализатора 2010.1105.19.41785.

1 Ответ

1 голос
/ 26 сентября 2011

В случае вашего искусственного использования (float c = dummyAttrib) атрибут будет оптимизирован. Вопрос в том, что делает ваша логика подготовки меша в этом случае. Если он запрашивает используемые атрибуты из GL, он ничего не получит. И без переданных атрибутов вершин примитив не будет отрисован (поведение моего Radeon 2400HD на любом Catalyst).

Таким образом, в основном, вы должны передать искусственный неиспользуемый атрибут (что-то вроде 1 байта на вершину в неинициализированном буфере), если GL сообщает об атрибутах вообще.

...