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

       

Часть V



8.2.3.5. Часть V

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

Device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);

Тем не менее, пока решены не все проблемы. Если просто очистить буфер глубины, отражение чайника будет нарисовано поверх зеркала и будет выглядеть неестественно. Необходимо не только очистить буфер глубины, но и выполнить смешивание пикселей отражения с пикселями зеркала. Благодаря этому отражение будет выглядеть так, будто оно находится в глубине зеркала. Для смешивания пикселей отражения чайника с пикселями зеркала мы будем использовать следующую формулу:

ИтоговыйПиксель =
= ПиксельИсточника 

 ПиксельПриемника + ПиксельПриемника 
 (0, 0, 0, 0) =
= ПиксельИсточника 
 ПиксельПриемника

Пиксель источника берется из отражения чайника, а писксель приемника — из зеркала, и формула помогает нам увидеть как они соединяются воедино. В коде это выглядит так:

Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);

Наконец-то мы готовы к рисованию отражения чайника:

Device->SetTransform(D3DTS_WORLD, &W); Device->SetMaterial(&TeapotMtrl); Device->SetTexture(0, 0);

Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); Teapot->DrawSubset(0);

Вспомните, что в разделе 8.2.3.4 мы получили матрицу W, которая помещает отражение чайника в предназначенное ему место сцены. Также обратите внимание, что мы меняем режим удаления невидимых граней. Это необходимо потому, что при отражении объекта его фронтальные и обратные полигоны меняются местами; при этом порядок обхода вершин не меняется. Таким образом порядок обхода вершин «новых» фронтальных граней будет указывать Direct3D, что они являются обратными полигонами. Аналогичным образом порядок обхода вершин «новых» обратных граней будет убеждать Direct3D в том, что они являются фронтальными. Следовательно, для коррекции нам следует изменить условие отбрасывания обратных граней.

Возвращая все в исходное состояние мы запрещаем смешивание и работу буфера трафарета, после чего восстанавливаем стандартный режим отбрасывания обратных граней:

Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false); Device->SetRenderState(D3DRS_STENCILENABLE, false); Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

} // конец функции RenderMirror()



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