|
|
Повышение реалистичности изображений
Особенности реалистичного изображения Передача глубины Позволяет оценить расстояние до объектов Освещение объектов Позволяет оценить форму, цвет и материал объектов Отбрасывание теней Дополнительная информация о геометрии сцены Оптические эффекты Доп. информация о жидкостях, газах, полупрозрачных объектах и средах
Передача глубины Построение перспективных проекций Использование буфера глубины Сплошное закрашивание полигонов Depth of Field
Освещение объектов Световая энергия, падающая на поверхность: Частично поглощается, вызывая нагревание объекта При полном поглощении световой энергии тело называется абсолютно черным Частично отражается При полном отражении цветовой энергии тело называется абсолютно белым Частично пропускается При полном пропускании световой энергии тело является абсолютно прозрачным (вакуум)
Отраженный свет Свойства отраженного света зависят от следующих факторов: Строение, направление и форма источника света Ориентация и свойства поверхности Отраженный свет: Диффузный Зеркальный
Геометрические составляющие отраженного света m s v m – нормаль к поверхности в точке P v – вектор, соединяющий точку P с глазом наблюдателя s – вектор, соединяющий точку P с источником света P
Диффузная составляющая отраженного света Часть света слегка проникает внутрь поверхности объекта и излучается обратно по равномерно по всем направлениям Рассеянный свет сильно взаимодействует с поверхностью, поэтому его цвет обычно зависит от природы материала поверхности Характерно для шероховатых и матовых поверхностей
Вычисление диффузной составляющей отраженного света Пусть свет падает от точечного источника на одну сторону микро-грани поверхности Часть света диффузно переизлучается во всех направлениях Часть переизлученного света достигает глаза с интенсивностью Id Как зависит результирующая интенсивность света от векторов m, v и s?
Вычисление диффузной составляющей отраженного света Свет рассеивается одинаково во всех направлениях Ориентация микрограни относительно глаза не имеет значения (кроме случая v ∙ m < 0 – в этом случае Id = 0 Количество света зависит от ориентации микрограни по отношению к источнику света «наблюдаемая» источником света площадь микрограни
Закон Ламберта m s P s m P Θ Is – интенсивность падающего света ρd – коэффициент диффузного отражения
Зеркальное отражение Падающий свет отражается от поверхности и излучается вдоль некоторого направления Это порождает блики, за счет которых поверхность выглядит блестящей Характерно для гладких поверхностей
Модель Фонга (Phong’s model) Количество отраженного света имеет наибольшую величину в направлении абсолютного зеркального отражения При других углах количество отраженного света быстро убывает
Θ m s r Θ v P φ альтернативное приближение при бесконечно удаленном источнике света и наблюдателе, векторы s и v одинаковы для всех граней объекта
Роль фонового света В дополнение к диффузному и зеркальному источнику света добавляется еще и фоновый источник света среды, не имеющий определенного направления Его использование призвано смягчить резкие тени на частях объектов, на которые не попадает никакой свет
Комбинирование компонентов освещения Комбинирование компонентов освещения заключается нахождении суммарного количества света, попадающего в глаз
Добавление цвета В случает отражения цветных поверхностей цветными источниками света приемлемое приближение дает вычисление интенсивностей красной, зеленой и синей составляющих
Стандартная поддержка освещенности в OpenGL Максимум – 8 источников света Значение цвета примитива вычисляется для каждой его вершины. Полученные цветовые значения линейно интерполируются (освещение по Гуро)
Параметры, влияющие на освещенность в OpenGL Текущий вектор нормали Свойства материала Параметры источников света Параметры модели освещения
Свойства материала Различные материалы по разному отражают свет Некоторые материалы сами излучают свет, например, фосфор В OpenGL материал обладает следующими свойствами: Рассеянный цвет (GL_AMBIENT) Диффузный цвет (GL_DIFFUSE) Цвет зеркального отражения (GL_SPECULAR) Излучаемый цвет (GL_EMISSION) Степень зеркального отражения (GL_SHININESS)
Свойства материала Различные материалы по разному отражают свет Некоторые материалы сами излучают свет, например, фосфор В OpenGL материал обладает следующими свойствами: Рассеянный цвет (GL_AMBIENT) Диффузный цвет (GL_DIFFUSE) Цвет зеркального отражения (GL_SPECULAR) Излучаемый цвет (GL_EMISSION) Степень зеркального отражения (GL_SHININESS)
Задание свойств материала в OpenGL Для определения вышеупомянутых свойств материала используется команда glMaterial: glMaterial[f i](GLenum face, GLenum pname, type param) glMaterial[f i]v(GLenum face, GLenum pname, const type *params) face – GL_FRONT, GL_BACK или GL_FRONT_AND_BACK pname – GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS
Установка цвета материала при помощи glColor При включенном освещении текущий цвет вершины не используется вместо него используются цветовые характеристики материала Однако использование команды glMaterial* для изменения цвета отдельных вершин может показаться громоздким Команда glColorMaterial позволяет задавать параметры отдельных вершин с использованием команды glColor при включенном освещении Для включения данной функции надо выполнить: glEnable(GL_COLOR_MATERIAL)
glColorMaterial Позволяет определить какие параметры материала изменяются при помощи команды glColor glColorMaterial(GLenum face, GLenum mode) face – GL_FRONT, GL_BACK, GL_FRONT_AND_BACK mode – GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_AMBIENT_AND_DIFFUSE
Пример void SetCubeMaterial() { glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); float specular[4] = {0.7f, 0.7f, 0.7f, 1}; glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glMaterialf(GL_FRONT, GL_SHININESS, 10); }
Источники света в OpenGL Включение режима освещения: glEnable(GL_LIGHTING) Включение источника света: glEnable(GL_LIGHTi), где i – число от 0 до GL_MAX_LIGHTS (не может быть больше 8) Задание параметров источника света: glLight[i f](GLenum light, GLenum pname, type param) glLight[i f]v(GLenum light, GLenum pname, const type* params)
Скалярные параметры источника освещения GL_SPOT_EXPONENT Распределение интенсивности света (от 0 до 128). Увеличение данного параметра делает источник света более сфокусированным GL_SPOT_CUTOFF максимальный угол разброса источника света [0, 90] или 180 для точечных источников GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION Постоянный, линейный и квадратичный факторы ослабления света с расстоянием от источника света до вершины: 1/(k0 + k1*S + k2*S2)
Конический источник света GL_SPOT_CUTOFF
Векторные параметры источника освещения GL_AMBIENT – интенсивность фонового освещения GL_DIFFUSE – интенсивность диффузного освещения GL_SPECULAR – интенсивность зеркального отражения GL_POSITION – позиция источника света в однородных координатах объекта Если компонент w равен 0, то источник света рассматривается как направленный и бесконечно удаленный. Диффузное и зеркальное освещение рассчитываются исходя из направления на источник. Ослабление света при этом не действует. GL_SPOT_DIRECTION – параметр params задает трехкомпонентный вектор направления конического источника света
Пример установки источника света void SetLights() { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); const float diffuseColor[4] = {0.8f, 0.8f, 0.8f, 1}; const float ambientColor[4] = {0.2f, 0.2f, 0.2f, 1}; const float specularColor[4] = {1.2f, 1.2f, 1.2f, 1}; const float lightDirection[4] = {0.0f, 0.0f, 1.0f, 0}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor); glLightfv(GL_LIGHT0, GL_POSITION, lightDirection); }
Влияние освещения на реалистичность изображения
Наложение текстуры
Текстурирование Очень часть поверхности не являются окрашенными в один цвет, а имеют некоторый нанесенный на них рисунок, узор Кожа Древесина Ткани Текстурирование – простой и достаточно эффективный способ повышения реалистичности изображения за счет детализации поверхности цветом
Принципы наложения текстуры Создание текстурного объекта Определение текстурной функции Задание текстурных координат для вершин примитивов Растеризация примитива
Текстурные объекты Текстура – это объект OpenGL С каждым текстурным объектом связано его изображение, набор параметров и «имя» - целое число без знака OpenGL по умолчанию работает с текстурным объектом с индексом 0 Привязка к заданному текстурному объекту по его имени осуществляется при помощи команды glBindTexture Все последующие команды управляющие параметрами текстуры относятся к выбранному текстурному объекту
Генерирование текстурных имен Выбор текстурного объекта осуществляется по его «имени» В сложных приложениях приходится иметь дело с большим количеством текстур Необходимо следить за тем, чтобы при создании новой текстуры ее имя не было связано с уже используемым текстурным объектом OpenGL позволяет получать имена текстурных объектов, имеющихся в свободном наличии
Команда glGenTextures Команда glGenTextures позволяет сгенерировать заданное количество имен для текстурных объектов void glGenTextures( GLsizei n, GLuint *textures) GLuint textureName = 0; glGenTextures(1, &textureName); glBindTexture(GL_TEXTURE_2D, textureName);
Удаление текстуры Ставшие ненужными текстурные объекты необходимо удалить с целью освобождения памяти Если удаляемый объект текстуры был ранее выбран при помощи команды glBindTexture, то происходит выбор текстурного объекта с индексом 0 Текстурный объект 0 не может быть удален Будучи удаленным, текстурный объект не имеет ни размеров, ни содержимого. Его имя становится свободным для повторного использования
Команда glDeleteTextures Команда осуществляет удаление указанных текстурных объектов void glDeleteTextures( GLsizei n, const GLuint *textures) GLuint textureName; glGenTextures(1, &textureName); ... glDeleteTextures(1, &textureName);
Текстурная функция В процессе растеризации OpenGL интерполирует значение текстурных координат вершин по поверхности примитива с учетом перспективы Для каждого фрагмента вычисляются его координаты в текстурном пространстве Текстурная функция отображает значение текстурной координаты в значение некоторой величины, например, цвета, влияющего на финальный цвет фрагмента
Задание текстурной функции Вначале задается текстурная функция в текстурном пространстве например texture(s,t) – двухмерное текстурное пространство Данная функция генерирует значения цвета или яркости для каждого значения текстурных координат в диапазоне от 0 до 1
Способы задания текстурных функций Растровые текстуры Значение функции вычисляется на основе выборки значений из растрового изображения в качестве дискретных значений функции Процедурные текстуры Вычисляют значение функции в данной точке на основе заданной формулы Шахматная доска Фрактал Мраморные поверхности OpenGL поддерживает процедурные текстуры при помощи фрагментных (пиксельных) шейдеров
Создание изображения OpenGL накладывает ограничения на размеры текстуры Ширина и высота должны быть степенью двойки OpenGL принимает данные о текстуре в строго заданных форматах. Загрузка изображения из файла и представление их в пригодном для OpenGL виде – забота приложения
Текстурное изображение Для того, чтобы OpenGL мог вычислить значение текстурной функции, необходимо задать эту функцию Стандартный способ задания текстурной функции – задание текстурного изображения Текстурное изображение определяет дискретные значения текстурной функции в диапазоне текстурных координат от 0 до 1
Типы текстур OpenGL позволяет осуществлять наложение различных типов текстур Одномерные текстуры Двумерные текстуры Трехмерные текстуры Кубические текстуры Для каждого типа текстур в OpenGL имеется функция, создающая текстурное изображение
Семейство команд glTexImage* Данные команды задают текстурное изображение определенного типа для текущего текстурного объекта glTexImage1D задает изображение одномерной текстуры glTexImage2D задает изображение двумерной текстуры или одну из шести текстур кубической текстуры glTexImage3D задает изображение для трехмерной текстуры
Представление текстурного изображения в памяти В зависимости от формы используемой команды glTexImage* приложение должно сформировать в памяти одно-, двух-, или трехмерный массив элементов определенного типа и размерности Например, 24 битному BMP изображению может соответствовать двухмерный массив троек 8-битных чисел
Формат текстуры в OpenGL Изображение внутри OpenGL хранится в виде одно-, двух- или трехмерного массива числовых значений определенного типа, задающих цвета пикселей в одном из следующих форматов: GL_ALPHA GL_LUMINANCE GL_LUMINANCE_ALPHA GL_INTENSITY GL_RGB GL_RGBA
Загрузка текстурных данных из файла Приложение должно загрузить данные из графического файла, при необходимости распаковав их, и представить их в одном из следующих форматов: GL_COLOR_INDEX GL_RED GL_GREEN GL_BLUE GL_ALPHA GL_RGB GL_RGBA GL_BGR_EXT GL_BGRA_EXT GL_LUMINANCE GL_LUMINANCE_ALPHA
Наложение текстуры Двумерное текстурное пространство Трехмерное пространство 0 1 1 z x y s t
Наложение текстуры
Текстурные координаты Помимо координат в пространстве или направления вектора нормали с каждой вершиной полигона ассоциируются координаты данной вершины в текстурном пространстве Пространство одномерной текстуры - прямая Пространство двумерной текстуры – двумерная плоскость Пространство трехмерной или кубической текстуры – трехмерный объем
Команда glTexCoord Команда glTexCoord*() позволяет указать значение текущих текстурных координат При создании вершины с помощью команды glVertex* текущая текстурная координата становится атрибутом созданной вершины При рисовании текстурированных примитивов не забывайте указывать текстурные координаты вершины перед выполнением glVertex
Необходимые действия для создания изображения с текстурой Создать изображение Подойдет любой графический редактор Создать из данного изображения текстуру – образ в памяти Задать параметры текстуры и ее взаимодействия с объектом, на который она будет накладываться
Вариант задания текстурных координат s t (1, 0) (0, 0) (0, 1) (1, 1)
Включение текстурирования Текстурирование включается при помощи команды glEnable(GL_TEXTURE_2D) или glEnable(GL_TEXTURE_1D)
Уровни детализации текстуры OpenGL позволяет задать для текстуры несколько изображений, соответствующих различным уровням детализации Для изображения текстуры на маленьких объектах OpenGL будет использовать текстуры с меньшим уровнем детализации Расход памяти при этом будет больше всего лишь на 1/3 в случае двухмерной текстуры Использование различных уровней детализации может увеличить скорость и качество наложения текстуры Уровень детализации указывается при использовании команд glTexImage*D
Изображения, соответствующие различным уровням детализации (mip-maps)
Автоматическое создание mip-maps Библиотека GLU содержит функции для автоматического создания текстуры с различными уровнями детализации gluBuild1DMipmaps gluBuild2DMipmaps
Пример
Для чего нужна фильтрация текстур? Экран, как и растровое изображение, соответствующее текстуре, состоит из дискретных пикселей При большом увеличении нескольким пикселям экрана может соответствовать один тексель – будет видна мозаичная структура текстуры При уменьшении одному пикселю экрана может соответствовать несколько пикселей текстуры. При движении это может создавать рябь
Фильтрация текстур Фильтрация текстур определяет то, каким образом будут выбираться пиксели текстуры при растеризации Стандартно в OpenGL существуют два фильтра: Фильтр, работающий при уменьшении текстуры Фильтр, работающий при увеличении текстуры
Указание режима фильтрации текстуры Режимы фильтрации текстуры и некоторые другие параметры устанавливаются при помощи функции glTexParameter glTexParameter[i f] (GLenum target, GLenum pname, GLenum param) glTexParameter[i f]v (GLenum target, GLenum pname, const GLenum *param)
Фильтр увеличения glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter) Параметр filter принимает значения: GL_NEAREST GL_LINEAR
Фильтр уменьшения glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter) Параметр filter принимает значения: GL_NEAREST GL_LINEAR GL_NEAREST_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR GL_LINEAR_MIPMAP_NEAREST GL_LINEAR_MIPMAP_LINEAR
Пример фильтрации изображений
Параметры текстуры С каждым текстурным объектом ассоциируются определенный набор параметров Фильтры уменьшения/увеличения Способ вычисления текстурной функции в зависимости от соотношения размеров примитива и текстурного изображения «Заворачивание» текстурных координат Правила вычисления текстурной функции для координат, выходящих за пределы диапазона [0; 1] Приоритет текстуры Управляет резидентным размещением текстуры в быстрой памяти в случае ее нехватки
Команда glTexParameter Данная команда позволяет устанавливать значение скалярного либо векторного целочисленного или вещественного параметра текстуры Синтаксис: void glTexParameter[i f]( GLenum target, GLenum pname, Type param) void glTexParameter[i f]v( GLenum target, GLenum pname, const Type *param) Параметры: target - тип текстуры (например GL_TEXTURE_2D) pname – имя параметра param – значение указанного параметра
«Заворачивание» (Wrap) текстурных координат Значение текстурной функции определено для координат, компоненты которых находятся в интервале от 0 до 1 Координаты вершины в текстурном пространстве могут выходить за пределы данного интервала Использование матрицы текстурных координат также может приводить к выходу за пределы заданного диапазона OpenGL позволяет задать способ вычисления текстурной функции за границами допустимого диапазона Режим заворачивания определяет способ отображения «неправильных» координат внутрь допустимой области
Установка режима заворачивания Установка режима заворачивания текстурной координаты осуществляется при помощи вызова команды: glTexParameteri(target, wrapCoord, wrapMode) target – тип текстуры (например GL_TEXTURE_2D) wrapCoord GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T GL_TEXTURE_WRAP_R (GL_TEXTURE_WRAP_R_EXT) wrapMode – режим заворачивания
Режимы заворачивания GL_CLAMP ½ edge + ½ border GL_CLAMP_TO_EDGE (GL_CLAMP_TO_EDGE_EXT) edge only GL_CLAMP_TO_BORDER (GL_CLAMP_TO_BORDER_ARB) border only GL_REPEAT отброс целой части текстурной координаты GL_MIRRORED_REPEAT (GL_MIRRORED_REPEAT_ARB) зеркальное отражение по границе текстуры
Применение режимов заворачивания Применение различных режимов заворачивания координат позволяет осуществить: Заполнение большой площади при помощи небольших шаблонов обои, кирпичи, ткань, кафельная плитка и т.п. вывод одиночных изображений бесшовная стыковка текстур
Включение/выключение текстурирования Включение/выключение наложения текстуры на примитивы осуществляется при помощи команд glEnable/glDisable c параметрами GL_TEXTURE_1D GL_TEXTURE_2D GL_TEXTURE_3D GL_TEXTURE_CUBEMAP Наложение текстуры не работает при отсутствии текстурного изображения для выбранного текстурного объекта
Texture 1 Texture 2 glBindTexture(GL_TEXTURE_2D, 1); glTexImage2D(...); glTexParameteri(GL_TEXTURE_2D, ...); glBindTexture(GL_TEXTURE_2D, 2); glTexImage2D(...); glTexParameteri(GL_TEXTURE_2D, ...); glBindTexture(GL_TEXTURE_2D, 1); glEnable(GL_TEXTURE_2D); drawCube(); glBindTexture(GL_TEXTURE_2D, 2); drawSphere(); Texture 0
Взаимодействие текстуры с объектом Цвет текстуры должен каким-то образом взаимодействовать с цветом объекта, на который накладывается текстура OpenGL позволяет задать несколько режимов смешивания цветов объекта и текстуры
Установка режима взаимодействия текстуры и объекта Устанавливается при помощи функции glTexEnv* void glTexEnv[i f](GLenum target, GLenum pname, GLtype param) void glTexEnvf[i f]v(GLenum target, GLenum pname, const GLtype *param)
Установка режима взаимодействия glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode) Параметр mode принимает значения: GL_MODULATE GL_DECAL GL_BLEND GL_REPLACE GL_ADD
Прямоугольник без текстуры
Текстура с альфа-каналом
GL_REPLACE
GL_MODULATE
GL_DECAL
GL_ADD
Мультитекстурирование
Что такое мультитекстурирование? Начиная с версии 1.3 в библиотеке OpenGL появилась поддержка нескольких блоков текстурирования (texture units) Мультитекстурирование позволяет накладывать на примитив две или более различных текстур одновременно Количество зависит от реализации и не превышает 8
Применение мультитекстурирования Shadow maps Наложение текстуры теней на поверхность объектов в дополнение к основной текстуре Detail textures Увеличение детализированности поверхности объекта за счет добавления высокочастотной текстуры мелких деталей к низкочастотной основной текстуре Environment mapping Наложение текстуры окружающей среды на объект в дополнение к основной текстуре Bump mapping Дополнительные текстуры могут нести информацию о неровностях поверхности
Использование мультитекстурирования Мультитекстурирование было добавлено с сохранением обратной совместимости с версией 1.2.1 Для доступа к текстурному блоку приложение должно сделать его активным при помощи команды glActiveTexture
Как работает мультитекстурирование После определения цвета фрагмента, полученного в результате интерполяции цветов вершин примитива, OpenGL выполняет наложение текстуры на фрагмент во всех текстурных блоках, в которых разрешено наложение текстуры Цвет полученный на выходе текстурного модуля №0 становится выходным для текстурного модуля №1 и т.д. Режим наложения текстуры определяется при помощи функции glTexEnv.
Принцип работы мультитекстурирования
Мультитекстурирование в Windows Библиотека OpenGL.dll в системах Windows содержит версию OpenGL 1.1 Функции, появившиеся в старших версиях OpenGL, в этой dll отсутствуют Однако они доступны в виде расширений OpenGL Для поддержки мультитекстурирования следует пользоваться расширением GL_ARB_multitexture
Работа с расширениями OpenGL
Получение списка поддерживаемых расширений С каждым расширением связано некоторое символическое имя Например, GL_ARB_multitexture Узнать об поддерживаемых расширениях можно при помощи вызова функции const GLubyte* glGetString(GL_EXTENSIONS) Возвращаемая строка содержит символические имена поддерживаемых расширений, разделенные пробелами
Получение адреса функции расширения по ее имени Единственный* способ получения адреса функции OpenGL расширения в системе Windows – использование функции PROC wglGetProcAddress( LPCSTR procName) * - единственный рекомендуемый к повсеместному использованию
Пример получения адреса функции расширения PFNGLACTIVETEXTUREARBPROC glActiveTexture = NULL; PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2f = NULL; bool multiTextureSupported = false; LPCSTR *extString = (LPCSTR *)glGetString(GL_EXTENSIONS); if (strstr(extString, "GL_ARB_multitexture")) { multiTextureSupported = true; glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB"); glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB"); }
GLEW – OpenGL Extension Wrangler library Кроссплатформенная библиотека с открытым исходным кодом для облегчения работы с расширениями OpenGL Берет на себя рутинные задачи по проверке наличия доступных расширений и получении адресов необходимых функций Прозрачна и легка в использовании Макросы, предоставляемые библиотекой, полностью совместимы со спецификацией функций соответствующих расширений
Пример glewInit(); ... if (GLEW_ARB_multitexture) { glActiveTexture(GL_TEXTURE1); } ... glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
Текстурные координаты и мультитекстурирование С появлением мультитекстурирования с вершиной могут быть ассоциированы несколько текстурных координат – свои для каждого Texture Unit’а Для указания текущих текстурных координат, соответствующих заданному Texture Unit’у служит команда void glMultiTexCoord[1 2 3 4][i s f d][v]( GLenum texture, Type coords) texture - GL_TEXTUREx
Пример glActiveTexture (GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 1); glActiveTexture (GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 2); glBegin(GL_TRIANGLES); { glMultiTexCoord2f(GL_TEXTURE0, ...); glMultiTexCoord2f(GL_TEXTURE1, ...); glVertex3f(...); ... } glEnd();
Смешивание цветов и полупрозрачность
Смешивание цветов (blending) В процессе растеризации сформированный цвет фрагмента может быть как записан напрямую, так и примешан к цвету существующего фрагмента буфера кадра Результат смешивания зависит от цветов исходного и выводимого фрагментов, а также от функции смешивания (blend-function) Данная возможность позволяет создавать различные эффекты, а также осуществлять вывод полупрозрачных объектов
Режим смешивания цветов Режим смешивания цветов включается и выключается при помощи команд: glEnable(GL_BLEND) glDisable(GL_BLEND)
Принцип работы смешивания цветов При включенном режиме смешивания цветов результирующий цвет фрагмента вычисляется путем взвешенной суммы цветов исходного и выводимого фрагментов: C = Сs * Ks + Cd * Kd Сd и Cs – исходный и выводимый цвета Kd и Ks – их весовые коэффициенты Весовые коэффициенты задаются при помощи функции смешивания
Функция смешивания Функция смешивания задает способ вычисления коэффициентов, на которые умножаются компоненты исходного и выводимого фрагментов В OpenGL функция смешивания определяется при помощи команды glBlendFunc(GLenum sFactor, GLenum dFactor) sFactor – задает коэффициент, применяемый к цвету выводимого фрагмента dFactor – коэффициент, применяемый к цвету исходного фрагмента
Рисование полупрозрачных объектов Если в сцене присутствуют полупрозрачные объекты, то для ее корректной визуализации необходимо придерживаться следующего алгоритма Рисуем непрозрачные объекты с разрешенной записью в буфер глубины Включаем режим смешивания цветов Рисуем полупрозрачные объекты с выключенной записью в буфер глубины, причем выводим в первую очередь наиболее удаленные от наблюдателя полупрозрачные примитивы
Особенности рисования полупрозрачных объектов Необходимость сортировки полигонов по удаленности от наблюдателя Несоблюдение данного правила приводит к появлению неприятных «артефактов» Необходимость выбор правильной функции смешивания для достижения нужного результата
Оптимизация сортировки примитивов При любом изменении положения камеры или полупрозрачных объектов требуется сортировка всех полупрозрачных примитивов Затраты на сортировку полигонов Затраты по передачу вершин примитивов на сторону OpenGL (нет возможности хранить статическую геометрию на OpenGL-сервере) Желательно упростить или вообще избавиться от сортировки по глубине
Сортировка полупрозрачных объектов вместо сортировки примитивов Если объекты сцены являются выпуклыми, то можно рисовать их с помощью модифицированного алгоритма художника: Сперва рисуем обратные, а потом лицевые грани выпуклого объекта Невыпуклые статические объекты можно разбить на выпуклые составляющие и сортировать уже их
Альтернативные способы вывода полупрозрачных объектов Существуют методики рисования полупрозрачных объектов без необходимости сортировки полигонов ценой нескольких проходов рендеринга – Order independent transparency Качество/скорость зависят от количества проходов Избавление от необходимости сортировки полигонов позволяет хранить геометрию сцены на стороне сервера От реализации OpenGL требуется поддержка определенных расширений
Выбор функции смешивания Хорошие результаты для поглощающих свет полупрозрачных материалов (светофильтров) дает функция смешивания: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) Для светящихся материалов (искры, пламя, снег) хорошие результаты дает функция смешивания: glBlendFunc(GL_ONE, GL_ONE) Примечательно, что вывод полупрозрачных примитивов с помощью данной функции, не требует сортировки вообще
Наложение тумана
Что такое туман? Туман — форма выделения паров воды в виде микроскопических капель или ледяных кристаллов, которые собираясь в приземном слое атмосферы (иногда до нескольких сотен метров) делают воздух менее прозрачным.
Применение тумана в компьютерной графике Моделирование природных явлений, малопрозрачных сред Туман, пасмурная погода, дождь, пыль, однородный дым, подводная среда Дополнительное средство передачи глубины и дистанции Объекты расположенные дальше от наблюдателя видны менее отчетливо При рендеринге открытых пространств туман позволяет скрыть линию горизонта, вызванную ограниченной глубиной видимого объема
Реализация тумана в OpenGL Туман в OpenGL характеризуется несколькими величинами Цвет Уравнение (линейное, экспоненциальное или квадратичное экспоненциальное) Плотность Цвет фрагмента смешивается с цветом тумана с использованием коэффициента, рассчитываемого по уравнению тумана с учетом расстояния от наблюдателя до объекта
Уравнения тумана
Управление наложением тумана Включение/выключение glEnable/glDisable(GL_FOG) Задание параметров glFog[f i][v](pname, param[s]) pname: GL_FOG_MODE (GL_LINEAR, GL_EXP, GL_EXP2) GL_FOG_DENSITY GL_FOG_START GL_FOG_END GL_FOG_INDEX GL_FOG_COLOR
Пример наложения тумана float fogDensity = 0.008f; glFogf(GL_FOG_DENSITY, fogDensity); float fogStart = 100.0f; glFogf(GL_FOG_START, fogStart); float fogEnd = 230; glFogf(GL_FOG_END, fogEnd); float fogColor[] = {0.8f, 0.8f, 0.8f, 1}; glFogfv(GL_FOG_COLOR, fogColor); glFogi(GL_FOG_MODE, g_fogMode); glEnable(GL_FOG);
Вопросы?
| URL: |
No comments posted yet
Comments