Если попытаться классифицировать все известные на сегодня методы освещения, то в первую очередь их можно разделить на программные и аппаратные. При этом программные методы, в которых всю работу выполняет центральный процессор, использовавшиеся задолго до появления 3D акселераторов, являются наиболее часто используемыми сегодня. Аппаратные методы полностью (или почти полностью) реализуются с помощью видеокарты. Эти методы пока редко используются даже в секторе Hi-End.
3.1.1 Полностью программное освещение
Как следует из названия, модуль освещения выключается, а цвета рассчитываются в самой программе. В видеокарту они передаются функциями glColor*. Видеокарте остаётся интерполировать значения цвета между вершинами и наложить текстуру. Как видно, этот метод практически непригоден для моделирования освещения Фонга и, вообще, для высококачественного моделирования.
Карты освещённости (lightmaps), впервые использованные в glQuake, на сегодняшний день широко применяются в 3D играх, т. е. там, где необходимо достичь компромисс между скоростью и качеством.
Очевидно, что, используя только 8 или 16 источников света (типичное ограничение большинства реализаций OpenGL), невозможно добиться по-настоящему реалистичного моделирования. Кроме этого, при увеличении количества источников света скорость падает экспоненциально. В то же время в играх с их огромным числом источников света преобладают постоянные источники с ограниченным радиусом действия (факелы и т. п.). Очевидно, такое освещение может быть вычислено заранее.
Картинка, содержащая световой блик, называется картой освещённости (lightmap). Карты освещённости можно или смешивать с накладываемой на объект текстурой, или применять уже поверх текстуры (двухпроходный вариант). Если ускоритель поддерживает мультитекстурирование (например, 3dfx Voodoo2 и выше, nVidia RivaTNT/GeForce, S3 Savage, ATI Rage 128 или Radeon), то такое освещение почти не снижает скорости работы.
Карты освещённости перебрасывают всю наиболее тяжёлую работу с процессора на 3D-акселератор. Цена этого решения - активное использование ограниченной локальной (текстурной) памяти видеокарты и/или интенсивный обмен по системной шине.
Качество такого "освещения" сильно зависит от количества и размера карт освещённости. Практика показала, что выгодно для простых объектов использовать карты освещённости, а более сложные, состоящие из многих плоскостей, освещать стандартными средствами OpenGL. Результат - более высокие скорость работы и качество изображения, чем, если бы эти два метода применялись по отдельности.
Рисунок 3.1 - Сцена без освещения |
Рисунок 3.2 - Карты освещённости |
Рисунок 3.3 - Сцена с освещением |
Несмотря на очевидные преимущества, метод имеет свои недостатки. Если в сцене преобладают сложные объекты, то проецирование на сотни и тысячи плоскостей одновременно окажется даже медленнее, чем математические расчёты в вершинах.
Затем, алгоритм многопроходный по своей сути. Отключение расчётов уравнения освещения в несколько раз снижает ограничение по геометрии, но затем придётся умножить время расчёта и передачи в акселератор данных на число проходов. Даже при использовании мультитекстурирования, возможно, к многопроходному варианту всё равно придётся прибегнуть.
3.1.3 Виртуальные источники света
Можно использовать и стандартные средства освещения OpenGL, учитывая программно-аппаратное ограничение на число источников света. Марк Килгард (Mark J. Kilgard) в своей работе рассмотрел две возможные модификации метода [5]. В обоих случаях все источники помещались в один список, и сортировались согласно их важности, или ("яркости"). Разница состояла только в способе вычисления этой "яркости". В конечном счёте, так или иначе, использовались только самые "важные" источники.
В первом, самом простом случае, учитывалось только расстояние до объекта, "яркостью" был взятый с обратным знаком квадрат расстояния.
Второй вариант использует модель Ламберта. Согласно закону Ламберта, диффузная составляющая (GL_DIFFISE) пропорциональна косинусу угла между нормалью к поверхности, и направлением луча света.
Видно, что оба метода, несмотря на несколько разную теорию, дают, в конечном счёте, весьма похожие результаты.
Алгоритм может быть дополнительно усовершенствован за счёт учёта энергии источника, т. е. лучше всегда отдавать предпочтение источникам с большей энергией. Амплитудой источника A можно считать значение яркости luma=0.299*R + 0.587*G + 0.114*B. Целесообразно в качестве цвета RGB взять диффузную составляющую источника света
Второе усовершенствование касается расчёта расстояния до объекта. Это связано с тем, что расчёт расстояния до центра объекта можно использовать только для сферических объектов, в противном случае можно, например, ввести несколько "контрольных точек" и учитывать расстояние до каждой из них.
3.1.4 Накопление освещённости
Кроме всех перечисленных трюков, можно использовать стандартные средства освещения OpenGL, а ограничение числа источников преодолевать с помощью буфера накопления (accumulation buffer). Если каждый источник освещает все объекты, алгоритм достаточно прост. Суммарная освещённость поверхности состоит из "фонового освещения" (GL_LIGHT_MODEL_AMBIENT), общего для всей сцены, и отдельных составляющих, вносимых каждым источником. Кроме того, "снизу" сцены обычно выводится фоновая картинка (небо и горизонт), а "поверх" накладываются спецэффекты вроде тумана и т.п. Это тоже надо учесть, чтобы не применить спецэффекты несколько раз к одному и тому же изображению.
Очевидно, что данный метод является самым "честным", и, естественно, самым медленным. А если ещё учесть, что на большинстве 3D акселераторов буфер накопления реализуется исключительно программными средствами, то этот метод вряд ли можно считать пригодным для приложений реального времени.