Как OpenGL интерполирует переменные в фрагментном шейдере, даже если они установлены в вершинном шейдере только три раза?
Поскольку вершинный шейдер запускается один раз для каждой вершины (это означает, что в треугольнике 3 раза), как переменная переменная вычисляется для каждого фрагмента, если она назначена (как в примере) только три раза?
Фрагмент шейдера:
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
Вершинный шейдер:
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
v_Color = a_Color;
gl_Position = a_Position;
}
Итак, вопрос в том, как система, стоящая за этим, знает, как вычислять переменную v_Color для каждого фрагмента, поскольку этот шейдер назначает v_Color только 3 раза (в треугольнике).
2 ответа
Все выходные данные вершинного шейдера находятся на одну вершину. Когда вы установите v_Color
в вершинном шейдере он устанавливает его в текущей вершине. Когда запускается фрагментный шейдер, он читает v_Color
значение для каждой вершины в примитиве и интерполирует между ними в зависимости от местоположения фрагмента.
Прежде всего, ошибочно полагать, что вершинный шейдер запускается один раз для каждой вершины. Используя индексированный рендеринг, примитивная сборка обычно может получить доступ к кешу после T&L (результат предыдущих вызовов вершинного шейдера) на основе индекса вершины, чтобы исключить оценку вершины более одного раза. Однако новые вещи, такие как геометрические шейдеры, могут легко привести к поломке.
Что касается того, как фрагментный шейдер получает свое значение, это обычно делается во время растеризации. Эти атрибуты для каждой вершины интерполируются вдоль поверхности примитива (в данном случае треугольника) на основе расстояния фрагмента относительно вершин, которые использовались для построения примитива. В DX11 интерполяция может быть отложена до тех пор, пока не запустится сам фрагментный шейдер (так называемая интерполяция "модель по запросу"), но традиционно это происходит при растеризации.