Прозрачные объекты.
Автор: MegaMax
В этой статье я хотел бы рассмотреть такой замечательный эффект как прозрачность. Существует несколько способов добавления прозрачности в Вашу сцену, рассмотрим несколько из них ... но чуть попозже, сначала я бы хотел немного отойти от темы и рассказать про то, как написан пример, чтобы потом не было лишних вопросов ;)
Чтобы не утруждать себя написанием каркаса приложения, я использовал D3DFramework, который поставляется вместе с DX9SDK и с его помощью можно легко создавать простенькие приложения (например, наше). Я использовал DX9Appwizard для создания каркаса.
Далее, так как я страшно ленивый человек, то коробку, которая рисуется в примере, я не захотел рисовать ручками и использовал функцию D3DXCreateBox(). Потом с помощью метода CloneMesh() интерфейса ID3DXMesh я сделал нашей коробки нужных формат вершин, кстати, формат вершин описывал не при помощи FVF, а с помощью Vertex Declaration (если возникнут вопросы по этому моменту, то прошу в форум, поговорим :). Еще я нарисовал фон, чтобы можно было отчетливее увидеть работу того или иного метода.
Вроде все рассказал, теперь собственно к делу!!
Что есть альфа блендинг (alpha blending)?
Альфа канал в вершинах
Альфа канал в материале
Альфа канал в текстуре
Альфа блендинг и буфер кадра
Альфа блендинг и RenderTarget
Альфа-тест
ColorKeys
Что есть альфа блендинг (alpha blending)?
Альфа блендинг используется для того, чтобы отображать изображения в которых есть прозрачные или полупрозрачные пиксели. В дополнение к красной, зеленой и синей цветовой составляющей, каждый пиксель может иметь "прозрачную" составляющую, которую в народе называют альфа канал (alpha channel). Альфа канал обычно имеет столько же бит, сколько и основное цветовой канал. Например, восьми битный альфа канал может иметь 256 уровней прозрачности, от 0 (пиксель полностью прозрачен) до 255 (пиксель полностью не прозрачен).
Для включения альфа блендинга, в Direct3D необходимо установить параметр D3DRS_ALPHABLENDENABLE в TRUE:
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
В Direct3D цвет может быть задан как с использованием альфа канала (RGBA), так и без него (RGB). Прозрачность может содержаться в вершинах, в материале, в текстуре. Также можно использовать буфер кадра (Frame buffer), чтобы делать некоторые эффекты.
Рассмотрим подробнее все эти методы.
Альфа канал в вершинах
Название метода говорит само за себя. Альфа канал мы будем хранить в каждой вершине объекта. Для включения этого метода необходимо установить параметр D3DRS_DIFFUSEMATERIALSOURCE в D3DMCS_COLOR1. Этим мы даем понять, что хотим использовать цвет из вершинных данных, а не из материала.
m_pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
Рассмотрим, что же значат эти параметры:
D3DRS_DIFFUSEMATERIALSOURCE - определяет источник цвета для расчета освещения. Может иметь следующие значения:
D3DMCS_MATERIAL - использует цвет из текущего материала
D3DMCS_COLOR1 - использует diffuse color из вершины
D3DMCS_COLOR2 - использует specular color из вершины
По умолчанию стоит D3DMCS_COLOR1.
Также нам надо дать понять Direct3D, что мы хотим, чтобы цвет вершин участвовал в просчете освещения. Делается это следующим образом:
m_pd3dDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE );
В принципе, это состояние по умолчанию стоит в TRUE, но на всякий пожарный поставить надо.
Теперь нам надо добавить альфа канал в каждую вершину нашей коробки:
BoxVertex* pVertices; m_pBoxVB->Lock(0, 0, ( VOID**)&pVertices, 0); WORD t; // Add alpha value to vertices for ( t=0; t<m_dwNumVertices; t++ ) pVertices[t].Diffuse = 0x77FF0000; m_pBoxVB->Unlock( );
Альфа канал задается первой парой чисел. Для удобства можно использовать макрос D3DCOLOR_ARGB(alpha, red, green, blue). Каждый параметр макроса может иметь значение от 0 до 255.
Подробно рассматривать формат вершин я не буду, т.к. это не соответствует теме статьи, но повторюсь, если есть вопросы, то прошу в форум, обязательно отвечу.
Вот и все, теперь, установив нужные состояния конвейера рендеринга мы можем нарисовать нашу коробку:
m_pd3dDevice->SetVertexDeclaration(m_pBoxDeclaration); m_pd3dDevice->SetStreamSource( 0, m_pBoxVB, 0, 28); m_pd3dDevice->SetIndices( m_pBoxIB); m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_dwNumVertices, 0, m_dwPrimitivesCount);
А вот и результат:
Альфа канал в материале
Мы можем определить альфа канал и в материале. Для этого создадим материал, который содержит его:
D3DMATERIAL9 mtrl; ZeroMemory(&mtrl, sizeof( mtrl) ); mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambient.g = 0.0f; mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f; mtrl.Diffuse.a = mtrl.Ambient.a = 0.7f; //<<-- степень прозрачности.
Для включения метода устанавливаем D3DRS_DIFFUSEMATERIALSOURCE в D3DMCS_MATERIAL:
m_pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
Вот собственно и все. Незабываем установить наш материал, рисуем коробку и смотрим, что получилось.
#Direct3D, #основы, #прозрачность, #текстурирование
11 марта 2003 (Обновление: 2 июля 2009)
Комментарии [7]