Use o DirectX com cores avançadas em exibições de intervalo dinâmico alto/padrão

Este tópico mostra como usar o DirectX com cenários de Cores Avançadas, incluindo HDR (alto alcance dinâmico), WCG (gama de cores largas) com gerenciamento automático de cores do sistema e alta profundidade de bits. As telas de computador pessoal Premium (PC) com pelo menos um dos aprimoramentos acima estão se tornando generalizadas, fornecendo fidelidade de cores significativamente maior do que as telas tradicionais de SDR (intervalo dinâmico padrão).

Neste tópico, você obterá uma visão geral dos principais conceitos técnicos por trás do suporte ao Windows Advanced Color. Você aprenderá os requisitos e instruções para renderizar o conteúdo HDR, WCG e DirectX de alta profundidade de bits em uma dessas exibições. Se você tiver um aplicativo gerenciado por cores (por exemplo, usando perfis ICC), aprenderá como o gerenciamento automático de cores permite uma melhor precisão de cores para seus cenários.

Introdução à Cor Avançada no Windows

Cor Avançada é um termo guarda-chuva de tecnologias de sistema operacional (SO) para telas com fidelidade de cores significativamente maior do que as telas padrão. Os recursos estendidos predominantes são descritos nas seções abaixo. Os recursos de Cor Avançada foram introduzidos pela primeira vez para telas HDR com Windows 10, versão 1709 (Fall Creators Update) e para telas SDR especialmente provisionadas com o Windows 11, versão 22H2 (10.0; Build 22621) versão.

Alto intervalo dinâmico

Intervalo dinâmico refere-se à diferença entre a luminância máxima e mínima em uma cena; isso geralmente é medido em nits (candelas por centímetro quadrado). Cenas do mundo real, como este pôr do sol, geralmente têm intervalos dinâmicos de 10 ordens de magnitude de luminância; o olho humano pode discernir uma gama ainda maior após a adaptação.

imagem de um pôr do sol com brilho e pontos mais escuros na cena rotulada

Desde o Direct3D 9, os mecanismos gráficos têm sido capazes de renderizar internamente suas cenas com esse nível de fidelidade fisicamente precisa. No entanto, uma exibição típica de intervalo dinâmico padrão pode reproduzir apenas pouco mais de 3 pedidos de magnitude de luminância e, portanto, qualquer conteúdo renderizado em HDR teve que ser tonemapped (compactado) no intervalo limitado da tela. Novas telas HDR, incluindo aquelas que estão em conformidade com o padrão HDR10 (BT.2100), rompem essa limitação; Por exemplo, exibições auto emissivas de alta qualidade podem alcançar mais de 6 pedidos de magnitude.

Gama de cores largas

Gama de cores refere-se ao intervalo e saturação de matizes que uma tela pode reproduzir. As cores naturais mais saturadas que o olho humano pode perceber consistem em luz pura e monocromática, como a produzida por lasers. No entanto, as exibições de consumidores tradicionais geralmente podem reproduzir cores apenas dentro da gama sRGB, que representa apenas cerca de 35% de todas as cores perceptíveis por humanos. O diagrama a seguir é uma representação do "gafanhoto espectral" humano ou de todas as cores perceptíveis (em um determinado nível de luminância), em que o triângulo menor é a gama sRGB.

diagrama do gafanhoto espectral humano e da gama sRGB

Telas de computador profissionais high-end têm gama de cores com suporte há muito tempo que são significativamente mais largas do que sRGB, como Adobe RGB e DCI-P3 que cobrem cerca de metade das cores perceptíveis por humanos. E essas amplas exibições gama estão se tornando mais comuns.

Gerenciamento automático de cores do sistema

O gerenciamento de cores é a tecnologia e a prática de garantir a reprodução de cores precisa e consistente entre dispositivos. Se você for um criador de conteúdo digital, é crucial que as cores em seu conteúdo visual, como uma foto, uma imagem de produto ou um logotipo, apareçam da mesma forma em sua exibição, como na ampla variedade de dispositivos digitais do seu público.

O Windows forneceu APIs de suporte ao gerenciamento de cores desde o Windows 2000 com as APIs de Gerenciamento de Cores de Imagem (ICM) e posteriores do WCS (Sistema de Cores do Windows ). No entanto, essas APIs eram apenas auxiliares para aplicativos que desejavam/exigiam o gerenciamento de cores; enquanto a maioria dos aplicativos e conteúdo digital simplesmente assumia o espaço de cores sRGB padrão do setor e nunca eram gerenciados por cores pelo sistema operacional. Essa foi uma suposição razoável no passado, mas exibições de gama de alta qualidade estão se tornando muito mais comuns.

Novas versões do Windows dão suporte ao gerenciamento automático de cores do sistema; que garante que todas as cores em cada aplicativo do Windows, independentemente de estarem ou não cientes de cores, apareçam de forma precisa e consistente em cada tela com suporte.

Observação

O gerenciamento automático de cores não é uma propriedade do hardware de exibição; Em vez disso, é um recurso do Windows para dar suporte adequado a telas que têm gama de cores maiores do que sRGB.

Precisão profunda/profundidade de bits

Precisão numérica ou profundidade de bits refere-se à quantidade de informações usadas para identificar cores exclusivamente. Profundidade de bits mais alta significa que você pode distinguir entre cores muito semelhantes sem artefatos como faixas. Os monitores de computador base dão suporte a 8 bits por canal de cor, enquanto o olho humano requer pelo menos 10 a 12 bits de precisão para evitar distorções perceptíveis.

imagem de moinhos de vento em um canal simulado de 2 bits por cor versus 8 bits por canal

