Подтвердить что ты не робот

Как вершинный шейдер передает информацию о цвете в фрагментарный шейдер?

В простой приветственной программе OpenGL, которая просто рисует статический треугольник в окне, когда я устанавливаю 3 вершины треугольника на красный, зеленый и синий цвета, треугольник заполняется градиентом.

Но когда я использую шейдеры следующим образом:

Vertex Shader:

attribute vec4 aVertex;
attribute vec4 aColor;

varying vec4 vColor;

void main(void) {
    gl_Position = gl_ModelViewMatrix * gl_ProjectionMatrix * aVertex;
    vColor = aColor;
}

где атрибуты aVertex и aColor поступают из буфера вершин, прошедшего через вызов glVertexAttribPointer.

Фрагментный шейдер:

varying vec4 vColor;
void main(void) {
    gl_FragColor = vColor;
}

Треугольник по-прежнему заполнен градиентом, и возникает вопрос:

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

Итак, откуда появился градиент?

Или, другими словами, когда это случилось, что в frag-shader, vColor оказывается интерполированным цветом вместо вершин?

4b9b3361

Ответ 1

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

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

Использование ключевого слова "flat" отключит интерполяцию и вместо этого будет использовать значение первой вершины (я не уверен на 100% "плоский" работает с изменением, поскольку я переключился на использование ключевых слов ввода/вывода с помощью более новые версии GLSL).

На стороне примечания, я нашел это особенно полезным, если фрагмент нуждается в некоторых значениях из каждой из вершин. В этом случае я использую flat out myVertexValue[3] в геометрическом шейдере (например здесь).

Ответ 2

Градиент исходит из интерполяции между цветами вершин, которые происходят, когда переменный проход переходит в fragment shader.If вы не хотите интерполировать используйте "плоское" ключевое слово в начале изменения. Ваше недоразумение, вероятно, связано с недостатком знаний о том, как работают этапы вершин и фрагментов. Они работают по-разному. Вершина шейдера вызывается за вершину, а фрагмент - пиксель. Интерполяция происходит по умолчанию, так как существует необходимость обрезать фрагменты, генерируемые во время растеризации этап в области, определенной примитивной сборкой. И, как я уже сказал, вы можете отключить интерполяцию "плоской". В таком случае цвет первого атрибута вершины определит общий цвет формы.