Е. А. Снижко, Н. А. Флерова
Скачать 0.57 Mb.
|
Модель освещения. OpenGL рассчитывает свет так, как будто он может быть разделен на красный, зеленый и синий компоненты. Таким образом, источник света характеризуется количеством красного, зеленого и синего, которое он излучает, а материал по- верхности – долями тех же компонентов, которые он отражает в различных направлениях. Уравнения освещенности в OpenGL яв- ляются всего лишь аппроксимациями, но зато они работают доста- точно хорошо и могут быть рассчитаны относительно быстро. В модели освещения OpenGL свет исходит от нескольких ис- точников, которые могут включаться и выключаться индивиду- ально. Часть света обычно исходит из какого-либо определенного 49 направления или позиции, часть распределена по всей сцене. На- пример, если Вы включите лампочку в комнате, большая часть света будет исходить от нее, но часть света падает на поверхно- сти предметов в комнате после того, как он отразился от одной, двух, трех или более стен. Считается, что этот многократно от- раженный свет (называемый фоновым светом) распределен на- столько сильно, что не существует никакого способа определить его исходное направление, однако он исчезает при выключении определенного источника света. Наконец, в сцене может также присутствовать общий фоно- вый свет, у которого нет никакого конкретного источника, как будто он был отражен столько раз и распределен так сильно, что его оригинальный источник установить невозможно. В модели OpenGL эффект от источника света присутствует только если есть поверхности, поглощающие или отражающие свет. Считается, что каждая поверхность состоит из материала с несколькими свойствами. Материал может излучать свой собст- венный свет (например, фара автомобиля), он может распреде- лять некоторое количество входящего света во всех направлени- ях, также он может отражать часть света в определенном направ- лении (например, зеркало или другая блестящая поверхность). В модели освещения OpenGL предполагается, что освещение может быть разделено на четыре компонента: фоновое (ambient), диффузное (diffuse), зеркальное (specular) и исходящее (эмисси- онное – emissive). Все четыре компонента рассчитываются неза- висимо и только затем суммируются. Фоновый, диффузный, зеркальный и исходящий свет. Фо- новое излучение – это свет, который настолько распределен сре- дой (предметами, стенами и т.д.), что его направление определить невозможно: кажется, что он исходит отовсюду. Лампа дневного света имеет большой фоновый компонент, поскольку большая часть света, достигающего Вашего глаза, сначала отражается от множества поверхностей. Уличный фонарь имеет маленький фо- новый компонент: большая часть его света идет в одном направ- лении, кроме того, поскольку он находится на улице, очень не- большая часть света попадает Вам в глаз после того, как отразит- ся от других объектов. Когда фоновый свет падает на поверх- ность, он одинаково распределяется во всех направлениях. Диффузный компонент – это свет, идущий из одного направ- ления. Он выглядит ярким, если падает на поверхность под пря- 50 мым углом, и тусклым, если касается ее всего лишь вскользь. Однако, падая на поверхность, он распределяется одинаково во всех направлениях, т.е. его яркость одинакова независимо от то- го, с какой стороны Вы смотрите на поверхность. Вероятно, лю- бой свет, исходящий из определенного направления или позиции, имеет диффузный компонент. Зеркальный свет исходит из определенного направления и отражается от поверхности также в определенном направлении. При отражении хорошо сфокусированного лазерного луча от ка- чественного зеркала происходит почти 100%-ное зеркальное от- ражение. Блестящий металл или пластик имеет высокий зеркаль- ный компонент, а кусок ковра или плюшевая игрушка – нет. Вы можете думать о зеркальности, как о том, насколько блестящим выглядит материал. Помимо фонового, диффузного и зеркального цветов мате- риалы могут также иметь исходящий цвет, имитирующий свет, исходящий от самого объекта. В модели освещения OpenGL ис- ходящий свет поверхности добавляет объекту интенсивности, но на него не влияют никакие источники света, и он не производит дополнительного света для сцены в целом. Хотя источник света излучает единое распределение частот, фоновый, диффузный и зеркальный компоненты могут быть раз- личны. Например, если в Вашей комнате красные стены и белый свет, то этот свет, отражаясь от стен, будет скорее красным, чем белым (несмотря на то, что падающий на стену свет белый). OpenGL позволяет устанавливать значения красного, зеленого и синего независимо для каждого компонента света. Цвет материала и света. Модель освещения OpenGL дела- ет допущение о том, что цвет материала зависит от долей падаю- щего красного, зеленого и синего света, которые он отражает. Например, максимально красный шар отражает весь красный свет, который на него падает, и поглощает весь зеленый и синий. Если Вы посмотрите на такой мяч под белым светом (состоящим из одинакового количества красного, зеленого и синего), весь красный свет отразится и Вы увидите красный мяч. Если смот- реть на мяч при красном свете, он также будет выглядеть крас- ным. Если, однако, посмотреть на него под зеленым светом, он будет выглядеть черным (весь зеленый свет поглотится, а крас- ный компонент отсутствует, т.е. никакой свет отражен не будет). 51 Так же как и свет, материалы имеют разные фоновый, диф- фузный и зеркальный цвета, которые задают реакцию материала на соответствующие компоненты света. Фоновый цвет материала комбинируется с фоновым компонентом всех источников света, диффузный с диффузным компонентом, а зеркальный с зеркаль- ным. Фоновый и диффузный цвета задают видимый цвет мате- риала, они обычно близки, если не эквивалентны. Зеркальный цвет обычно белый или серый. Он задает цвет блика на объекте (т.е. может совпадать с зеркальным компонентом источника света). Цветовые компоненты, задаваемые для источников света, оз- начают совсем не то же самое, что для материалов. Для источни- ка света число представляет собой процент от полной интенсив- ности каждого цвета. Если R, G и B – величины цвета источника света – все равны 1,0, свет будет максимально белым. Если вели- чины будут равны 0,5, свет все равно останется белым, но лишь с половиной интенсивности (будет казаться серым). Если R=G=1 и B=0 (полный красный, полный зеленый, отсутствие синего), свет будет желтым. Для материалов числа соответствуют отраженным пропорци- ям этих цветов. Так что если для материала R=1, G=0,5 и B=0, этот материал отражает весь красный свет, половину зеленого и совсем не отражает синего. Другими словами, если обозначить компоненты источника света как (LR, LG, LB), а компоненты ма- териала как (MR, MG, MB) и проигнорировать все остальные взаимодействия, то свет, который поступит в глаз, можно опре- делить как (LR–MR, LG–MG, LB–MB). Похожим образом, если два источника света с характеристи- ками (R1, G1, B1) и (R2, G2, B2) направлены в одну точку, OpenGL сложит компоненты: (R1+R2, G1+G2, B1+B2). Если ка- кая-либо из сумм будет больше единицы (соответствуя цвету, который нельзя отобразить), компонент будет урезан до единицы. Включение фонового освещения. По умолчанию освещение отключено. Включается оно командой glEnable(GL_LIGHTING). Без освещения работать практически невозможно. Сфера всегда будет показываться как круг, а конус – как круг или треугольник. Если монотонное тело равномерно освещено, то увидеть его рельеф невозможно. Поэтому необходимо использовать источни- ки света. 52 Когда освещение разрешено, можно устанавливать фоновую освещенность. По умолчанию значение фоновой освещенности равно (0,2; 0,2; 0,2; 1). Фоновое освещение устанавливается с по- мощью функции glLightModel. Если повысить его до (1,1,1,1), т.е. до максимума, то включать источники света не понадобится. Их действие просто не будет заметно, так как объект уже макси- мально освещен. Добавление в функцию main вызова следующей функции по- зволит установить фоновое освещение: float ambient[4] = {0.5, 0.5, 0.5, 1}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient). Задание параметров материала. Материал может рассеи- вать, отражать и излучать свет. Свойства материала устанавли- ваются при помощи функции glMaterialfv(GLenum face, GLenum pname, GLtype* params) Первый параметр определяет грань, для которой устанавли- ваются свойства. Он может принимать одно из следующих зна- чений: GL_BACK – задняя грань, GL_FRONT – передняя грань, GL_FRONT_AND_BACK – обе грани. Второй параметр функции glMaterialfv определяет свойство материала, которое будет установлено, и может принимать сле- дующие значения: GL_AMBIENT – рассеянный свет, GL_DIFFUSE – тоже рассеянный свет (пояснения см. ниже), GL_SPECULAR – отраженный свет, GL_EMISSION – излучаемый свет, GL_SHININESS – степень отраженного света, GL_AMBIENT_AND_DIFFUSE – оба рассеянных света. Ambient и diffuse переводятся на русский как "рассеянный". Разница между ними не очень понятна. Используем только GL_DIFFUSE. Третий параметр определяет цвет соответствую- щего света, кроме случая GL_SHININESS. Цвет задается в виде массива из четырех элементов – RGBA. В случае GL_SHININESS 53 params указывает на число типа float, которое должно быть в диапазоне от 0 до 128. Создание, позиционирование и включение одного или более источников света. В разговорной речи источники света часто именуются просто лампами. Все параметры лампы задаются с помощью функции glLight, которая имеет следующий прототип: void glLight[if][v]( GLenum light, GLenum pname, GLfloat param) Буква v в названии функции определяет, используется ли векторная версия команды. Первый аргумент определяет номер лампы. Его можно зада- вать двумя способами. Первый – явно указать GL_LIHGTi, где GL_LIGHTi предопределено в файле gl.h следующим образом: /* LightName */ #define GL_LIGHT0 0x4000 #define GL_LIGHT1 0x4001 #define GL_LIGHT2 0x4002 #define GL_LIGHT3 0x4003 #define GL_LIGHT4 0x4004 #define GL_LIGHT5 0x4005 #define GL_LIGHT6 0x4006 #define GL_LIGHT7 0x4007 Второй способ – GL_LIGHT0 + i, где i – номер лампы. Такой способ используется, если существует необходимость в цикле изменять параметры ламп. Второй аргумент определяет имя па- раметра, а третий – его значение. С помощью следующих функ- ций разрешаем освещение и включаем нулевую лампу: glEnable(GL_LIGHTING); glEnable(GL_LIGHT0). Массивы pos и dir содержат координаты местоположения лампы и направления, куда она светит. Массив dir содержит три координаты – x, y, z, массив pos – четыре, назначение четвертого не очень ясно. Если его значение отличается от нуля, то изобра- жение получается вполне логичным. При нуле получается некор- ректный результат. По умолчанию цвет всех источников света, кроме GL_LIGHT0, черный: 54 glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir). После настройки параметров источника света его нужно ак- тивизировать командой glEnable(). Параметры источника света. В аргументе param задается значение или значения, в которые следует установить характери- стику pname. Если используется векторная версия команды, param представляет собой вектор величин, а если невекторная, то param – одно единственное значение. Невекторная версия коман- ды может использоваться только для указания параметров, чье значение выражается одним числом. Значения параметров по умолчанию. Имена параметров Значения по умолчанию Смысл GL_AMBIENT (0.0,0.0,0.0,1.0) Интенсивность фонового света GL_DIFFUSE (1.0,1.0,1.0,1.0) или (0.0,0.0,0.0,1.0) Интенсивность диффузного света (значение по умол- чанию для 0-го источника – белый свет, для остальных – черный) GL_SPECULAR (1.0,1.0,1.0,1.0) или (0.0,0.0,0.0,1.0) Интенсивность зеркального света (значение по умол- чанию для 0-го источника – белый свет, для остальных – черный) GL_POSITION (0.0,0.0,1.0,0.0) Положение источ- ника света (x,y,z,w) GL_SPOT_DIRECTION (0.0,0.0,-1.0) Направление света прожектора (x,y,z) GL_SPOT_EXPONENT 0.0 Концентрация светового луча GL_SPOT_CUTOFF 180.0 Угловая ширина светового луча GL_CONSTANT_ATTENUATION 1.0 Постоянный фактор ослабления GL_LINEAR_ATTENUATION 0.0 Линейный фак- тор ослабления GL_QUADRATIC_ATTENUATION 0.0 Квадратичный фактор ослабления 55 Значения по умолчанию для GL_DIFFUSE и GL_SPECULAR в таблице различаются для GL_LIGHT0 и других источников све- та (GL_LIGHT1, GL_LIGHT2, ...). Для параметров GL_DIFFUSE и GL_SPECULAR источника света GL_LIGHT0 значение по умолчанию – (1.0, 1.0, 1.0, 1.0). Для других источников света зна- чение тех же параметров по умолчанию – (0.0, 0.0, 0.0, 1.0). Цвет. OpenGL позволяет ассоциировать с каждым источни- ком света три различных параметра, связанных с цветом: GL_AMBIENT, GL_DIFFUSE и GL_SPECULAR. Параметр GL_AMBIENT задает RGBA интенсивность фонового света, ко- торый каждый отдельный источник света добавляет к сцене: Glfloat light_ambient[]={0.0,0.0,1.0,1.0}; glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); Параметр GL_DIFFUSE, наверное, наиболее точно совпадает с тем, что Вы привыкли называть «цветом света». Он определяет RGBA цвет диффузного света, который отдельный источник све- та добавляет к сцене. По умолчанию для GL_LIGHT0 параметр GL_DIFFUSE равен (1.0, 1.0, 1.0, 1.0), что соответствует яркому белому свету. Значение по умолчанию для всех остальных источ- ников света (GL_LIGHT1, GL_LIGHT2, ..., GL_LIGHT7) равно (0.0, 0.0, 0.0, 0.0). Параметр GL_AMBIENT влияет на цвет зеркального блика на объекте. В реальном мире на объектах вроде стеклянной бутылки имеется зеркальный блик соответствующего освещению цвета (часто белого). Для создания эффекта реалистичности нужно уста- новить GL_SPECULAR в то же значение, что и GL_DIFFUSE. По умолчанию GL_SPECULAR равно (1.0, 1.0, 1.0, 1.0) для GL_LIGHT0 и (0.0, 0.0, 0.0, 0.0) для остальных источников. Позиция и ослабление. Можно выбрать, следует ли считать источник света расположенным бесконечно далеко от сцены или близко к ней. На источники света первого типа ссылаются как на направленные (directional): эффект от бесконечно далекого рас- положения источника заключается в том, что все лучи его света могут считаться параллельными к моменту достижения объекта. Примером реального направленного источника света может слу- жить солнце. Источники второго типа называются позиционными (positional), поскольку их точное положение в сцене определяет 56 их эффект и, в частности, направление, из которого идут лучи. Примером позиционного источника света является настольная лампа. Направленный источник: Glfloat light_position[]={1.0,1.0,1.0,0.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_position); Как видно, для параметра GL_POSITION задается вектор из четырех величин (x, y, z, w). Если последняя величина w равна нулю, соответствующий источник света считается направленным, и величины (x, y, z) определяют его направление. Это направле- ние преобразуется видовой матрицей. По умолчанию параметру GL_POSITION соответствуют значения (0, 0, 1, 0), что задает свет, направленный вдоль отрицательного направления оси z. (Заметьте, что никто не запрещает Вам создать свет, направленный в (0, 0, 0), однако такой свет не даст должного эффекта.) Если значение w не равно нулю, свет является позиционным и величины (x, y, z) задают местоположение источника света в однородных объектных координатах. Это положение преобразу- ется видовой матрицей и сохраняется в видовых координатах. Кроме того, по умолчанию позиционный свет излучается во всех направлениях, но Вы можете ограничить распространение света, создав конус излучения, определяющий прожектор. Задания к работе 1. Построить две сферы с координатами и радиусом, задан- ными для каждого варианта. 2. Задать фоновое освещение с параметрами, заданными для каждого варианта. 3. Задать параметры материала для сфер. Одна из сфер долж- на иметь свойство GL_DIFFUSE , а вторая – GL_SHININESS. Цвет и степень блеска заданы в вариантах задания. 4. Создать источники света, количество которых различно для каждого варианта. Параметры источников света задаются произвольно, однако они должны быть различны для разных ламп. 57 Варианты к заданиям № Координаты центра сферы Радиус сферы Параметры фонового освещения Цвет, степень блеска Кол-во ламп 1 1,0,4 3 0.2,0.2,0.3,1 красный, 45 2 2 2,7,9 5 0.1,0.4,0.1,1 синий, 79 3 3 9,4,10 2.9 0.5,0.3,0.5,1 желтый, 93 1 4 -15,9,2.2 6 0.3,0.6,0.2,1 зеленый, 39 2 5 8,3.8,-1.7 3.4 0.2,0.7,0.1,1 розовый, 122 1 Дополнительные задания 1. В установленном графическом окне построить куб, задать для различных его граней различные параметры материала: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE. 2. Установить диффузный источник света, освещающий бе- лую неблестящую сферу. При нажатии клавиш управления кур- сором лампа должна изменять свой цвет от красного до фиолето- вого в порядке следования цветов в спектре. 3. Установить диффузный источник света, освещающий бе- лую неблестящую сферу. При нажатии клавиш управления кур- сором лампа должна передвигаться в указанном направлении. 4. Построить пирамиду, освещаемую двумя источниками света – красным и зеленым. При нажатии клавиши “G” или “R” интенсивность соответственно зеленого или красного источника света увеличивается на 10%. По достижении интенсивности в 100%, она должна автоматически падать до 10%. 5. Построить куб, освещенный вращающимся вокруг него источником света. При нажатии клавиши «вправо» источник све- та начинает двигаться с большей скоростью. При нажатии кла- виши «влево» скорость движения лампы должна уменьшаться. |