Partilhar via


Utilize o DirectX com cores avançadas em ecrãs com gama dinâmica alta/padrão

Este tópico mostra como usar o DirectX com cenários de cores avançadas, incluindo HDR (High Dynamic Range), WCG (ampla gama de cores) com gerenciamento automático de cores do sistema e alta profundidade de bits. Os monitores de computador pessoal (PC) premium com pelo menos uma das melhorias acima estão se tornando generalizados, fornecendo fidelidade de cor significativamente maior do que os monitores SDR (faixa dinâmica padrão) tradicionais.

Neste tópico, você terá uma visão geral dos principais conceitos técnicos por trás do suporte ao Windows Advanced Color. Você aprenderá os requisitos e as instruções para renderizar conteúdo HDR, WCG e DirectX de alta profundidade de bits em um desses monitores. 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 ao Advanced Color no Windows

Advanced Color é um termo abrangente de tecnologias de sistema operacional (SO) para monitores com fidelidade de cor significativamente maior do que monitores padrão. As capacidades expandidas predominantes são descritas nas secções abaixo. Os recursos avançados de cores foram introduzidos pela primeira vez para monitores HDR com o Windows 10, versão 1709 (Fall Creators Update), e para monitores SDR especialmente provisionados com o Windows 11, versão 22H2 (10.0; Build 22621) lançamento.

Gama dinâmica elevada

Faixa dinâmica refere-se à diferença entre a luminância máxima e mínima numa cena; isto é frequentemente medido em nits (candelas por metro quadrado). Cenas do mundo real, como este pôr do sol, geralmente têm faixas dinâmicas de 10 ordens de magnitude de luminância; O olho humano consegue discernir um alcance ainda maior após a adaptação.

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

Desde o Direct3D 9, os motores gráficos têm sido capazes de renderizar internamente as suas cenas com este nível de fidelidade fisicamente precisa. No entanto, um ecrã de gama dinâmica padrão típico pode reproduzir apenas um pouco mais de 3 ordens de magnitude de luminância e, portanto, qualquer conteúdo renderizado por HDR teve que ser tonemapeado (comprimido) para o alcance limitado do ecrã. Os novos ecrãs HDR, incluindo os que cumprem a norma HDR10 (BT.2100), ultrapassam esta limitação; Por exemplo, monitores auto-emissivos de alta qualidade podem atingir mais de 6 ordens de magnitude.

Ampla gama de cores

A gama de cores refere-se à gama e saturação de tonalidades que um ecrã 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, os principais monitores de consumo muitas vezes podem reproduzir cores apenas dentro da gama sRGB, que representa apenas cerca de 35% de todas as cores percetíveis pelo ser humano. O diagrama abaixo é uma representação do "locus espectral" humano, ou todas as cores percetíveis (em um determinado nível de luminância), onde o triângulo menor é a gama sRGB.

diagrama do locus espectral humano e da gama sRGB

Os monitores de PC profissionais de alta qualidade há muito suportam gamas de cores que são significativamente mais amplas do que o sRGB, como Adobe RGB e DCI-P3 que cobrem cerca de metade das cores percetíveis pelo ser humano. E estes ecrãs de gama larga estão a tornar-se mais comuns.

Gerenciamento automático de cores do sistema

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

O Windows fornece APIs de suporte ao gerenciamento de cores desde o Windows 2000 com as APIs de Gerenciamento de Cores de Imagem (ICM) e posteriores do Sistema de Cores do Windows (WCS). No entanto, essas APIs eram apenas auxiliares para aplicativos que desejavam/precisavam fazer gerenciamento de cores; enquanto a maioria dos aplicativos e conteúdo digital simplesmente assumiu o espaço de cores sRGB padrão da indústria e nunca foi gerenciado por cores pelo sistema operacional. Essa era uma suposição razoável no passado, mas monitores de gama ampla de alta qualidade estão se tornando muito mais comuns.

Novas versões do Windows suportam gerenciamento automático de cores do sistema; que garante que todas as cores em todos os aplicativos do Windows, com ou sem reconhecimento de cores, apareçam com precisão e consistência em todos os monitores suportados.

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 suportar adequadamente monitores que têm gamas 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. Maior profundidade de bits significa que você pode distinguir entre cores muito semelhantes sem artefatos como bandas. Os principais monitores de PC suportam 8 bits por canal de cor, enquanto o olho humano requer pelo menos 10-12 bits de precisão para evitar distorções percetíveis.