Antes da Cor Avançada, o DWM (Gerenciador de Janelas da Área de Trabalho) restringia os aplicativos em janelas para gerar conteúdo a apenas 8 bits por canal de cor, mesmo que a exibição tivesse suporte para uma profundidade de bits mais alta. Quando a Cor Avançada está habilitada, o DWM executa sua composição usando o FP16 (ponto flutuante de meia precisão) IEEE, eliminando quaisquer gargalos e permitindo que a precisão total da exibição seja usada.

Arquitetura do sistema de Cores Avançadas do Windows

As informações nesta seção são opcionais para a criação de aplicativos de Cores Avançadas; mas é útil entender como a tecnologia funciona para otimizar a renderização e o comportamento do aplicativo.

Nesta seção, usaremos um diagrama simplificado para descrever os componentes relevantes da pilha de gráficos do Windows:

diagrama de bloco da pilha de gráficos do Windows: aplicativo para DWM para exibir kernel

Windows existente: telas de 8 bits/sRGB

Durante décadas, as telas do consumidor e a pilha de gráficos do Windows foram baseadas em cerca de 8 bits por canal (24 bits por pixel) de conteúdo sRGB. Aplicativos que usam APIs gráficas, como o DirectX, podem executar renderização interna usando profundidades de bits altas e espaços de cores estendidos; no entanto, o sistema operacional suportava apenas um inteiro de 8 bits com sRGB implícito e nenhum gerenciamento de cores do sistema:

diagrama de bloco da pilha de exibição SDR: limitado a sRGB, 8 bits, sem gerenciamento de cores

Isso significava que todos os dados de cor adicionais renderizados por um aplicativo seriam perdidos ao serem exibidos; e que o aplicativo teve que executar o próprio gerenciamento de cores para garantir a reprodução precisa em uma tela.

Windows 10, versão 1703: HDR é exibido com Cor Avançada

O Windows 10, versão 1703, introduziu a primeira versão dos recursos de Cor Avançada para telas HDR. Isso exigiu vários avanços significativos na pilha de gráficos do sistema operacional:

  • Suporte à sinalização de vídeo HDR
  • Composição do sistema usando um espaço de cores canônico de alta profundidade de bits
  • Gerenciamento automático de cores do sistema

diagrama de bloco da pilha de exibição HDR: FP16, scRGB, com gerenciamento automático de cores

Cada avanço é abordado nas subseções abaixo. O resultado líquido é que os dados de cor do aplicativo estendido agora são preservados corretamente pelo sistema operacional e reproduzidos com precisão em telas HDR.

Suporte à sinalização de vídeo HDR

A sinalização HDR sobre conectores de vídeo, como DisplayPort e HDMI, usa principalmente 10 bits por precisão de canal (ou superior) e o espaço de cor BT.2100 ST.2084. O kernel de exibição, o driver de exibição e o hardware de GPU subjacente precisam dar suporte à detecção, seleção e condução desse modo de sinalização.

Composição do sistema usando um espaço de cores canônico de alta profundidade de bits

O espaço de cores BT.2100 ST.2084 é um padrão eficiente para codificar cores HDR, mas não é adequado para muitas operações de renderização e composição (mesclagem). Também queremos uma prova futura do sistema operacional para dar suporte a tecnologias e espaços de cores muito além do BT.2100, que cobre menos de 2/3 de cores visíveis para humanos. Por fim, sempre que possível, queremos minimizar o consumo de recursos de GPU para melhorar a potência e o desempenho.

Quando estiver no modo HDR, o DWM (Gerenciador de Janelas da Área de Trabalho) usará um CCCS (espaço de cor de composição canônica) definido como:

  • Espaço de cor scRGB (primárias BT.709/sRGB com gama linear)
  • Meia precisão IEEE (profundidade de FP16 bits)

Isso fornece um bom equilíbrio entre todas as metas acima. O CCCS permite valores de cor fora do intervalo numérico [0, 1]; considerando o intervalo de valores fp16 válidos, ele pode representar ordens de magnitude mais cores do que o intervalo visual humano natural, incluindo valores de luminância acima de 5 milhões de nits. FP16 tem excelente precisão para operações de combinação gama linear, mas custa metade do consumo de memória de GPU e largura de banda da precisão única tradicional (FP32) sem perda de qualidade perceptível.

Gerenciamento automático de cores do sistema

O Windows é um ambiente multitarefa em que o usuário pode executar qualquer número de aplicativos SDR e HDR ao mesmo tempo com janelas sobrepostas. Portanto, é crucial que todos os tipos de conteúdo pareçam corretos e com a qualidade máxima quando a saída para uma exibição; por exemplo, um aplicativo de produtividade sRGB (SDR) com uma janela de vídeo BT.2100 ST.2084 (HDR) reproduzindo sobre ele.

Quando estiver no modo HDR, o Windows executará operações de gerenciamento de cores em dois estágios:

  1. O DWM converte cada aplicativo de seu espaço de cor nativo em CCCS antes da mesclagem.
  2. O kernel de exibição converte o framebuffer do sistema operacional de CCCS para o espaço de cor de formato de fio (BT.2100 ST.2084).

diagrama de bloco do gerenciamento automático de cores que ocorre no DWM e exibe o diagrama de bloco de kernel do gerenciamento automático de cores que ocorre no DWM e exibe o kernel, parte 2

Observação

Em ambos os estágios, a operação de gerenciamento de cores consiste em uma conversão de espaço de cor (matriz e 1DLUT). As cores que excedem a gama de cores de destino da exibição são numericamente recortadas.

Windows 11, versão 22H2: SDR é exibido com Cor Avançada

