Efeitos

O que são efeitos Direct2D?

Você pode usar Direct2D para aplicar um ou mais efeitos de alta qualidade a uma imagem ou um conjunto de imagens. As APIs de efeitos são criadas no Direct3D 11 e aproveitam os recursos de GPU para processamento de imagens. Você pode encadear efeitos em um grafo de efeito e compor ou misturar a saída de efeitos.

Um efeito Direct2D executa uma tarefa de geração de imagens, como alterar o brilho, desaturar uma imagem ou criar uma sombra de soltar. Os efeitos podem aceitar zero ou mais imagens de entrada, expor várias propriedades que controlam sua operação e gerar uma única imagem de saída.

Cada efeito cria um grafo de transformação interno composto por transformações individuais. Cada transformação representa uma única operação de imagem. A main finalidade de uma transformação é abrigar os sombreadores executados para cada pixel de saída. Esses sombreadores podem incluir sombreadores de pixel, sombreadores de vértice, o estágio de combinação de uma GPU e sombreadores de computação.

Os efeitos Direct2Dembutidos e os efeitos personalizados que você pode fazer usando a API de efeitos personalizados funcionam dessa maneira.

Há uma variedade de efeitos internos de categorias como as que estão aqui. Consulte a seção Efeitos Internos para obter uma lista completa.

Você pode aplicar efeitos a qualquer bitmap, incluindo: imagens carregadas pelo COMPONENTE de Imagem do Windows (WIC), primitivos desenhados por Direct2D, texto de DirectWrite ou cenas renderizadas pelo Direct3D.

Com Direct2D efeitos, você pode escrever seus próprios efeitos que você pode usar para seus aplicativos. Uma estrutura de efeito personalizado permite que você use recursos de GPU, como sombreadores de pixel, sombreadores de vértice e a unidade de mesclagem. Você também pode incluir outros efeitos internos ou personalizados em seu efeito personalizado. A estrutura para criar efeitos personalizados é a mesma que foi usada para criar os efeitos internos de Direct2D. A API de autor do efeito Direct2D fornece um conjunto de interfaces para criar e registrar efeitos.

Tópicos de mais efeitos

O restante deste tópico explica os conceitos básicos de Direct2D efeitos, como aplicar um efeito a uma imagem. A tabela aqui tem links para tópicos adicionais sobre efeitos.

Tópico Descrição
Vinculação de Sombreador de Efeito
Direct2D usa uma otimização chamada vinculação de sombreador de efeito que combina várias passagens de renderização de grafo de efeito em uma única passagem.
Efeitos personalizados
Mostra como escrever seus próprios efeitos personalizados usando o HLSL padrão.
Como carregar uma imagem em efeitos de Direct2D usando o FilePicker
Mostra como usar o Windows::Storage::P ickers::FileOpenPicker para carregar uma imagem em Direct2D efeitos.
Como salvar o conteúdo do Direct2D em um arquivo de imagem
Este tópico mostra como usar IWICImageEncoder para salvar conteúdo na forma de uma ID2D1Image em um arquivo de imagem codificado, como JPEG.
Como aplicar efeitos a primitivos
Este tópico mostra como aplicar uma série de efeitos a primitivos Direct2D e DirectWrite.
Controlando a precisão e o recorte numérico em grafos de efeito
Os aplicativos que renderizam efeitos usando Direct2D devem ter cuidado para alcançar o nível desejado de qualidade e previsibilidade em relação à precisão numérica.

Aplicando um efeito a uma imagem

Você pode usar a API de efeitos Direct2D para aplicar transformações a imagens.

Observação