Imagem de moinhos de vento numa simulação a 2 bits por canal de cor versus 8 bits por canal

Antes do Advanced Color, o Desktop Window Manager (DWM) restringia as aplicações em janela à saída de conteúdo a apenas 8 bits por canal de cor, mesmo que o ecrã suportasse uma profundidade de bits superior. Quando Advanced Color está ativado, o DWM executa sua composição usando o ponto flutuante de meia precisão IEEE (FP16), eliminando quaisquer gargalos e permitindo que a precisão total da tela seja usada.

Arquitetura do sistema Windows Advanced Color

As informações nesta seção são opcionais para criar aplicativos Advanced Color; Mas é útil entender como a tecnologia funciona para otimizar a renderização e o comportamento do seu aplicativo.

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

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

Windows existente: monitores 8-bit / sRGB

Durante décadas, os ecrãs de consumo e a pilha de gráficos do Windows baseavam-se em cerca de 8 bits por canal (24 bits por pixel) de conteúdo sRGB. Aplicativos que usam APIs gráficas, como DirectX, podem executar renderização interna usando altas profundidades de bits e espaços de cores estendidos; no entanto, o SO suportava apenas números inteiros de 8 bits com sRGB implícito e sem gestão de cores do sistema:

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

Isso significava que quaisquer dados de cores adicionais renderizados por um aplicativo seriam perdidos ao serem exibidos; e que o aplicativo tinha que realizar o próprio gerenciamento de cores para garantir uma reprodução precisa em um display.

Windows 10, versão 1703: monitores HDR com Advanced Color

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

  • Suporte de sinalização para ecrãs 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 blocos da pilha de exibição HDR: FP16, scRGB, com gerenciamento automático de cores

Cada avanço é abordado nas subseções abaixo. O resultado final é que os dados de cores estendidos do aplicativo agora são preservados corretamente pelo sistema operacional e reproduzidos com precisão em monitores HDR.

Suporte de sinalização para ecrãs HDR

A sinalização HDR através de conectores de ecrã, como DisplayPort e HDMI, utiliza principalmente uma precisão de 10 bits por canal (ou superior) e o espaço de cores BT.2100 ST.2084. O kernel de exibição, o driver de vídeo e o hardware de GPU subjacente precisam suportar a deteção, seleção e condução desse modo de sinalização.

Composição de sistema utilizando um espaço de cores normalizado com 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 (mistura). Também queremos preparar o sistema operacional para o futuro para suportar tecnologias e espaços de cores muito além do BT.2100, que cobre menos de 2/3 das cores visíveis por humanos. Finalmente, sempre que possível, queremos minimizar o consumo de recursos da GPU para melhorar a potência e o desempenho.

Quando no modo HDR, o Desktop Window Manager (DWM) usa um espaço de cores de composição canônica (CCCS) definido como:

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

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

Gerenciamento automático de cores do sistema

O Windows é um ambiente multitarefa onde 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 máxima qualidade quando enviados para uma tela; por exemplo, um aplicativo de produtividade sRGB (SDR) com uma janela de vídeo BT.2100 ST.2084 (HDR) reproduzindo sobre ele.

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

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

diagrama de blocos do gerenciamento automático de cores que ocorre no DWM e no kernel de exibição diagrama de blocos do gerenciamento automático de cores que ocorre no DWM e no kernel de exibição, parte 2

Observação

Em ambos os estágios, a operação de gestão de cores consiste em uma conversão de espaço de cores (matriz e 1DLUT). As cores que excedem a gama de cores alvo do ecrã são limitadas numericamente.

Windows 11, versão 22H2: monitores SDR com Advanced Color

Embora a prevalência de monitores HDR esteja crescendo rapidamente, os monitores SDR continuarão sendo importantes nos próximos anos. O suporte a HDR no Windows 10, versão 1703, estabeleceu a maior parte do trabalho de base necessário para melhorar os monitores SDR também. O Windows 11, versão 22H2 estende os recursos de gerenciamento avançado de cores e cores automáticas para determinados monitores SDR qualificados. O diagrama de blocos gráficos para monitores SDR coloridos avançados é muito semelhante ao HDR:

diagrama em blocos da camada de ecrã SDR AC: FP16, scRGB, com gestão automática de cores

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

A sinalização subjacente para monitores SDR permanece inalterada, embora a versão 22H2 do Windows 11 suporte 10 bits por canal e superior, dependendo das capacidades do monitor.

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

