Проблема в том, что вы используете квад. Квадрат нарисован с использованием двух треугольников, но треугольники не в той ориентации, которая вам нужна.
Если я определю четверные вершины как:
- A : нижняя левая вершина
- B : нижняя правая вершина
- C : верхняя правая вершина
- D : верхняя левая вершина
Я бы сказал, что квад состоит из следующих треугольников:
Цвета, назначенные каждой вершине:
- A : желтый
- B : красный
- C : желтый
- D : красный
Принимая во внимание геометрию (два треугольника), пиксели между D и B являются результатом интерполяции между красным и красным: действительно, красный!
Решением будет геометрия с двумя треугольниками, но ориентированная по-другому:
Но, вероятно, вы не получите точного градиента, поскольку в середине четырехугольника вы получите полный желтый вместо желтого, смешанного с красным. Итак, я полагаю, что вы можете достичь точного результата, используя 4 треугольника (или веер треугольника), в которых центрированная вершина является интерполяцией между желтым и красным.
Wooop! Эффективно результат не тот, который я ожидал. Я думал, что градиент был получен путем линейной интерполяции между цветами, но это не так (мне действительно нужно настроить цветовое пространство ЖК-дисплея!). Действительно, наиболее масштабируемое решение - рендеринг с использованием фрагментных шейдеров.
Сохранить решение, предложенное Bahbar . Я бы посоветовал начать реализацию сквозного вершинного / фрагментного шейдера (указав только вершины и цвета, которые вы должны получить в предыдущем результате); затем начните играть с функцией mix и координаты текстуры передаются в вершинный шейдер.
Вам действительно нужно понимать конвейер рендеринга с программируемыми шейдерами : вершинный шейдер вызывается один раз для каждой вершины, фрагментный шейдер вызывается один раз для фрагмента (без мультисэмплирования фрагмент является пикселем; с мультисэмплингом, aa пиксель состоит из множества фрагментов, которые интерполируются для получения цвета пикселя).
Вершинный шейдер принимает входные параметры (униформы и входные данные; униформы постоянны для всех вершин, передаваемых между glBegin / glEnd; входные данные характерны для каждого экземпляра вершинного шейдера (4 вершины, 4 экземпляра вершинного шейдера).
Фрагментный шейдер принимает в качестве входных данных выходные данные вершинного шейдера, который создал фрагмент (из-за растеризации треугольников, линий и точек). В ответе Bahbar единственным выводом является переменная uv (общая для обоих источников шейдеров).
В вашем случае вершинный шейдер выводит координаты текстуры вершины UV (передается "как есть"). Эти UV-координаты доступны для каждого фрагмента, и они рассчитываются путем интерполяции значений, выводимых вершинным шейдером, в зависимости от положения фрагмента.
Если у вас есть эти координаты, вам нужно только два цвета: красный и желтый в вашем случае (в Bahbar ответ соответствует color0 и color1 форма). Затем смешайте эти цвета в зависимости от UV-координат конкретного фрагмента. (*)
(*) Вот сила шейдеров: вы можете указать различные методы интерполяции, просто изменив источник шейдера. Линейная, билинейная или сплайн-интерполяция реализуются путем указания дополнительных униформ для фрагментного шейдера.
Хорошая практика!