Embora a prevalência de telas HDR esteja crescendo rapidamente, as telas SDR permanecerão importantes para os anos seguintes. O suporte a HDR no Windows 10, versão 1703, estabeleceu a maior parte das bases necessárias para aprimorar as telas SDR também. Windows 11, a versão 22H2 estende as funcionalidades avançadas de gerenciamento de cores e cores automáticas para determinadas exibições de SDR qualificadas. O diagrama de bloco gráfico para exibições de SDR de Cor Avançada é muito semelhante ao HDR:

diagrama de bloco da pilha de exibição ac de SDR: FP16, scRGB, com gerenciamento automático de cores

Suporte à sinalização de exibição SDR com alta profundidade de bits

A sinalização subjacente para exibições de SDR não é alterada, embora o Windows 11, a versão 22H2 dá suporte a 10 bits por canal e superior, dependendo dos recursos da exibição.

Composição do sistema usando um espaço de cores canônico de alta profundidade de bits

A funcionalidade de Cor Avançada do DWM, incluindo a mesclagem no CCCS, é quase inteiramente inalterada em relação às telas HDR. A diferença main é que o DWM usa luminância referenciada por vídeo com telas SDR e luminância referenciada por cena com telas HDR. Isso altera a maneira como o conteúdo renderizado da Cor Avançada é interpretado pelo sistema operacional:

Tipo de exibição Comportamento de luminância Como 1.0f é interpretado
SDR Referenciado por exibição Como o nível branco de referência da exibição
HDR Referenciado por cena Como 80 nits (branco de referência nominal)

Gerenciamento automático de cores do sistema

Os recursos de gerenciamento de cores do sistema operacional também são praticamente inalterados em relação às telas HDR. A diferença main é que o kernel de exibição é convertido no espaço de cores referenciado pela exibição, conforme definido pelos dados de colorimetria e calibragem da tela, em vez do espaço de cores PADRÃO BT.2100 ST.2084 para telas HDR.

Exibir o provisionamento necessário

Dados precisos de um perfil DO MHC ICC são necessários para definir a operação de gerenciamento de cores de saída do kernel de exibição. Portanto, somente os monitores SDR que foram provisionados especificamente pelo fabricante ou um provedor de calibragem de exibição com um perfil válido são qualificados para o gerenciamento automático de cores. Confira Comportamento do perfil ICC com Cor Avançada para obter mais informações.

Requisitos do sistema e suporte ao sistema operacional

O Windows 10, versão 1709, enviou pela primeira vez suporte a Cores Avançadas para telas HDR. A versão Windows 11 versão 22H2 adiciona suporte a Cores Avançadas para exibições SDR que têm dados de provisionamento precisos.

Este tópico pressupõe que seu aplicativo esteja direcionando o Windows 10, versão 2004 (ou posterior) para telas HDR e o Windows 11 versão 22H2 (ou posterior) para exibições SDR.

Monitor

Uma tela de alto intervalo dinâmico deve implementar o padrão HDR10 ou BT.2100 ST.2084. A qualidade da tela HDR pode variar muito, e é altamente recomendável exibir telas certificadas, como VeSA DisplayHDR. A partir do Windows 11, versão 22H2, o Windows exibe a status de certificação de exibições conhecidas no aplicativo Configurações.

Uma exibição de intervalo dinâmico padrão deve ter dados de provisionamento de cores precisos para suporte a Cores Avançadas. No Windows 11, versão 22H2, o único método com suporte para substituir esses dados é por meio de um perfil MHC ICC; além disso, o usuário ou fabricante de vídeo deve ter habilitado o gerenciamento automático de cores. Para obter mais informações, consulte Comportamento do perfil ICC com Cor Avançada.

Processador gráfico (GPU)

Para a funcionalidade completa de Cores Avançadas em telas SDR e HDR, uma GPU recente é necessária:

  • AMD Radeon RX série 400 (Polaris) ou mais recente
  • Série NVIDIA GeForce 10 (Pascal) ou mais recente
  • Intel Core 10ª geração (Ice Lake) selecionado ou mais recente*

Observação

Os chipsets Comet Lake (código de modelo de cinco dígitos) do nome de código Intel não fornecem funcionalidade completa.

Requisitos de hardware adicionais podem ser aplicados, dependendo dos cenários, incluindo aceleração de codec de hardware (HEVC de 10 bits, VP9 de 10 bits etc.) e suporte ao PlayReady (SL3000). Entre em contato com seu fornecedor de GPU para obter informações mais específicas.

Driver gráfico (WDDM)

O driver gráfico mais recente disponível é altamente recomendado, seja de Windows Update ou do site do fornecedor de GPU ou do fabricante do computador. Este tópico se baseia na funcionalidade de driver do WDDM 2.7 (Windows 10, versão 2004) para telas HDR e WDDM 3.0 (Windows 11, versão 21H2) para telas SDR.

APIs de renderização com suporte

O Windows 10 dá suporte a uma ampla variedade de APIs e estruturas de renderização. O suporte avançado a cores depende fundamentalmente de seu aplicativo ser capaz de executar apresentações modernas usando DXGI ou as APIs de Camada Visual.

Portanto, qualquer API de renderização que possa ser gerada para um desses métodos de apresentação pode dar suporte à Cor Avançada. Isso inclui (mas não se limita a) o abaixo.

  • Direct3D 11
  • Direct3D 12
  • Direct2D
  • Win2D
    • Requer o uso das APIs CanvasSwapChain ou CanvasSwapChainPanel de nível inferior.
  • Windows.UI.Input.Inking
    • Dá suporte à renderização de tinta seca personalizada usando DirectX.
  • XAML
    • Dá suporte à reprodução de vídeos HDR usando MediaPlayerElement.
    • Dá suporte à decodificação de imagens JPEG XR usando o elemento Image .
    • Dá suporte à interoperabilidade do DirectX usando SwapChainPanel.

Manipulando funcionalidades de exibição dinâmica