A funcionalidade DWM Advanced Color, incluindo a mistura em CCCS, permanece quase totalmente inalterada em relação aos monitores HDR. A principal diferença é que o DWM utiliza luminância referida ao display com monitores SDR e luminância referida à cena com monitores HDR. Isso altera a maneira como o conteúdo renderizado do Advanced Color é interpretado pelo sistema operacional:

Tipo de exibição Comportamento da luminância Como é interpretado o 1.0f
SDR Display-referred Como nível de branco de referência do visor
HDR Scene-referred As 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 permanecem praticamente inalterados em relação aos monitores HDR. A principal diferença é que o kernel do monitor converte para o espaço de cores referido ao display, conforme definido pelos dados de colorimetria e calibração do display, em vez do espaço de cores padrão BT.2100 ST.2084 para monitores HDR.

Provisionamento de exibição necessário

Dados precisos de um perfil ICC MHC são necessários para definir a operação de gerenciamento de cores de saída do kernel de exibição. Portanto, somente monitores SDR que foram especificamente provisionados pelo fabricante ou por um provedor de calibração de vídeo com um perfil válido são elegíveis para gerenciamento automático de cores. Consulte o comportamento do perfil ICC com Advanced Color para obter mais informações.

Requisitos do sistema e suporte ao sistema operacional

O Windows 10, versão 1709 foi fornecido pela primeira vez com suporte a cores avançadas para monitores HDR. A versão 22H2 do Windows 11 adiciona suporte a cores avançadas para monitores SDR com dados de provisionamento precisos.

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

Ecrã

Um monitor de alta faixa dinâmica deve implementar o padrão HDR10 ou BT.2100 ST.2084. A qualidade do ecrã HDR pode variar muito, pelo que recomendamos vivamente ecrãs certificados, como VESA DisplayHDR. A partir da versão 22H2 do Windows 11, o Windows exibe o status de certificação de monitores conhecidos em Configurações.

Uma exibição de faixa dinâmica 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 suportado para substituir esses dados é por meio de um perfil ICC MHC; Além disso, o usuário ou fabricante do monitor deve ter habilitado o gerenciamento automático de cores. Para obter mais informações, consulte Comportamento do perfil ICC com Advanced Color.

Processador gráfico (GPU)

Para obter a funcionalidade Advanced Color completa em monitores SDR e HDR, é necessária uma GPU recente:

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

Observação

Os chipsets de nome de código Intel Comet Lake (código de modelo de 5 dígitos) 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 a PlayReady (SL3000). Entre em contato com o fornecedor da GPU para obter informações mais específicas.

Driver gráfico (WDDM)

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

APIs de renderização suportadas

O Windows 10 oferece 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 do Visual Layer.

