DirectX Графика в проектах Delphi

Частичная прозрачность объемных фигур



Предыдущие разделы подготовили нас к тому, чтобы вплотную заняться выводом объемных полупрозрачных объектов. Для начала рассмотрим вывод одной единственной фигуры на сцене (проект каталога Ех10), в которой сфера стала наполовину прозрачной (рис. 10.7).

Рис. 10.7. Первый пример частичной прозрачности объемных фигур

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

with FD3DDevice do begin
SetTransform(D3DTS WORLD, matSphere) ;
// Устанавливаем полупрозрачный материал SetMaterial(MaterialSphere); // Включаем режим смешения
SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD(True)); // Первой выводится внутренняя сторона сферы SetRenderState(D3DRS_CULLMODE, D3DCULL__CW);
DrawPrimitive(D3DPT_TRIANGLELIST, 30 + 51 + 51 + 960, 960); // Внешняя сторона сферы
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
DrawPrimitive(D3DPT_TRIANGLELIST, 30 +o 51 + 51, 960);
SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD(False));
end;

Обязательно посмотрите, как работает пример с переставленным порядком воспроизведения и убедитесь, что в этом случае эффект получается точно таким же, как и при отсутствии воспроизведения внутренней стороны сферы.
Теперь мы попытаемся внести в сцену еще небольшое изменение - сделать полупрозрачным конус. Конечно, мы помним, что помимо изменения свойств материала для конуса требуется также добавить дублированное описание, с перевернутыми нормалями его внутренней стороны. Но для этой фигуры нашей композиции есть еще одна тонкость: конус стоит на полу комнаты, его дно соприкасается с квадратом пола. Следовательно, на время воспроизведения этой части фигуры надо отключать работу с Z-буфером, иначе при включении полупрозрачности нам станут видны паразитные узоры. В коде примера из каталога Ex11 я и делаю именно так:


// Первой воспроизводится внутренняя поверхность конуса
SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
DrawPrimitive(D3DPT_TRIANGLEFAN, 81 + 51, 49); // Сам конус
// Дно конуса рисуется с отключенной работой Z-буфера
SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
DrawPrimitive(D3DPT_TRIANGLEFAN, 81 + 51 + 51, 49); // Дно
SetRenderState(D3DRS_ZENABLE, D3DZBJTRUE); // Второй воспроизводится внешняя поверхность конуса
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
DrawPrimitive(D3DPTjrRIANGLEFAN, 30, 49);
SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
DrawPrimitive(D3DPT_TRIANGLEFAN, 81, 49);

Конус теперь рисуется замечательно, и мы видим его внутреннюю часть, на которой нет никаких непрошеных узоров. Однако работа примера не может удовлетворять нас полностью, поскольку при прохождении сферы за конусом она становится невидна, как будто конус непрозрачный (рис. 10.8).



Рис. 10.8. При присутствии на сцене нескольких полупрозрачных объектов требуется сортировка вывода

Мы знаем, почему так происходит и что необходимо сделать, чтобы все выводилось правильно. Объекты следует воспроизводить отсортированными в поле зрения так, чтобы первыми выводились более удаленные объекты, и заполнять кадр полупрозрачным цветом до того, как будет применена операция отсечения по содержимому буфера глубины.
Сейчас посмотрите работу проекта каталога Ех12, в котором оба объекта выводятся полупрозрачными. В зависимости от текущего значения переменной Angle, определяющего положение сферы в пространстве, задаем порядок вывода фигур сцены: первой воспроизводится фигура, располагающаяся в текущий момент дальше от глаза наблюдателя:

if Angle < Pi
then // Конус расположен дальше, чем сфера; первым выводится конус
else // Конус загораживает сферу; первой выводится сфера


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