效果
什麼是 Direct2D 效果?
您可以使用 Direct2D 將一或多個高品質的效果套用至影像或一組影像。 效果 API 建置在 Direct3D 11 上,並利用 GPU 功能進行影像處理。 您可以在效果圖形中鏈結效果,並撰寫或混合效果的輸出。
Direct2D 效果會執行影像工作,例如變更亮度、解除飽和影像,或建立陰影。 效果可以接受零個或多個輸入影像、公開多個控制其作業的屬性,併產生單一輸出影像。
每個效果都會建立由個別轉換組成的內部轉換圖形。 每個轉換都代表單一影像作業。 轉換的主要目的是要容納針對每個輸出圖元執行的著色器。 這些著色器可以包含圖元著色器、頂點著色器、GPU 的混合階段,以及計算著色器。
您可以使用自定義效果 API 來讓 Direct2D 內建效果和自訂效果都能以這種方式運作。
有一系列來自類別的 內建效果,例如此處的內建效果 。 如需完整清單,請參閱內建效果一節。
您可以將效果套用至任何點陣圖,包括:由 Windows 圖像處理元件 (WIC) 載入的影像、Direct2D 所繪製的基本類型、DirectWrite 中的文字,或 Direct3D 所呈現的場景。
透過 Direct2D 效果,您可以撰寫自己的效果,以用於應用程式。 自定義效果架構可讓您使用 GPU 功能,例如圖元著色器、頂點著色器和混合單位。 您也可以在自定義效果中包含其他內建或自定義效果。 建置自定義效果的架構與用來建立 Direct2D 內建效果的架構相同。 Direct2D 效果作者 API 提供一組介面來建立和註冊效果。
更多效果主題
本主題的其餘部分說明 Direct2D 效果的基本概念,例如將效果套用至影像。 下表提供有關效果的其他主題連結。
主題 | 說明 |
---|---|
效果著色器連結 |
Direct2D 使用稱為效果著色器鏈接的優化,結合多個效果圖形轉譯傳遞至單一階段。 |
自訂效果 |
示範如何使用標準 HLSL 撰寫自己的自定義效果。 |
如何使用 FilePicker 將影像載入 Direct2D 效果 |
示範如何使用 Windows::Storage::P ickers::FileOpenPicker 將影像載入 Direct2D 效果。 |
如何將 Direct2D 內容儲存至影像檔案 |
本主題說明如何使用 IWICImageEncoder,將標識碼 2D1Image 格式的內容儲存至編碼的影像檔案,例如 JPEG。 |
如何將效果套用至基本類型 |
本主題說明如何將一系列效果套用至 Direct2D 和 DirectWrite 基本類型。 |
控制效果圖形中的有效位數和數值裁剪 |
使用 Direct2D 轉譯效果的應用程式必須小心,才能達到與數值精確度相關的所需品質和可預測性層級。 |
將效果套用至影像
您可以使用 Direct2D 效果 API 將轉換套用至影像。
注意
此範例假設您已經建立ID2D1DeviceContext和IWICBitmapSource物件。 如需建立這些對象的詳細資訊,請參閱 如何使用 FilePicker 和 裝置內容將影像載入 Direct2D 效果。
宣告 ID2D1Effect 變數,然後使用 ID2DDeviceContext::CreateEffect 方法建立位圖來源效果。
ComPtr<ID2D1Effect> bitmapSourceEffect; DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
使用 ID2D1Effect::SetValue,將BitmapSource屬性設定為WIC位圖來源。
DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
宣告ID2D1Effect變數,然後建立高斯模糊效果。
ComPtr<ID2D1Effect> gaussianBlurEffect; DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
設定輸入以接收來自位圖來源效果的影像。 設定 SetValue 方法和標準偏差屬性的模糊量。
gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get()); DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
使用裝置內容來繪製產生的影像輸出。
m_d2dContext->BeginDraw(); m_d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue)); // Draw the blurred image. m_d2dContext->DrawImage(gaussianBlurEffect.Get()); HRESULT hr = m_d2dContext->EndDraw();
必須在 ID2DDeviceContext::BeginDraw 和 EndDraw 呼叫之間呼叫 DrawImage 方法,就像其他 Direct2D 轉譯作業一樣。 DrawImage 可以擷取影像或效果的輸出,並將其轉譯至目標表面。
空間轉換
Direct2D 提供內建效果,可轉換 2D 和 3D 空間中的影像,以及縮放比例。 縮放和轉換效果提供各種品質等級,例如:最接近的鄰居、線性、立方體、多樣本線性、異向性,以及高品質的立方體。
注意
不過,當您將 Cached 屬性設定為 true 時,非等性模式會在縮放時產生 Mipmap,但是,如果您將 Cached 屬性設定為 true,則每次對於足夠小的影像而言,都不會產生 mipmap。
ComPtr<ID2D1Effect> affineTransformEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
affineTransformEffect->SetInput(0, bitmap.Get());
D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F(0.9f, -0.1f, 0.1f, 0.9f, 8.0f, 45.0f);
DX::ThrowIfFailed(affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix));
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(affineTransformEffect.Get());
m_d2dContext->EndDraw();
這種使用 2D 仿射轉換效果會稍微旋轉點陣圖逆時針旋轉。
之前 |
---|
之後 |
撰寫影像
某些效果接受多個輸入,並將其複合成一個產生的影像。
內建複合和算術複合效果提供各種模式,如需詳細資訊,請參閱 複合 主題。 混合效果具有各種可用的 GPU 加速模式。
ComPtr<ID2D1Effect> compositeEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));
compositeEffect->SetInput(0, bitmap.Get());
compositeEffect->SetInput(1, bitmapTwo.Get());
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();
複合效果會根據您指定的模式,以各種不同方式結合影像。
像素調整
有幾個內建 Direct2D 效果可讓您改變像素數據。 例如,色彩矩陣效果可用來變更影像的色彩。
ComPtr<ID2D1Effect> colorMatrixEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1ColorMatrix, &colorMatrixEffect));
colorMatrixEffect->SetInput(0, bitmap.Get());
D2D1_MATRIX_5X4_F matrix = D2D1::Matrix5x4F(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
DX::ThrowIfFailed(colorMatrixEffect->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix));
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(colorMatrixEffect.Get());
m_d2dContext->EndDraw();
此程式代碼會擷取影像並改變色彩,如此處範例影像所示。
之前 |
---|
之後 |
建置效果圖形
您可以將效果鏈結在一起以轉換影像。 例如,這裡的程式代碼會套用陰影和 2D 轉換,然後將結果組合在一起。
ComPtr<ID2D1Effect> shadowEffect;
ComPtr<ID2D1Effect> affineTransformEffect;
ComPtr<ID2D1Effect> compositeEffect;
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Shadow, &shadowEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect));
DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect));
shadowEffect->SetInput(0, bitmap.Get());
affineTransformEffect->SetInputEffect(0, shadowEffect.Get());
D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation(20, 20));
affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix);
compositeEffect->SetInputEffect(0, affineTransformEffect.Get());
compositeEffect->SetInput(1, bitmap.Get());
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();
以下是結果。
效果會採用 ID2D1Image 對象作為輸入。 您可以使用ID2D1Bitmap,因為介面衍生自ID2D1Image。 您也可以使用ID2D1Effect::GetOutput來取得ID2D1Effect對象的輸出做為ID2D1Image,或使用SetInputEffect方法來為您轉換輸出。 在大部分情況下,效果圖是由 ID2D1Effect 物件直接鏈結在一起,這可讓您輕鬆地將多個效果套用至影像,以建立吸引人的視覺效果。
如需詳細資訊,請參閱 如何將效果套用至基本類型 。