Portanto, qualquer API de renderização que possa gerar saída para um desses métodos de apresentação pode oferecer suporte ao Advanced Color. Isso inclui (mas não está limitado 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
    • Suporta renderização personalizada de tinta seca usando DirectX.
  • XAML
    • Suporta reprodução de vídeos HDR usando MediaPlayerElement.
    • Suporta decodificação de imagens JPEG XR usando o elemento Image.
    • Suporta interoperabilidade com DirectX usando SwapChainPanel.

Gestão das capacidades de visualização dinâmica

O Windows 10 suporta uma enorme variedade de ecrãs com capacidade Advanced Color, desde painéis integrados energeticamente eficientes a monitores de jogos e TVs topo de gama. Os utilizadores do Windows esperam que o seu aplicativo lide perfeitamente com todas essas variações, incluindo os monitores SDR existentes e onipresentes.

O Windows 10 fornece controle sobre HDR e recursos de cores avançadas para o usuário. Seu aplicativo deve detetar a configuração da tela atual e responder dinamicamente a quaisquer alterações na capacidade. Isso pode ocorrer por vários motivos, por exemplo, porque o usuário ativou ou desabilitou um recurso, ou moveu o aplicativo entre diferentes monitores, ou o estado de energia do sistema mudou.

Opção 1: AdvancedColorInfo

Observação

O AdvancedColorInfo API do Tempo de Execução do Windows é utilizável independentemente da API de renderização, oferece suporte a Cores Avançadas para exibições SDR e usa eventos para sinalizar quando os recursos mudam. No entanto, ele está disponível apenas para aplicativos da Plataforma Universal do Windows (UWP); as aplicações de ambiente de trabalho (que não têm um CoreWindow) não podem utilizá-lo. Para saber mais, consulte APIs do Windows Runtime não suportadas em aplicações de ambiente de trabalho.

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

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

Tipo de cor avançado Capacidades de visualização
SDR Ecrã SDR sem capacidades avançadas de cor
WCG Display SDR com alta profundidade de bits e gerenciamento automático de cores
HDR Ecrã HDR com todas as capacidades avançadas de cor

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

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

Para lidar com alterações nos recursos Advanced Color, inscreva-se no evento DisplayInformation::AdvancedColorInfoChanged. Esse evento é gerado se qualquer parâmetro dos recursos de Cores Avançadas da tela for alterado por qualquer motivo.

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

IDXGIOutput6

Observação

A interface IDXGIOutput6 da Infraestrutura Gráfica do DirectX está disponível para qualquer aplicativo que use DirectX, seja área de trabalho ou UWP (Plataforma Universal do Windows). No entanto, IDXGIOutput6não suporta monitores SDR com recursos avançados de cores, como gerenciamento automático de cores; ele pode identificar apenas monitores HDR.

Se você estiver escrevendo um aplicativo de área de trabalho Win32 e usando DirectX para renderizar, use DXGI_OUTPUT_DESC1 para obter recursos de exibição. Obtenha uma instância dessa estrutura através de IDXGIOutput6::GetDesc1.

Para verificar qual tipo de Cor Avançada está ativa no momento, use a propriedade ColorSpace, que é do tipo DXGI_COLOR_SPACE_TYPEe contém um dos seguintes valores:

DXGI_COLOR_SPACE_TYPE Capacidades de visualização
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 Ecrã SDR sem capacidades avançadas de cor
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 Ecrã HDR com todas as capacidades avançadas de cor

Observação

Monitores SDR com recursos Advanced Color também são relatados como DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; DXGI não permite que você distinga entre os dois tipos.

Observação

O DXGI não permite que você verifique quais tipos de cores avançadas são suportados, mas não ativos no momento.

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

As aplicações de ambiente de trabalho Win32 não têm um mecanismo nativo para responder às alterações de funcionalidade de Cor Avançada. Em vez disso, se seu aplicativo usa um loop de renderização, você deve consultar IDXGIFactory1::IsCurrent com cada quadro. Se ele relatar FALSE, então você deve obter um novo DXGI_OUTPUT_DESC1 e verificar quais valores foram alterados.

Além disso, sua bomba de mensagens Win32 deve manipular a mensagem WM_SIZE, o que indica que seu aplicativo pode ter se movido entre monitores diferentes.

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 permuta retornam uma saída DXGI obsoleta quando DXGIFactory::IsCurrent é false; e recriar a cadeia de permuta para obter uma saída atual resulta em uma tela temporariamente preta. Em vez disso, recomendamos que enumerem os limites de todas as saídas DXGI e determinem qual delas tem a maior interseção com os limites da janela da aplicação.

O código de exemplo a seguir vem do aplicativo de exemplo Direct3D 12 HDR 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));

Configurar a cadeia de permuta DirectX

Depois de determinar que a tela atualmente suporta recursos de cores avançadas, configure sua cadeia de permuta da seguinte maneira.

Usar um efeito de modelo de apresentação invertida

Ao criar a sua cadeia de permuta usando um dos métodos CreateSwapChainFor[Hwnd|Composition|CoreWindow], deve usar o modelo de flip DXGI selecionando a opção DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ou DXGI_SWAP_EFFECT_FLIP_DISCARD, o que torna a sua cadeia de permuta elegível para processamento de cores avançadas do DWM e várias otimizações em ecrã completo. Para obter mais informações, consulte Para obter o melhor desempenho, use o modelo de inversão DXGI.

Opção 1. Use o formato de pixel FP16 e o espaço de cores scRGB

O Windows 10 suporta duas combinações principais de formato de pixel e espaço de cores para Advanced Color. Selecione um com base nos requisitos específicos do seu aplicativo.

Recomendamos que as aplicações de uso geral utilizem a Opção 1. É a única opção que funciona para todos os tipos de exibições de cores avançadas, conteúdo e APIs de renderização. Ao criar a sua swap chain, especifique DXGI_FORMAT_R16G16B16A16_FLOAT no seu DXGI_SWAP_CHAIN_DESC1. Por padrão, uma cadeia de permuta criada com um formato de pixel de ponto flutuante é tratada como se usasse o espaço de cores 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 mistura.