O Windows 10 dá suporte a uma enorme variedade de telas compatíveis com Cores Avançadas, desde painéis integrados eficientes por energia até monitores de jogos e TVs de alto nível. Os usuários do Windows esperam que seu aplicativo lide perfeitamente com todas essas variações, incluindo exibições onipresentes de SDR existentes.

O Windows 10 fornece controle sobre os recursos HDR e Cor Avançada para o usuário. Seu aplicativo deve detectar a configuração da exibição atual e responder dinamicamente a quaisquer alterações na funcionalidade. Isso pode ocorrer por vários motivos, por exemplo, porque o usuário habilitou ou desabilitou um recurso, ou moveu o aplicativo entre telas diferentes ou o estado de energia do sistema foi alterado.

Opção 1: AdvancedColorInfo

Observação

A API Windows Runtime AdvancedColorInfo é utilizável independentemente da API de renderização, dá suporte à Cor Avançada para exibições de SDR e usa eventos para sinalizar quando os recursos mudam. No entanto, ele está disponível apenas para aplicativos Plataforma Universal do Windows (UWP) ; aplicativos da área de trabalho (que não têm um CoreWindow) não podem usá-lo. Para obter mais informações, consulte WINDOWS RUNTIME APIs sem suporte em aplicativos da área de trabalho.

Primeiro, obtenha uma instância de AdvancedColorInfo de DisplayInformation::GetAdvancedColorInfo.

Para marcar qual tipo de Cor Avançada está ativo no momento, use a propriedade AdvancedColorInfo::CurrentAdvancedColorKind. Essa é a propriedade mais importante para marcar e você deve configurar o pipeline de renderização e apresentação em resposta ao tipo ativo:

Tipo de cor avançado Recursos de exibição
SDR Exibição de SDR sem recursos de Cor Avançada
WCG Exibição de SDR com alto gerenciamento de cores e profundidade de bits
HDR Tela HDR com todos os recursos de Cor Avançada

Para marcar quais tipos de Cores Avançadas têm suporte, mas não necessariamente ativos, chame AdvancedColorInfo::IsAdvancedColorKindAvailable. Você pode usar essas informações, por exemplo, para solicitar que o usuário navegue até o aplicativo Configurações do Windows para que ele possa habilitar o gerenciamento automático de cores ou HDR.

Os outros membros do AdvancedColorInfo fornecem informações quantitativas sobre o volume de cores físicas do painel (luminância e chrominance), correspondente a metadados HDR estáticos SMPTE ST.2086. Embora ST.2086 tenha sido originalmente projetado para telas HDR, essas informações são úteis e estão disponíveis para telas HDR e SDR. Você deve usar essas informações para configurar o mapeamento de tom e o mapeamento de gama do aplicativo.

Para lidar com alterações nos recursos de Cor Avançada, registre-se no evento DisplayInformation::AdvancedColorInfoChanged . Esse evento será gerado se qualquer parâmetro dos recursos de Cor Avançada da exibição for alterado por qualquer motivo.

Manipule esse evento obtendo uma nova instância de AdvancedColorInfo e verificando quais valores foram alterados.

IDXGIOutput6

Observação

A interface IDXGIOutput6 da Infraestrutura de Elementos Gráficos do DirectX está disponível para qualquer aplicativo que usa DirectX, seja desktop ou UWP (Plataforma Universal do Windows). No entanto, IDXGIOutput6não dá suporte a telas SDR com recursos de Cor Avançada, como gerenciamento automático de cores; ele pode identificar apenas telas HDR.

Se você estiver escrevendo um aplicativo da área de trabalho Win32 e usando o DirectX para renderizar, use DXGI_OUTPUT_DESC1 para obter recursos de exibição. Obtenha uma instância desse struct por meio de IDXGIOutput6::GetDesc1.

Para marcar qual tipo de Cor Avançada está ativo no momento, use a propriedade ColorSpace, que é do tipo DXGI_COLOR_SPACE_TYPE e contém um dos seguintes valores:

DXGI_COLOR_SPACE_TYPE Recursos de exibição
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 Exibição de SDR sem recursos de Cor Avançada
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 Tela HDR com todos os recursos de Cor Avançada

Observação

As exibições de SDR com recursos de Cor Avançada também são relatadas como DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; O DXGI não permite distinguir entre os dois tipos.

Observação

O DXGI não permite que você marcar quais tipos de Cores Avançadas são compatíveis, mas não ativos no momento.

A maioria dos outros membros do DXGI_OUTPUT_DESC1 fornece informações quantitativas sobre o volume de cores físicas do painel (luminância e chrominance), correspondente a metadados HDR estáticos SMPTE ST.2086. Embora o ST.2086 tenha sido originalmente projetado para telas HDR, essas informações são úteis e estão disponíveis para telas HDR e SDR. Você deve usar essas informações para configurar o mapeamento de tom e o mapeamento de gama do aplicativo.

Os aplicativos da área de trabalho do Win32 não têm um mecanismo nativo para responder às alterações de funcionalidade de Cor Avançada. Em vez disso, se o aplicativo usar um loop de renderização, você deverá consultar IDXGIFactory1::IsCurrent com cada quadro. Se ele relatar FALSE, você deverá obter uma nova DXGI_OUTPUT_DESC1 e marcar quais valores foram alterados.

Além disso, sua bomba de mensagem Win32 deve lidar com a mensagem WM_SIZE , o que indica que seu aplicativo pode ter se movido entre diferentes exibições.

Observação

