4. Освещение.
4.1. Компоненты света и материалы.
Свет в Direct3D состоит из трех компонент: фоновый свет, рассеиваемый свет и отраженный свет. Фоновый свет освещает всю сцену.
Он состоит из совокупности света, отраженного всеми поверхностями объектов сцены. Рассеиваемый свет распространяется в определенном направлении.
Сталкиваясь с объектом, он отражается во всех направлениях (рассеивается в пространстве). Отражаемый свет, при столкновении с поверхностью,
формирует на ней блики. Этот тип света требует большего объема вычислений, чем остальные два, поэтому Direct3D позволяет его отключить (вернее,
подключить, так как по умолчанию он не используется).
рDevice->SetRenderState(D3DRS_SPECULARENABLE, true);
В Direct3D компоненты света задаются, фактически, своим цветом (то есть структурами D3DCOLORVALUE или D3DXCOLOR). При
использовании D3DXCOLOR альфа-канал не учитывается.
Как известно, яблоко имеет зеленый цвет потому, что их кожура поглощает все лучи, кроме зеленых. В Direct3D подобный эффект моделируется
заданием материала для объекта. Материал задает цвет, тип и количество отражаемого света. Он инициализируется структурой D3DMATERIAL9.
typedef struct _D3DMATERIAL9 {
D3DCOLORVALUE Diffuse, Ambient, Specular, Emissive;
float Power;
} D3DMATERIAL9;
Diffuse - рассеиваемый свет.
Ambient - фоновый свет.
Specular - отражаемый свет.
Emissive - собственное свечение объекта.
Power - резкость отражений.
При визуализации, материал объекта задается с помощью метода IDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial). Вот пример задания
материала:
D3DMATERIAL9 green, red;
//задаем один материал
рDevice->SetMaterial(&green);
//рисуем зеленые яблоки...
//задаем другой материал
рDevice->SetMaterial(&red);
//рисуем красные яблоки...
4.2. Задание освещения.
Для того, чтобы Direct3D мог правильно рассчитать освещение сцены, нам придется усовершенствовать нашу структуру с описанием
вершины, добавив туда координаты нормали (или задав её как D3DXVECTOR3). Также, нам придется изменить формат вершин (FVF).
struct NormalVertex
{
float x, y, z;
float nx, ny, nz;//координаты нормали
static const DWORD FVF;
}
const DWORD NormalVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
Нормаль точки можно рассчитать как среднее арифметическое нормалей к граням, содержащим эту точку.
Direct3D поддерживает три типа источников света. Точечный источник испускает лучи во всех направлениях (например: солнце). Источник направленного
света испускает параллельные лучи в строго определенном направлении (например: солнечный зайчик от зеркала). Источник зонального света
испускает конический сноп лучей в заданном направлении (например: фонарик). Любой источник света задается структурой 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 - направление испускаемых лучей (для точечного света не используется).
Остальные параметры задают некоторые физические характеристики света и используются довольно редко.
После инициализации, нам остается только зарегистрировать источник света в списке источников, управляемых Direct3D, и включить
его.
//регистрируем
рDevice->SetLight(
n, //номер источника
&light); //указатель на источник
//включаем
Device->LightEnable(n, true);
Пример приложения: "Освещенная пирамида"
|