No entanto, essa opção consome 64 bits por pixel, o que dobra a largura de banda da GPU e o consumo de memória em comparação com os formatos tradicionais de pixel UINT8. 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. Não há nenhuma fixação imposta em valores abaixo de -0,5 ou acima de 7,5, conforme especificado nos documentos padrão scRGB antigos. Por exemplo, scRGB (1.0, 1.0, 1.0) codifica o padrão D65 branco a 80 nits; mas scRGB (12.5, 12.5, 12.5) codifica o mesmo branco D65 a 1000 nits muito mais brilhantes. Algumas operações gráficas exigem um intervalo numérico normalizado, e você deve modificar a operação ou renormalizar os valores de cor.

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

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

A opção 2 é uma otimização de desempenho que só estará disponível se seu aplicativo atender a todas as seguintes condições:

  • Destina-se a um ecrã HDR
  • Usa Direct3D 12 ou Direct3D 11
  • A cadeia de swap não requer mistura com alfa/transparência

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

Mas se o seu aplicativo se qualificar para a opção 2, isso poderá fornecer um 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 cheia, como um jogo. Ao criar sua cadeia de permuta, você deve considerar especificar DXGI_FORMAT_R10G10B10A2_UNORM em DXGI_SWAP_CHAIN_DESC1. Por padrão, isso é tratado como usar o espaço de cores sRGB; portanto, você deve chamar explicitamente IDXGISwapChain3::SetColorSpace1e definir como seu espaço de cores DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, também conhecido como HDR10/BT.2100.

Esta opção consome os mesmos 32 bits por pixel que os formatos tradicionais de pixel SDR UINT8. Além disso, em certas GPUs, isso elimina algum processamento necessário para converter o conteúdo para o formato de fio HDR10.

Usando uma cadeia de permuta de cores avançada quando a tela está no modo SDR

Pode utilizar uma cadeia de troca de Cores Avançadas, mesmo que o ecrã não suporte todas as capacidades das Cores Avançadas. Nesses casos, o Desktop Window Manager (DWM) irá converter o seu conteúdo para se ajustar às capacidades do ecrã, executando o recorte numérico. Por exemplo, se renderizar para uma swapchain scRGB FP16 e tiver como alvo um ecrã padrão, tudo fora do intervalo numérico [0, 1] será recortado.

Esse comportamento de conversão para baixo também ocorrerá se a janela do seu aplicativo estiver cobrindo dois ou mais monitores com capacidades de cores avançadas diferentes. AdvancedColorInfo e IDXGIOutput6 são abstraídos para relatar apenas as características do monitor principal (sendo o principal definido como o display que contém o centro da janela).

Faça corresponder o branco de referência da sua aplicação ao nível de branco de referência SDR do Sistema Operativo

Observação

A referência branca aplica-se apenas a ecrãs HDR; para ecrãs SDR Advanced Color, (1.0, 1.0, 1.0) significa sempre a luminância branca máxima que o ecrã pode reproduzir.

Em muitos cenários, seu aplicativo desejará renderizar conteúdo SDR e HDR; por exemplo, renderizar legendas ou controles de transporte sobre vídeo HDR ou interface do usuário em uma cena de jogo. É importante entender o conceito de nível de branco de referência SDR para garantir que seu conteúdo SDR pareça correto em uma tela HDR. Branco de referência indica o brilho no qual um objeto branco difuso (como uma folha de papel ou, às vezes, uma interface do usuário) aparece em uma cena HDR. Como os valores de cor HDR têm brilho referenciado por cena, um determinado valor de cor 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 com luminância de 80 nits. O Windows permite que o usuário ajuste o nível de branco de referência SDR à sua preferência; essa é a luminância que o Windows renderizará sRGB (1.0, 1.0, 1.0) em. Em monitores HDR desktop, os níveis de branco de referência SDR são normalmente definidos para cerca de 200 nits.

Seu aplicativo HDR deve permitir que o usuário defina o nível de 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 de branco de referência SDR. Isso implica multiplicar o framebuffer da sua aplicação no espaço de gama linear.

Observação

Em uma tela que suporta um controle de brilho, como em um laptop, o Windows também ajusta a luminância do conteúdo HDR (referenciado por cena) para corresponder ao nível de brilho desejado pelo usuário, mas isso é invisível para o aplicativo. A menos que estejas a tentar garantir a reprodução com precisão de bits do sinal HDR, podes geralmente ignorar isso.