Para obter um novo DXGI_OUTPUT_DESC1, você deve obter a exibição atual. No entanto, você não deve chamar IDXGISwapChain::GetContainingOutput. Isso ocorre porque as cadeias de troca retornam uma saída DXGI obsoleta depois que DXGIFactory::IsCurrent é false; e recriar a cadeia de troca para obter uma saída atual resulta em uma tela temporariamente preta. Em vez disso, recomendamos que você enumere pelos limites de todas as saídas DXGI e determine qual delas tem a maior interseção com os limites da janela do aplicativo.

O código de exemplo a seguir vem do aplicativo de exemplo HDR Direct3D 12 no GitHub.

// Retrieve the current default adapter.
ComPtr<IDXGIAdapter1> dxgiAdapter;
ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, &dxgiAdapter));

// Iterate through the DXGI outputs associated with the DXGI adapter,
// and find the output whose bounds have the greatest overlap with the
// app window (i.e. the output for which the intersection area is the
// greatest).

UINT i = 0;
ComPtr<IDXGIOutput> currentOutput;
ComPtr<IDXGIOutput> bestOutput;
float bestIntersectArea = -1;

while (dxgiAdapter->EnumOutputs(i, &currentOutput) != DXGI_ERROR_NOT_FOUND)
{
    // Get the retangle bounds of the app window
    int ax1 = m_windowBounds.left;
    int ay1 = m_windowBounds.top;
    int ax2 = m_windowBounds.right;
    int ay2 = m_windowBounds.bottom;

    // Get the rectangle bounds of current output
    DXGI_OUTPUT_DESC desc;
    ThrowIfFailed(currentOutput->GetDesc(&desc));
    RECT r = desc.DesktopCoordinates;
    int bx1 = r.left;
    int by1 = r.top;
    int bx2 = r.right;
    int by2 = r.bottom;

    // Compute the intersection
    int intersectArea = ComputeIntersectionArea(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);
    if (intersectArea > bestIntersectArea)
    {
        bestOutput = currentOutput;
        bestIntersectArea = static_cast<float>(intersectArea);
    }

    i++;
}

// Having determined the output (display) upon which the app is primarily being 
// rendered, retrieve the HDR capabilities of that display by checking the color space.
ComPtr<IDXGIOutput6> output6;
ThrowIfFailed(bestOutput.As(&output6));

DXGI_OUTPUT_DESC1 desc1;
ThrowIfFailed(output6->GetDesc1(&desc1));

Configurando sua cadeia de troca do DirectX

Depois de determinar que a tela atualmente dá suporte a recursos de Cor Avançada, configure sua cadeia de troca da seguinte maneira.

Usar um efeito de modelo de apresentação de inversão

Ao criar sua cadeia de troca usando um dos CreateSwapChainFor[Hwnd|Composição|Métodos CoreWindow] , você deve usar o modelo de inversão DXGI selecionando a opção DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ou DXGI_SWAP_EFFECT_FLIP_DISCARD , o que torna sua cadeia de troca qualificada para processamento de Cores Avançadas do DWM e várias otimizações de tela inteira. Para obter mais informações, consulte Para obter o melhor desempenho, use o modelo de inversão DXGI.

Opção 1. Usar o formato de pixel FP16 e o espaço de cor scRGB

O Windows 10 dá suporte a duas combinações main de formato de pixel e espaço de cores para Cor Avançada. Selecione um com base nos requisitos específicos do aplicativo.

Recomendamos que os aplicativos de uso geral usem a Opção 1. É a única opção que funciona para todos os tipos de APIs de exibição, conteúdo e renderização de Cores Avançadas. Ao criar sua cadeia de troca, especifique DXGI_FORMAT_R16G16B16A16_FLOAT em seu DXGI_SWAP_CHAIN_DESC1. Por padrão, uma cadeia de troca criada com um formato de pixel de ponto flutuante é tratada como se usásse o espaço de cor DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 . Esse é o mesmo formato de pixel e espaço de cor usado pelo DWM.

Essa combinação fornece o intervalo numérico e a precisão para especificar qualquer cor fisicamente possível e executar processamento arbitrário, incluindo mesclagem.

No entanto, essa opção consome 64 bits por pixel, o que dobra a largura de banda de GPU e o consumo de memória em comparação com os formatos de pixel UINT8 tradicionais. Além disso, scRGB usa valores numéricos que estão fora do intervalo normalizado [0, 1] para representar cores que estão fora da gama sRGB e/ou maiores que 80 nits de luminância. Por exemplo, scRGB (1.0, 1.0, 1.0) codifica o D65 branco padrão em 80 nits; mas scRGB (12.5, 12.5, 12.5) codifica o mesmo D65 branco em um nits 1000 muito mais brilhante. Algumas operações gráficas exigem um intervalo numérico normalizado e você deve modificar a operação ou normalizar novamente os valores de cor.

A maneira como os valores de luminância são interpretados com essa opção difere entre as telas SDR e HDR; veja abaixo.

Opção 2: usar o formato de pixel UINT10/RGB10 e o espaço de cor HDR10/BT.2100

A opção 2 é uma otimização de desempenho disponível somente se o aplicativo atender a todas as seguintes condições:

  • Direciona uma tela HDR
  • Usa Direct3D 12 ou Direct3D 11
  • A cadeia de troca não requer mesclagem com alfa/transparência

Se o aplicativo não atender a todas essas condições, você deverá usar a Opção 1.

Mas se o aplicativo se qualificar para a opção 2, isso poderá fornecer melhor desempenho se o aplicativo estiver consumindo conteúdo codificado em HDR10, como um player de vídeo, ou se ele for usado principalmente em cenários de tela inteira, como um jogo. Ao criar sua cadeia de troca, considere especificar DXGI_FORMAT_R10G10B10A2_UNORM em DXGI_SWAP_CHAIN_DESC1. Por padrão, isso é tratado como usando o espaço de cor sRGB; Portanto, você deve chamar explicitamente IDXGISwapChain3::SetColorSpace1 e definir como seu espaço de cor DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, também conhecido como HDR10/BT.2100.

