Войти
ПрограммированиеСтатьиГрафика

Прозрачные объекты. (2 стр)

Автор:

Альфа канал в текстуре

Итак мы подошли пожалуй к самому широко используемому методу получения прозрачности. Реализуется он не просто, а очень просто ;)

Для начала нам надо создать текстуру с альфа каналом. Я делал это следующим образом: первым делом запустил DX Texture Tool и создал текстуру с форматом A8R8G8B8 (можно выбрать и другой формат, но надо, чтобы он поддерживал альфа канал). Затем в Adobe Photoshop нарисовал прямоугольник с градиентной заливкой, наподобие такого:

Изображение

И вставил его как альфа канал в созданную текстуру. Далее вставил основное изображение и сохранил.

Теперь нам надо установить текстуру и текстурные состояния (на загрузку не буду отвлекаться, ок?).

    
    // Устанавливаем стейты для отображения текстуры ...
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

    // Устанавливаем текстуру
    m_pd3dDevice->SetTexture(0, m_pAlphaTexture);

Ну посмотрим, чего же мы тут наворотили. Нас в первую очередь интересуют параметры D3DTSS_ALPHAOP, D3DTSS_ALPHAARG1, D3DTSS_ALPHAARG2.

D3DTSS_ALPHAOP - определяет какая операция используется при альфа блендинге. Может принимать одно из значений из перечисляемого типа D3DTEXTUREOP.

D3DRSS_ALPHAARG1(2) - определяет откуда будут браться значения цветов пикселей при смешивании. Может принимать одно из значений из перечисляемого типа D3DTA.

Вы также можете почитать про параметры и их значения в статье про мультитекстурирование(линк) или в DX9SDK.

Вот собственно и все. Посмотрим, что из этого получилось:

Изображение

Можно поэкспериментировать с параметрами блендинга и добиться очень интересных результатов ;)

Альфа блендинг и буфер кадра

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

При альфа блендинге мы смешиваем 2 цвета: исходный и существующий. Исходный цвет берется из нашего прозрачного объекта, а существующий из пикселя, с которым мы будем смешивать цвета. Цвет существующего пикселя может быть получен путем рендринга предыдущих объектов, которые расположены позади нашего прозрачного объекта и буду видны сквозь него. Вот формула, по которой вычисляется конечный цвет пикселя:

Final Color=ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor
ObjectColor - цвет пикселя примитива
PixelColor - цвет уже существующего в буфере кадра

Типы смешивания можно посмотреть в SDK в перечисляемом типа D3DBLEND

Итак, установим параметры блендинга:

     m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
     m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR );
     m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND,D3DBLEND_INVSRCCOLOR );

Вот и все ;) теперь можно рисовать и смотреть, что же у нас получилось. Скриншота тут не будет, предоставлю возможность его получения читателю.

Альфа блендинг и RenderTarget

Существует еще один способ альфа блендинга. Мы можем смешивать альфа канал отдельно от цветового канала. Это достигается путем установления параметра D3DRS_SEPARATEALPHABLENDENABLE в TRUE.

Когда этот параметр установлен в FALSE (по умолчанию) операции смешивания для альфа канала и цветового канала одинаковы. Данная возможность поддерживается не всеми видеокартами, поэтому необходимо проверить, поддерживается ли она. Посмотреть это можно в структуре D3DCAPS9 в члене PrimitiveMiscCaps например следующим образом:

    if( pCaps->PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND )
       bCapsAcceptable = TRUE;   

Для управления типами смешивания есть два параметра: D3DRS_SRCBLENDALPHA и D3DRS_DESTBLENDALPHA. Их значения и смысл сходны с D3DRS_SRCBLEND и D3DRS_DESTBLEND, но применяются только к альфа каналу. Так же надо установить D3DRS_BLENDOPALPHA для определения как будут смешиваться исходные и существующие пиксели.

Прозрачность вычисляется по следующей формуле:

renderTargetAlpha = (alphain* srcBlendOp) BlendOp (alphart* destBlendOp)

Где:
alphain - значение альфа канала в исходном пикселе
srcBlendOp - тип смешивания у источника
BlendOp - определяет как смешиваются исходный пиксель и уже существующий в render target.
alphart - значение альфа канала в существующем пикселе в render target
destBlendOp - тип смешивания у render target

Альфа-тест

Мы можем использовать так называемый альфа-тест для управления рисованием пикселей, т.е. будут нарисованы только те пиксели, которые прошли альфа тест, который определяется установленной функцией. Включить альфа тест мы можем установив D3DRS_ALPHATESTENABLE в TRUE. Функция для альфа теста устанавливается при помощи D3DRS_ALPHAFUNC, а значение, с которым будет сравниваться в D3DRS_ALPHAREF. Использование альфа теста может увеличить производительность приложения, т.к. пиксели, которые не прошли тест просто не буду растеризоваться. Но не все видео карты поддерживают все возможности альфа теста, поэтому перед тем как использовать ту или функцию необходимо проверить поддерживает ли ее адаптер. Вот небольшой пример как можно использовать альфа тест:

if (pCaps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL)
{
    m_pd3dDevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x00000001);
    m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); 
    m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
}
Значения D3DRS_ALPHAFUNC могут быть:
D3DCMP_NEVER - ни один из пикселей не пройдет тест
D3DCMP_LESS - тест пройдут пиксели, альфа канал у которых меньше чем установленный в D3DRS_ALPHAREF
D3DCMP_EQUAL - тест пройдут пиксели, альфа канал у которых равен установленному в D3DRS_ALPHAREF
D3DCMP_LESSEQUAL - тест пройдут пиксели, альфа канал у которых меньше или равен установленному в D3DRS_ALPHAREF
D3DCMP_GREATER - тест пройдут пиксели, альфа канал у которых больше чем установленный в D3DRS_ALPHAREF
D3DCMP_NOTEQUAL - тест пройдут пиксели, альфа канал у которых не равен установленному в D3DRS_ALPHAREF
D3DCMP_GREATEREQUAL - тест пройдут пиксели, альфа канал у которых, больше или равен установленному в D3DRS_ALPHAREF
D3DXMP_ALWAYS - все пиксели пройдут тест

ColorKeys

Есть еще один способ, который я бы никому не советовал использовать, т.к. он не является таким гибким как тот же альфа блендинг.

Это использование ключей прозрачности (ColorKeys). Т.е. задается некоторый цвет в текстуре, который не будет отображаться, т.е. пиксель с этим цветом будет прозрачным. Для использования этого метода необходимо правильно создать текстуру, например с помощью функции D3DXCreateTextureFromFileEx(). У этой функции один из параметров называется ColorKey, который и определяет, какой цвет в текстуре будет прозрачен. Дополнительную информацию можно найти в DXSDK.

Ну вот вроде бы и все, что я имею вам сказать. Все комментарии принимаются в форуме или на мыло.

Исходник к статье: 20030311.zip (474 кБ).

Enjoy.

Страницы: 1 2

#Direct3D, #основы, #прозрачность, #текстурирование

11 марта 2003 (Обновление: 2 июля 2009)

Комментарии [7]