Se seu aplicativo sempre renderiza SDR e HDR em superfícies separadas e depende da composição do sistema operacional, o Windows executará automaticamente o ajuste correto para aumentar o conteúdo SDR para o nível de branco desejado. Por exemplo, se o seu aplicativo usa XAML e renderiza conteúdo HDR para o 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 de branco de referência SDR por conta própria. Caso contrário, o conteúdo SDR pode parecer muito fraco em condições típicas de visualização na área de trabalho. Primeiro, você deve obter o nível de branco de referência SDR atual e, em seguida, deve ajustar os valores de cor de qualquer conteúdo SDR que estiver renderizando.

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

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

Passo 2. Ajustar os valores de cor do conteúdo 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 para uma cadeia de permuta FP16, ele seria reproduzido com luminância de 80 nits. Para corresponder ao nível de branco de referência real definido pelo usuário, você deve ajustar o conteúdo SDR de 80 nits para o nível especificado por meio AdvancedColorInfo.SdrWhiteLevelInNits.

Se você estiver renderizando usando FP16 e scRGB, ou qualquer espaço de cor que use gama linear (1.0), então você pode simplesmente multiplicar o valor de cor SDR por AdvancedColorInfo.SdrWhiteLevelInNits / 80. Se você estiver usando Direct2D, há 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 cores gama não linear, como HDR10, executar o ajuste do nível de branco SDR é mais complexo. Se você estiver escrevendo seu próprio sombreador de pixel, considere converter em gama linear para aplicar o ajuste.

Adapte o conteúdo HDR às capacidades do ecrã utilizando o mapeamento de tons

Os ecrãs HDR e Advanced Color variam muito em termos das suas capacidades. 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 HDR conterá cores que excedem as capacidades do ecrã. Para obter a melhor qualidade de imagem, é importante que você execute o mapeamento de tons HDR, essencialmente compactando a gama 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 de conteúdo); mapeadores de tons mais sofisticados também adaptarão luminância mínima (MinCLL) e/ou cores primárias.

Passo 1. Obtenha as capacidades de volume de cores do ecrã

Aplicativos da Plataforma Universal do Windows (UWP)

Use AdvancedColorInfo para obter o volume de cores da tela.

Aplicações DirectX Win32 (ambiente de trabalho)

Use DXGI_OUTPUT_DESC1 para obter o volume de cores da tela.

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

Dependendo de onde seu conteúdo HDR veio, há várias maneiras possíveis 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 foi renderizado dinamicamente, talvez seja possível extrair informações de cena dos estágios internos de renderização, por exemplo, a fonte de luz mais brilhante de uma cena.

Uma solução mais geral, mas computacionalmente cara, é executar um histograma ou outra passagem de análise no quadro renderizado. O aplicativo de exemplo de renderização avançada de imagens coloridas Direct2D no GitHub demonstra como fazer isso usando Direct2D; Os trechos 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;
}

Passo 3. Executar a operação de mapeamento de tons HDR

O mapeamento de tons é inerentemente um processo com perdas e pode ser otimizado para uma série de métricas percetivas ou objetivas, portanto, não há um algoritmo padrão único. O Windows fornece um efeito de mapeamento de tons HDR integrado 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 simplificado Reinhard tonemapper é 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;
}

Capturando conteúdo de tela HDR e WCG

As APIs que suportam a especificação de formatos de pixel, como as do namespace Windows.Graphics.Capture e o método IDXGIOutput5::DuplicateOutput1, 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, é necessário processamento adicional. Por exemplo, mapeamento de tom HDR para SDR (por exemplo, cópia de captura de tela SDR para compartilhamento na Internet) e salvamento de conteúdo com formato adequado (por exemplo, JPEG XR).

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

O gerenciamento avançado de cores e cores automáticas garante cores de exibição consistentes e colorimetricamente precisas para todos os aplicativos, legados e modernos. No entanto, alguns aplicativos podem executar seu próprio gerenciamento de cores explícito usando perfis de cores do International Color Consortium (ICC).

Quando a Cor Avançada está ativa em ecrãs SDR ou HDR, o comportamento dos perfis ICC de ecrã altera-se de formas que não são retroativamente compatíveis. Se seu aplicativo funciona com perfis ICC de exibição, o Windows oferece auxiliares de compatibilidade para garantir que seu aplicativo continue a ter o comportamento correto.

Para obter mais informações sobre as alterações no comportamento do perfil ICC e como você pode adaptar seu aplicativo para maximizar a compatibilidade com o Advanced Color, consulte o comportamento do perfil ICC com Advanced Color.

Recursos adicionais