Essa opção consome os mesmos 32 bits por pixel que os formatos de pixel UINT8 SDR tradicionais. Além disso, em determinadas GPUs, isso elimina alguns processamentos necessários para converter o conteúdo no formato de transmissão HDR10.

Usando uma cadeia de troca de cores avançada quando a exibição está no modo SDR

Você pode usar uma cadeia de troca de Cores Avançadas mesmo que a tela não dê suporte a todos os recursos de Cor Avançada. Nesses casos, o DWM (Gerenciador de Janelas da Área de Trabalho) reduzirá o conteúdo para se ajustar aos recursos da exibição executando recorte numérico. Por exemplo, se você renderizar em uma cadeia de troca scRGB FP16 e direcionar uma exibição padrão, tudo fora do intervalo numérico [0, 1] será recortado.

Esse comportamento de downconversion também ocorrerá se a janela do aplicativo estiver abrangendo duas ou mais exibições com diferentes funcionalidades de Cor Avançada. AdvancedColorInfo e IDXGIOutput6 são abstraídos para relatar apenas as características da exibição main (main sendo definidas como a exibição que contém o centro da janela).

Corresponder o branco de referência do aplicativo ao nível branco de referência do SDR do sistema operacional

Observação

O branco de referência aplica-se somente a telas HDR; para exibições de Cor Avançada de SDR (1.0, 1.0, 1.0) sempre significa a luminância branca máxima que a tela pode reproduzir.

Em muitos cenários, seu aplicativo desejará renderizar o conteúdo SDR e HDR; por exemplo, renderizar subtítulos ou controles de transporte por vídeo HDR ou interface do usuário em uma cena de jogo. É importante entender o conceito de nível branco de referência de SDR para garantir que o conteúdo de SDR esteja correto em uma tela HDR. O branco de referência indica o brilho no qual um objeto branco difuso (como uma folha de papel ou, às vezes, interface do usuário) aparece em uma cena HDR. Como os valores de cor HDR têm brilho referenciado pela cena, um valor de cor específico deve ser exibido em um nível de luminância absoluta e não em relação ao valor máximo possível do painel. Por exemplo, scRGB (1.0, 1.0, 1.0) e HDR10 (497, 497, 497) codificam exatamente D65 branco na luminância de 80 nits. O Windows permite que o usuário ajuste o nível branco de referência de SDR de acordo com suas preferências; essa é a luminância em que o Windows renderizará sRGB (1.0, 1.0, 1.0) em. Em monitores HDR da área de trabalho, os níveis de branco de referência de SDR normalmente são definidos como cerca de 200 nits.

Seu aplicativo HDR deve permitir que o usuário defina o nível branco de referência desejado ou leia o valor configurado pelo sistema. Você deve mapear seus valores de cor branca difusa em sua cena para o nível branco de referência SDR. Isso implica a multiplicação do cofre de quadros do aplicativo no espaço gama linear.

Observação

Em uma tela que dá suporte a um controle de brilho, como em um laptop, o Windows também ajusta a luminância do conteúdo HDR (referenciado pela cena) para corresponder ao nível de brilho desejado do usuário, mas isso é invisível para o aplicativo. A menos que você esteja tentando garantir a reprodução precisa do sinal HDR, você geralmente pode ignorar isso.

Se seu aplicativo sempre renderizar SDR e HDR para separar superfícies e depender da composição do sistema operacional, o Windows executará automaticamente o ajuste correto para aumentar o conteúdo de SDR para o nível branco desejado. Por exemplo, se seu aplicativo usa XAML e renderiza o conteúdo HDR para seu próprio SwapChainPanel.

No entanto, se seu aplicativo executar sua própria composição de conteúdo SDR e HDR em uma única superfície, você será responsável por executar o ajuste de nível branco de referência SDR por conta própria. Caso contrário, o conteúdo de SDR pode parecer muito fraco em condições típicas de exibição da área de trabalho. Primeiro, você deve obter o nível branco de referência SDR atual e, em seguida, deve ajustar os valores de cor de qualquer conteúdo SDR que você está renderizando.

Etapa 1. Obter o nível de branco de referência de SDR atual

Você pode obter o nível de branco de referência de SDR atual de uma destas maneiras:

Etapa 2. Ajustar valores de cor do conteúdo de SDR

O Windows define o nível de branco de referência nominal ou padrão em 80 nits. Portanto, se você renderizasse um sRGB padrão (1.0, 1.0, 1.0) branco em uma cadeia de troca FP16, ele seria reproduzido com luminância de 80 nits. Para corresponder ao nível de branco de referência definido pelo usuário real, você deve ajustar o conteúdo SDR de 80 nits para o nível especificado por meio de AdvancedColorInfo.SdrWhiteLevelInNits.

Se você estiver renderizando usando FP16 e scRGB ou qualquer espaço de cor que use gama linear (1,0), poderá simplesmente multiplicar o valor de cor SDR por AdvancedColorInfo.SdrWhiteLevelInNits / 80. Se você estiver usando Direct2D, haverá uma constante predefinida D2D1_SCENE_REFERRED_SDR_WHITE_LEVEL, que tem um valor de 80.

D2D1_VECTOR_4F inputColor; // Input SDR color value.
D2D1_VECTOR_4F outputColor; // Output color adjusted for SDR white level.
auto acInfo = ...; // Obtain an AdvancedColorInfo.

float sdrAdjust = acInfo->SdrWhiteLevelInNits / D2D1_SCENE_REFERRED_SDR_WHITE_LEVEL;