Este exemplo pressupõe que você já tenha objetos ID2D1DeviceContext e IWICBitmapSource criados. Para obter mais informações sobre como criar esses objetos, consulte Como carregar uma imagem em Direct2D efeitos usando o FilePicker e dispositivos e contextos de dispositivo.

  1. Declare uma variável ID2D1Effect e crie um efeito de origem bitmap usando o método ID2DDeviceContext::CreateEffect .

        ComPtr<ID2D1Effect> bitmapSourceEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect));
    
  2. Defina a propriedade BitmapSource como a origem do bitmap wic usando a ID2D1Effect::SetValue.

            DX::ThrowIfFailed(m_bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_wicBitmapSource.Get()));
    
  3. Declare uma variável ID2D1Effect e crie o efeito de desfoque gaussian .

        ComPtr<ID2D1Effect> gaussianBlurEffect;
    
        DX::ThrowIfFailed(m_d2dContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlurEffect));
    
  4. Defina a entrada para receber a imagem do efeito de origem do bitmap. Defina a quantidade de desfoque o método SetValue e a propriedade de desvio padrão.

        gaussianBlurEffect->SetInputEffect(0, bitmapSourceEffect.Get());
    
        DX::ThrowIfFailed(gaussianBlurEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 6.0f));
    
  5. Use o contexto do dispositivo para desenhar a saída de imagem resultante.

        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();
    

    O método DrawImage deve ser chamado entre as chamadas ID2DDeviceContext::BeginDraw e EndDraw, como outras operações de renderização Direct2D. DrawImage pode tirar uma imagem ou a saída de um efeito e renderizá-la para a superfície de destino.

Transformações Espaciais

Direct2D fornece efeitos internos que podem transformar imagens em espaço 2D e 3D, bem como dimensionamento. Os efeitos de escala e transformação oferecem vários níveis de qualidade, como: vizinho mais próximo, linear, cúbico, linear de várias amostras, anisotrópico e cúbico de alta qualidade.

Observação

No entanto, o modo anisotrópico gera mipmaps ao dimensionar se você definir a propriedade Cached como true nos efeitos que são inseridos na transformação em que os mipmaps não serão gerados sempre para imagens suficientemente pequenas.

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();

Esse uso do efeito de transformação de afins 2D gira ligeiramente o bitmap no sentido anti-horário.

Antes
Efeito 2d affine antes da imagem.
After (após)
Efeito 2d affine após a imagem.

Composição de imagens

Alguns efeitos aceitam várias entradas e as compõem em uma imagem resultante.

Os efeitos compostos internos e aritméticos de composição fornecem vários modos, para obter mais informações, consulte o tópico composto . O efeito blend tem uma variedade de modos acelerados de GPU disponíveis.

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();

O efeito composto combina imagens de várias maneiras diferentes de acordo com o modo especificado.

Ajustes de pixel

Há alguns efeitos Direct2D internos que permitem alterar os dados de pixel. Por exemplo, o efeito de matriz de cores pode ser usado para alterar a cor de uma imagem.

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();

Esse código usa a imagem e altera a cor, conforme mostrado nas imagens de exemplo aqui.

Antes
efeito de matriz de cores antes da imagem.
After (após)
efeito de matriz de cores após a imagem.

Consulte a seção efeitos internos de cor para obter mais informações.

Criando grafos de efeito

Você pode encadear efeitos juntos para transformar imagens. Por exemplo, o código aqui aplica uma sombra e uma transformação 2D e, em seguida, compõe os resultados juntos.

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();

Este é o conjunto de resultados.

saída de efeito de sombra.

Os efeitos levam objetos ID2D1Image como entrada. Você pode usar um ID2D1Bitmap porque a interface é derivada de ID2D1Image. Você também pode usar o ID2D1Effect::GetOutput para obter a saída de um objeto ID2D1Effect como ID2D1Image ou usar o método SetInputEffect , que converte a saída para você. Na maioria dos casos, um grafo de efeito consiste em objetos ID2D1Effect diretamente encadeados, o que facilita a aplicação de vários efeitos a uma imagem para criar visuais atraentes.

Consulte Como aplicar efeitos a primitivos para obter mais informações.

Direct2D exemplo de efeitos de imagem básicos

Efeitos internos