Введение в программирование трехмерных игр с DX9

       

Зональный свет



Рисунок 5.6. Зональный свет


В коде источники света представляются структурой D3DLIGHT9.

typedef struct _D3DLIGHT9 { D3DLIGHTTYPE Type; D3DCOLORVALUE Diffuse; D3DCOLORVALUE Specular; D3DCOLORVALUE Ambient; D3DVECTOR Position; D3DVECTOR Direction; float Range; float Falloff; float Attenuation0; float Attenuation1; float Attenuation2; float Theta; float Phi; } D3DLIGHT9;

Type — Задает тип источника света и может принимать одно из трех значений: D3DLIGHT_POINT, D3DLIGHT_SPOT или D3DLIGHT_DIRECTIONAL.

Diffuse — Цвет рассеиваемой составляющей испускаемого источником света.

Specular — Цвет отражаемой составляющей испускаемого источником света.

Ambient — Цвет фоновой составляющей испускаемого источником света.

Position — Вектор, задающий местоположение источника света в пространстве. Для направленного света значение не используется.

Direction — Вектор, задающий направление, в котором распространяется свет. Для точечного света не используется.

Range — Максимальное расстояние, на которое может распространиться свет прежде чем окончательно потухнет. Значение не может быть больше чем √FLT_MAX и не оказывает влияния на направленный свет.

Falloff — Значение используется только для зонального света. Оно определяет как меняется интенсивность света в пространстве между внутренним и внешним конусами. Обычно этому параметру присваивают значение 1.0f.



Attenuation0, Attenuation1, Attenuation2 — Переменные затухания, определяющие как меняется интенсивность света с увеличением расстояния до источника света. Эти переменные используются только для точечного и зонального света. Переменная Attenuation0 задает постоянное затухание, Attenuation1 — линейное затухание и Attenuation2 — квадратичное затухание. Вычисления выполняются по формуле



где D — это расстояние от источника света, а A0, A1, A2 соответственно Attenuation0, Attenuation1 и Attenuation2.


Theta — Используется только для зонального света; задает угол внутреннего конуса в радианах.

Phi — Используется только для зонального света; задает угол внешнего конуса в радианах.

Подобно инициализации структуры D3DMATERIAL9, в том случае, когда нам нужны только простые источники света, инициализация структуры D3DLIGHT9 становится рутинным занятием. Поэтому для инициализации простых источников света мы добавим в файлы d3dUtility.h/cpp следующие функции:

namespace d3d { . . . D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);

D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);

D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color); }

Реализация этих функций не содержит сложных моментов. Мы рассмотрим только реализацию InitDirectionalLight. Остальные функции похожи на нее:

D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = *color * 0.4f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Direction = *direction;

return light; }

Теперь для создания источника направленного света белого цвета, испускающего лучи вдоль оси X в положительном направлении, можно написать:

D3DXVECTOR3 dir(1.0f, 0.0f, 0.0f); D3DXCOLOR c = d3d::WHITE; D3DLIGHT9 dirLight = d3d::InitDirectionalLight(&dir, &c);

После того, как мы инициализировали экземпляр D3DLIGHT9, нам надо зарегистрировать его во внутреннем списке управляемых Direct3D источников света. Делается это вот так:

Device->SetLight( 0, // устанавливаемый элемент списка источников света, диапазон 0 - maxlights &light);// адрес инициализированной структуры D3DLIGHT9

После регистрации источника света мы можем включать его и выключать, как показано в приведенном ниже фрагменте кода:

Device->LightEnable( 0, // Включаемый или выключаемый источник света в списке true); // true = включить, false = выключить


Содержание раздела