// Normally in DirectX, color values are manipulated in shaders on GPU textures.
// This example performs scaling on a CPU color value.
outputColor.r = inputColor.r * sdrAdjust; // Assumes linear gamma color values.
outputColor.g = inputColor.g * sdrAdjust;
outputColor.b = inputColor.b * sdrAdjust;
outputColor.a = inputColor.a;

Se você estiver renderizando usando um espaço de cor gama não linear, como HDR10, a execução do ajuste de nível branco de SDR será mais complexa. Se você estiver escrevendo seu próprio sombreador de pixel, considere converter em gama linear para aplicar o ajuste.

Adaptar o conteúdo HDR às funcionalidades da tela usando o mapeamento de tom

As telas HDR e Cor Avançada variam muito em termos de seus recursos. Por exemplo, na luminância mínima e máxima e na gama de cores que eles são capazes de reproduzir. Em muitos casos, o conteúdo do HDR conterá cores que excedem os recursos da tela. Para obter a melhor qualidade de imagem, é importante que você execute o mapeamento de tom HDR, essencialmente compactando o intervalo de cores para se ajustar à tela, preservando melhor a intenção visual do conteúdo.

O parâmetro único mais importante para se adaptar é a luminância máxima, também conhecida como MaxCLL (nível de luz do conteúdo); Mapeadores de tom mais sofisticados também adaptarão minclL (luminância mínima) e/ou primárias de cores.

Etapa 1. Obter os recursos de volume de cores da exibição

Aplicativos da Plataforma Universal do Windows (UWP)

Use AdvancedColorInfo para obter o volume de cores da exibição.

Aplicativos Win32 (desktop) DirectX

Use DXGI_OUTPUT_DESC1 para obter o volume de cores da exibição.

Etapa 2. Obter informações de volume de cores do conteúdo

Dependendo de onde o conteúdo hdr veio, há várias maneiras potenciais de determinar suas informações de luminância e gama de cores. Determinados arquivos de vídeo e imagem HDR contêm metadados SMPTE ST.2086. Se o conteúdo tiver sido renderizado dinamicamente, você poderá extrair informações de cena dos estágios internos de renderização, por exemplo, a fonte de luz mais brilhante em uma cena.

Uma solução mais geral, mas computacionalmente cara, é executar um histograma ou outra análise passar o quadro renderizado. O aplicativo de exemplo de renderização de imagem de cor avançada direct2D no GitHub demonstra como fazer isso usando o Direct2D; os snippets de código mais relevantes estão incluídos abaixo:

// Perform histogram pipeline setup; this should occur as part of image resource creation.
// Histogram results in no visual output but is used to calculate HDR metadata for the image.
void D2DAdvancedColorImagesRenderer::CreateHistogramResources()
{
    auto context = m_deviceResources->GetD2DDeviceContext();

    // We need to preprocess the image data before running the histogram.
    // 1. Spatial downscale to reduce the amount of processing needed.
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1Scale, &m_histogramPrescale)
        );

    DX::ThrowIfFailed(
        m_histogramPrescale->SetValue(D2D1_SCALE_PROP_SCALE, D2D1::Vector2F(0.5f, 0.5f))
        );

    // The right place to compute HDR metadata is after color management to the
    // image's native colorspace but before any tonemapping or adjustments for the display.
    m_histogramPrescale->SetInputEffect(0, m_colorManagementEffect.Get());

    // 2. Convert scRGB data into luminance (nits).
    // 3. Normalize color values. Histogram operates on [0-1] numeric range,
    //    while FP16 can go up to 65504 (5+ million nits).
    // Both steps are performed in the same color matrix.
    ComPtr<ID2D1Effect> histogramMatrix;
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1ColorMatrix, &histogramMatrix)
        );

    histogramMatrix->SetInputEffect(0, m_histogramPrescale.Get());

    float scale = sc_histMaxNits / sc_nominalRefWhite;

    D2D1_MATRIX_5X4_F rgbtoYnorm = D2D1::Matrix5x4F(
        0.2126f / scale, 0, 0, 0,
        0.7152f / scale, 0, 0, 0,
        0.0722f / scale, 0, 0, 0,
        0              , 0, 0, 1,
        0              , 0, 0, 0);
    // 1st column: [R] output, contains normalized Y (CIEXYZ).
    // 2nd column: [G] output, unused.
    // 3rd column: [B] output, unused.
    // 4th column: [A] output, alpha passthrough.
    // We explicitly calculate Y; this deviates from the CEA 861.3 definition of MaxCLL
    // which approximates luminance with max(R, G, B).

    DX::ThrowIfFailed(histogramMatrix->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, rgbtoYnorm));

    // 4. Apply a gamma to allocate more histogram bins to lower luminance levels.
    ComPtr<ID2D1Effect> histogramGamma;
    DX::ThrowIfFailed(
        context->CreateEffect(CLSID_D2D1GammaTransfer, &histogramGamma)
        );

    histogramGamma->SetInputEffect(0, histogramMatrix.Get());

    // Gamma function offers an acceptable tradeoff between simplicity and efficient bin allocation.
    // A more sophisticated pipeline would use a more perceptually linear function than gamma.
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_RED_EXPONENT, sc_histGamma));
    // All other channels are passthrough.
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_GREEN_DISABLE, TRUE));
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_BLUE_DISABLE, TRUE));
    DX::ThrowIfFailed(histogramGamma->SetValue(D2D1_GAMMATRANSFER_PROP_ALPHA_DISABLE, TRUE));

    // 5. Finally, the histogram itself.
    HRESULT hr = context->CreateEffect(CLSID_D2D1Histogram, &m_histogramEffect);
    
    if (hr == D2DERR_INSUFFICIENT_DEVICE_CAPABILITIES)
    {
        // The GPU doesn't support compute shaders and we can't run histogram on it.
        m_isComputeSupported = false;
    }
    else
    {
        DX::ThrowIfFailed(hr);
        m_isComputeSupported = true;

        DX::ThrowIfFailed(m_histogramEffect->SetValue(D2D1_HISTOGRAM_PROP_NUM_BINS, sc_histNumBins));

        m_histogramEffect->SetInputEffect(0, histogramGamma.Get());
    }
}

