Листинг 16.6. Фрагментный шейдер для уменьшения резкости
uniform sampler2D Blurry: uniform float Alpha:
void main (void)
{
vec3 blurred = vec3 (texture2D(Blurry, gl_TexCoord[0],st)): vec3 color = gl_Color.rgb * Alpha + blurred * (1.0 - Alpha): gl_FragColor = vec4 (color. 1.0):
}
На этих примерах показан простой случай изменения целого изображения с изменением простого значения Alpha. Возможна и более сложная обработка - например, Alpha может быть значением функции от других переменных. Можно в какой-либо текстуре определить сложную форму, ограничивающую область изображения для внесения изменений, или выбрать несколько небольших областей на изображении с помощью какого-либо шаблона, маски. Операцию можно выполнять выборочно, для пикселов с конкретным диапазоном яркости (тени, области повышенной яркости или средние тона).
Фрагментные шейдеры можно использовать также для интерполяции более чем двух изображений, и не обязательно эта интерполяция будет линейной. Возможно интерполировать вдоль нескольких осей одновременно. Размытая полутоновая версия исходного изображения совместно с исходным изображением могут служить основой для создания за одну операцию насыщенного цветного изображения с хорошей резкостью.
16.6. Режимы плавного перехода
Высокоуровневый язык программирования достаточно выразителен для того, чтобы можно было сочетать два изображения самыми разными способами. В нем либо оба изображения сохраняются в текстурной памяти, либо одно из них загружается приложением с помощью функции gl DrawPi xel s. Приведем несколько фрагментов кода шейдера OpenGL для плавного попиксельного перехода в разных режимах:
□ base - vec4 - содержит значение цвета RGBA из исходного изображения;
□ Ы end - vec4 - содержит значение цвета RGB А из изображения, которое переходит в исходное;
□ resul t - vec4 - содержит значение цвета RGBA, результат операции плавного перехода;
□ если понадобится для вычислений, white является vec4 и содержит (1,0,1,0,1,0,1,0);
□ если понадобится для вычислений, 1 umCoeff является vec4 и содержит (0,2125,
0,7154, 0,0721, 1,0);
□ для окончательных вычислений ba se и resul t сочетаются с помощью числа с плавающей запятой opacity (непрозрачность), которое определяет участие каждого компонента.
Вероятно, результат выполнения приведенного кода не будет идентичен результату, полученному в излюбленной программе читателя, но эффекты будут очень похожими. Код шейдера OpenGL для некоторых режимов плавного перехода был создан с помощью информации, содержащейся в статье Дженса Груше-ля «Режимы плавного перехода», доступной по адресу http://www.pegtop.net/delphi/ blendmodes. Если явно не указано что-то иное, операции плавного перехода не коммутативные (если поменять местами исходное и конечное изображения, результат изменится).
Результаты выполнения шейдеров плавного перехода в различных режимах показаны на цветном рис. 30.
16.6.1. Обычный
Этот режим работы с изображением часто предполагается по умолчанию. Конечное изображение помещается над исходным. Окончательное изображение такое же, как конечное, если значение прозрачности 1,0 (исходное изображение полностью закрыто). При других значениях прозрачности результатом будет сочетание двух изображений, основанное на значении opacity: result = blend: