Главная » Статьи » Учебник: теория

Источники света.
Основы

В обычной жизни при включении лампы мы увидим, что она освещает всё окружающее её пространство, в Panda3D это не так. Недостаточно просто создать источник - ему необходимо указать какие узлы сцены он должен освещать. Итого шаги, которые необходимо совершить для того чтобы осветить нашу сцену:
1. создать узел - источник света необходимого типа;
2. поместить его куда-нибудь в сцену;
3. указать что он может освещать.
И в виде кода:

Code
dlight = DirectionalLight('my dlight')
dlnp = render.attachNewNode(dlight)
render.setLight(dlnp)

Когда мы прекрепляем источник света как узел сцены с помощью attachNewNode, то получаем NodePath, на который можно воздействовать стандартными для NodePath способами - вращать, перемещать, прикреплять к другим узлам.
В приведённом фрагменте кода мы указываем, что источник должен освещать render - корневой узел сцены, т.е. фактически будет освещаться вся сцена, т.к. освещение так же применяется ко всем дочерним узлам указанного узла. Если необходимо убрать эффект освещения с какого-то узла, в т.ч. дочернего, то нужно вызвать метод clearLight() для этого узла. Например sofa.clearLight(dlnp). Такой подход даёт большую гибкость и возможности для оптимизации.

Производительность

Одиночный источник света фактически не влияет на производительность, точно так же как и пять-шесть источников, освещающих всю сцену. Однако, если у вас в сцене находится очень большое количество источников, например подземелье с сотней факелов, то могут возникнуть проблемы. В этом случае имеет смысл указывать для объектов только несколько ближайших источников. Вообще грамотное планирование уровня с разбиением его на части может значительно улучшить скорость его обработки не только для освещения, но и для коллизий и рендеринга.
При включении попиксельного освещения источники становятся значительно прожорливее в плане производительности.

Цвет источников

Все источники имеют цвет. По умолчанию он белый, однако, можно назначить и другой с помощью метода light.setColor(VBase4(r, g, b, a)). Компонент a не учитывается. Например dlight.setColor(Vec4(1,0,0,1)). Компоненты могут быть больше 1 для более яркого освещения, однако, ярче чем изначальный цвет текстуры таким образом сделать модель не получится.

Точечный источник (Point light)

Точечный источник представляет собой "лампочку", испускающую свет во все стороны, т.е. для него не важна ориентация, однако важна пзиция, т.к. он имеет ограниченный радиус.

Code
plight = PointLight('plight')
plight.setColor(VBase4(0.2, 0.2, 0.2, 1))
plnp = render.attachNewNode(plight)
plnp.setPos(10, 20, 0)
render.setLight(plnp)

Затухание (Attenuation)

Можно указать источнику света затухание, так что с дистанцией его свет будет постепенно слабеть. Для этого существует метод plight.setAttenuation(Point3(A, B, C)). A, B и С - коэффициенты затухания. Обычно достаточно установить A и B в 0, а C между 0 и 1.

Направленый источник (Directional light)

Направленный источник представляет собой бесконечный параллельный поток света. Для направленного источника не важна позиция, но важна ориентация. По-умолчанию источник направлен по положительной оси Y, ориентацию можно изменить стандартными для NodePath способами - прикрепить к ориентированному в нужном направлении узлу, изменить угол или воспользоваться методом lookAt(otherNodePath).

Code
dlight = DirectionalLight('dlight')
dlight.setColor(VBase4(0.8, 0.8, 0.5, 1))
dlnp = render.attachNewNode(dlight)
dlnp.setHpr(0, -60, 0)
render.setLight(dlnp)

Окружающее освещение (Ambient light)

Используется для задания общего рассеянного освещения сцены, лишённой других источников света. При наличии дополнительного освещения влияет на цвет и глубину теней. Для него не важны ни позиция, ни ориентация.

Code
alight = AmbientLight('alight')
alight.setColor(VBase4(0.2, 0.2, 0.2, 1))
alnp = render.attachNewNode(alight)
render.setLight(alnp)

Прожектор (Spotlight)

Пржектор представляет собой наиболее типичный источник света, который имеет направление, начальную точку и "поле зрения". В действительности такой источник содержит "линзу" наподобие линзы камеры и освещает всё что попадает в поле зрения этой линзы. Можно воспользоваться свойствами линзы для установки угла и дальности освещения такого источника. Можно так же заменить тип линзы.
Замечание - Spotlight в английском пишется слитно и поэтому класс такого источника называется Spotlight а не SpotLight, как часто ошибочно пытаются писать.

Code
slight = render.attachNewNode(Spotlight("Spot"))
slight.node().getLens().setFov(40)
slight.node().getLens().setNearFar(1,50)
slight.setPos(-5,-5,-5)
slight.lookAt(0,0,0)
render.setLight(slight)

Теневые карты

В версии панды 1.7.0 была добавлена автоматическая генерация теневых карт для источников типа прожектор. Для включения необходимо вызвать метод setShadowCaster и включить генератор шейдеров для затеняемых объектов сцены.

Code
# Используется карта теней в разрешении 512x512
light.setShadowCaster(True, 512, 512)
# Включение генератора для корневого узла сцены
render.setShaderAuto()

Учитывая, что источники света в данном случае имеют линзу и фактически являются камерами, для них можно назначать маску чтобы исключить какие-то объекты из обработки для повышения производительности.
Если в сцене есть очень тонкие объекты, то может возникнуть ситуация, когда из-за погрешностей в вычислениях задняя сторона такого объекта отбрасывает тень на переднюю. Для таких объектов нужно установить смещение глубины. myNodePath.setDepthOffset(1), либо использовать параметр depth-offset в самом файле модели.
Категория: Учебник: теория | Добавил: ninth (14.12.2010)
Просмотров: 8887 | Рейтинг: 3.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Онлайн всего: 1
Гостей: 1
Пользователей: 0