// Uses a histogram to compute a modified version of MaxCLL (ST.2086 max content light level).
// Performs Begin/EndDraw on the D2D context.
void D2DAdvancedColorImagesRenderer::ComputeHdrMetadata()
{
    // Initialize with a sentinel value.
    m_maxCLL = -1.0f;

    // MaxCLL is not meaningful for SDR or WCG images.
    if ((!m_isComputeSupported) ||
        (m_imageInfo.imageKind != AdvancedColorKind::HighDynamicRange))
    {
        return;
    }

    // MaxCLL is nominally calculated for the single brightest pixel in a frame.
    // But we take a slightly more conservative definition that takes the 99.99th percentile
    // to account for extreme outliers in the image.
    float maxCLLPercent = 0.9999f;

    auto ctx = m_deviceResources->GetD2DDeviceContext();

    ctx->BeginDraw();

    ctx->DrawImage(m_histogramEffect.Get());

    // We ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
    // is lost. It will be handled during the next call to Present.
    HRESULT hr = ctx->EndDraw();
    if (hr != D2DERR_RECREATE_TARGET)
    {
        DX::ThrowIfFailed(hr);
    }

    float *histogramData = new float[sc_histNumBins];
    DX::ThrowIfFailed(
        m_histogramEffect->GetValue(D2D1_HISTOGRAM_PROP_HISTOGRAM_OUTPUT,
            reinterpret_cast<BYTE*>(histogramData),
            sc_histNumBins * sizeof(float)
            )
        );

    unsigned int maxCLLbin = 0;
    float runningSum = 0.0f; // Cumulative sum of values in histogram is 1.0.
    for (int i = sc_histNumBins - 1; i >= 0; i--)
    {
        runningSum += histogramData[i];
        maxCLLbin = i;

        if (runningSum >= 1.0f - maxCLLPercent)
        {
            break;
        }
    }

    float binNorm = static_cast<float>(maxCLLbin) / static_cast<float>(sc_histNumBins);
    m_maxCLL = powf(binNorm, 1 / sc_histGamma) * sc_histMaxNits;

    // Some drivers have a bug where histogram will always return 0. Treat this as unknown.
    m_maxCLL = (m_maxCLL == 0.0f) ? -1.0f : m_maxCLL;
}

Etapa 3. Executar a operação de tonemapping hdr

O tonemapping é inerentemente um processo de perda e pode ser otimizado para várias métricas perceptivas ou objetivas, portanto, não há um único algoritmo padrão. O Windows fornece um efeito de tonemapper hdr interno como parte do Direct2D, bem como no pipeline de reprodução de vídeo hdr do Media Foundation. Alguns outros algoritmos comumente usados incluem ACES Filmic, Reinhard e ITU-R BT.2390-3 EETF (função de transferência elétrica-elétrica).

Um operador de tonemapper Reinhard simplificado é mostrado neste próximo exemplo de código.

// This example uses C++. A typical DirectX implementation would port this to HLSL.
D2D1_VECTOR_4F simpleReinhardTonemapper(
    float inputMax, // Content's maximum luminance in scRGB values, e.g. 1.0 = 80 nits.
    float outputMax, // Display's maximum luminance in scRGB values, e.g. 1.0 = 80 nits.
    D2D1_VECTOR_4F input // scRGB color.
)
{
    D2D1_VECTOR_4F output = input;

    // Vanilla Reinhard normalizes color values to [0, 1].
    // This modification scales to the luminance range of the display.
    output.r /= inputMax;
    output.g /= inputMax;
    output.b /= inputMax;

    output.r = output.r / (1 + output.r);
    output.g = output.g / (1 + output.g);
    output.b = output.b / (1 + output.b);

    output.r *= outputMax;
    output.g *= outputMax;
    output.b *= outputMax;

    return output;
}

Captura de conteúdo de tela HDR e WCG

APIs que dão suporte à especificação de formatos de pixel, como os do namespace Windows.Graphics.Capture e do método IDXGIOutput5::D uplicateOutput1 , fornecem a capacidade de capturar conteúdo HDR e WCG sem perder informações de pixel. Observe que, depois de adquirir quadros de conteúdo, o processamento adicional é necessário. Por exemplo, mapeamento de tom HDR para SDR (por exemplo, cópia de captura de tela de SDR para compartilhamento da Internet) e salvamento de conteúdo com formato adequado (por exemplo, JPEG XR).

Alterações no gerenciamento de cores herdado e no comportamento do perfil ICC

O gerenciamento avançado de cores e cores automáticas garante uma cor de exibição consistente e colorimétricamente precisa para todos os aplicativos, herdados e modernos. No entanto, alguns aplicativos podem executar seu próprio gerenciamento explícito de cores usando perfis de cores do ICC (International Color Consortium).

Quando a Cor Avançada está ativa em exibições de SDR ou HDR, o comportamento de exibir perfis ICC muda de maneiras não compatíveis com versões anteriores. Se seu aplicativo funcionar com perfis ICC de exibição, o Windows oferecerá auxiliares de compatibilidade para garantir que seu aplicativo continue a obter o comportamento correto.

Mais informações sobre as alterações no comportamento do perfil DO ICC e como você pode adaptar seu aplicativo para maximizar a compatibilidade com a Cor Avançada, consulte o comportamento do perfil DO ICC com Cor Avançada.

Recursos adicionais