Técnicas comuns para aprimorar os mapas de profundidade de sombra

Mapas de sombra, introduzidos pela primeira vez em 1978, são uma técnica comum para adicionar sombras aos jogos. Três décadas depois, apesar dos avanços em hardware e software, os artefatos de sombreamento — ou seja, bordas cintilantes, aliasing de perspectiva e outros problemas de precisão — persistem.

Este artigo técnico fornece uma visão geral de alguns algoritmos comuns de mapa de profundidade de sombra e artefatos comuns e explica várias técnicas, variando em dificuldades de básico a intermediário, que podem ser usadas para aumentar a qualidade dos mapas de sombra padrão. Adicionar mapas de sombra básicos a um título normalmente é simples, mas entender as nuances dos artefatos de sombra pode ser desafiador. Este artigo técnico é escrito para o desenvolvedor de elementos gráficos intermediários que implementou sombras, mas não entende completamente por que artefatos específicos aparecem e não tem certeza de como contorná-los.

Selecionar as técnicas corretas para atenuar artefatos específicos não étrivial. Quando as deficiências do mapa de sombra são abordadas, a diferença de qualidade pode ser impressionante (Figura 1). A implementação correta dessas técnicas melhora drasticamente as sombras padrão. As técnicas explicadas neste artigo são implementadas no exemplo CascadedShadowMaps11 no SDK do DirectX.

Figura 1. Sombras com artefatos severos (à esquerda) e sombras depois de implementar as técnicas descritas neste artigo (à direita)

sombras com artefatos severos (à esquerda) e sombras depois de implementar as técnicas descritas neste artigo (à direita)

Análise de Mapas de Profundidade de Sombra

O algoritmo de mapa de profundidade de sombra é um algoritmo de dois passes. A primeira passagem gera um mapa de profundidade no espaço leve. Na segunda passagem, esse mapa é usado para comparar a profundidade de cada pixel no espaço leve em relação à profundidade correspondente no mapa de profundidade do espaço leve.

Figura 2. Partes-chave de uma cena de sombra

partes principais de uma cena de sombra

Passar 1

A cena é mostrada na Figura 2. Na primeira passagem (Figura 3), a geometria é renderizada em um buffer de profundidade do ponto de vista da luz. Mais especificamente, o sombreador de vértice transforma a geometria em espaço de exibição de luz.

O resultado final dessa primeira passagem é um buffer de profundidade que contém as informações de profundidade da cena do ponto de vista da luz. Isso agora pode ser usado na passagem 2 para determinar quais pixels são excluídos da luz.

Figura 3. Primeira passagem do mapeamento de sombra básico

primeira passagem do mapeamento de sombra básico

Passar 2

Na segunda passagem (Figura 4), o sombreador de vértice transforma cada vértice duas vezes. Cada vértice é transformado no espaço de exibição da câmera e passado para o sombreador de pixel como a posição. Cada vértice também é transformado pela matriz view-projection-texture da luz e passado para o sombreador de pixel como uma coordenada de textura. A matriz view-projection-texture é a mesma matriz usada para renderizar a cena na passagem 1 com uma transformação adicional. É uma transformação que dimensiona e converte os pontos do espaço de exibição (–1 para 1 em X e Y) para o espaço de textura (0 a 1 em X e 1 para 0 em Y).

O sombreador de pixel recebe a posição interpolada e as coordenadas de textura interpoladas. Tudo o que é necessário para executar o teste de profundidade agora está nesta coordenada de textura. O teste de profundidade agora pode ser executado indexando o buffer de profundidade da primeira passagem com as coordenadas de textura X e Y e comparando o valor de profundidade resultante com a coordenada de textura Z.

Figura 4. Segunda passagem de mapeamento de sombra básico

segunda passagem do mapeamento de sombra básico

Artefatos de mapa de sombra

O algoritmo de mapa de profundidade de sombra é o algoritmo de sombreamento em tempo real mais amplamente usado, mas ainda produz vários artefatos que exigem mitigação. Os tipos de artefatos que podem ocorrer são resumidos em seguida.

Aliasing de perspectiva

O aliasing de perspectiva, um artefato comum, é mostrado na Figura 5. Isso ocorre quando o mapeamento de pixels no espaço de exibição para texels no mapa de sombra não é uma proporção de um para um. Isso ocorre porque os pixels próximos ao plano próximo estão mais próximos e exigem uma resolução de mapa de sombra mais alta.

A Figura 6 mostra um mapa de sombra e um frusto de exibição. Perto do olho, os pixels estão mais próximos e muitos pixels são mapeados para os mesmos texels de sombra. Os pixels no plano distante são distribuídos, reduzindo assim o aliasing de perspectiva.

Figura 5. Aliasing de alta perspectiva (esquerda) versus aliasing de baixa perspectiva (à direita)

aliasing de alta perspectiva (esquerda) versus aliasing de baixa perspectiva (direita)

Para a imagem à esquerda, o aliasing de perspectiva é maior; muitos pixels de espaço nos olhos são mapeados para os mesmos texels de mapa de sombra. Na imagem à direita, o aliasing de perspectiva é baixo porque há um mapeamento 1:1 entre os pixels de espaço nos olhos e texels de mapa de sombra.

Figura 6. Exibir frusto com mapa de sombra

exibir frustum com mapa de sombra

Pixels claros no plano distante representam aliasing de baixa perspectiva, e pixels escuros no plano próximo representam aliasing de alta perspectiva.

A resolução do mapa de sombra também pode ser muito alta. Embora uma resolução mais alta seja menos perceptível, ela, no entanto, pode resultar em objetos pequenos, como fios telefônicos, não em sombras de conversão. Além disso, ter uma resolução muito alta pode causar graves problemas de desempenho devido a padrões de acesso à textura.

PSMs (mapas de sombra de perspectiva) e LSPSMs (mapas de sombra do espaço claro) tentam abordar o alias de perspectiva distorcendo a matriz de projeção da luz, a fim de colocar mais texels perto do olho onde eles são necessários. Infelizmente, nenhuma técnica é capaz de resolver o aliasing de perspectiva. A parametrização da transformação necessária para mapear pixels de espaço nos olhos para texels no mapa de sombra não pode ser associada por uma distorção linear. Uma parametrização logarítmica é necessária. PSMs colocam muitos detalhes perto do olho, fazendo com que sombras distantes sejam de baixa qualidade ou até mesmo desapareçam. Os LSPSMs fazem um trabalho melhor de encontrar um meio termo entre aumentar a resolução perto do olho e deixar detalhes suficientes para objetos distantes. Ambas as técnicas são degeneradas para sombras ortográficas em algumas configurações de cena. Essa degeneração pode ser contrariada renderizando um mapa de sombra separado para cada face do frusto de exibição, embora isso seja caro. Os LogPSMs (mapas de sombra de perspectiva logarítmica) também renderizam um mapa separado por face do frusto de exibição. Essa técnica usa rasterização não linear para colocar mais texels perto do olho. O hardware da classe D3D10 e D3D11 não dá suporte à rasterização não linear. Para obter mais informações sobre essas técnicas e algoritmos, consulte a seção Referências.

CSMs (mapas de sombra em cascata) são a técnica mais popular para lidar com o aliasing de perspectiva. Embora os CSMs possam ser combinados com PSMs e LSPSMs, isso é desnecessário. O uso de CSMs para corrigir erros de alias de perspectiva é abordado no artigo complementar, Cascaded Shadow Maps.

Aliasing projetivo

O aliasing projetivo é mais difícil de mostrar do que o aliasing de perspectiva. As sombras distended realçadas na Figura 7 demonstram erros de alias de projeto. O aliasamento projetivo ocorre quando o mapeamento entre texels no espaço da câmera para texels no espaço leve não é uma proporção de um para um; isso ocorre devido à orientação da geometria em relação à câmera de luz. O aliasamento projetivo ocorre à medida que o plano tangente da geometria se torna paralelo aos raios de luz.

Figura 7. Aliasing de alto projeto versus aliasing de baixo projeto

aliasing de alto projeto versus aliasing de baixo projeto

Técnicas usadas para aliviar erros de alias de perspectiva também atenuam o aliasamento projetivo. O aliasamento projetivo ocorre quando a superfície normal é ortogonal à luz; essas superfícies devem receber menos luz com base em equações de iluminação difusa.

Acne sombra e Self-Shadowing errônea

Acne de sombra (Figura 8), um termo sinônimo de auto-sombreamento errôneo, ocorre quando o mapa de sombra quantifica a profundidade sobre um texel inteiro. Quando o sombreador compara uma profundidade real com esse valor, é tão provável que ele seja auto-sombreado quanto sem sombra.

Outro motivo para acne de sombra é que o texel no espaço leve está tão próximo da profundidade do texel correspondente no mapa de profundidade que erros de precisão fazem com que o teste de profundidade falhe erroneamente. Um motivo para essa diferença de precisão é que o mapa de profundidade foi calculado pelo hardware de rasterização de função fixa, enquanto a profundidade que está sendo comparada foi calculada pelo sombreador. O aliasamento projetivo também pode causar acne de sombra.

Figura 8. Artefato de acne de sombra

artefato de acne sombra

Conforme mostrado na imagem à esquerda, alguns pixels falharam no teste de profundidade e criaram artefatos e padrões moiré. Para reduzir o auto-sombreamento errôneo, os limites no plano próximo e o plano distante para o frusto da exibição do espaço leve devem ser calculados da forma mais rigorosa possível. O viés de profundidade baseado em escala de inclinação e outros tipos de viés são outras soluções usadas para atenuar a acne de sombra.

Peter Panning

O termo Peter Panning deriva seu nome de um personagem de livro infantil cuja sombra se desanexou e quem poderia voar. Este artefato faz com que objetos com sombras ausentes pareçam ser desanexados de e flutuar acima da superfície (Figura 9).

Figura 9. Artefato de Peter Panning

artefato de movimento panorâmico peter

Na imagem à esquerda, a sombra é desanexada do objeto, criando um efeito flutuante.

Uma técnica para remover acne de superfície é adicionar algum valor à posição do pixel no espaço claro; isso é chamado de adição de um deslocamento de profundidade. Peter Panning resulta quando o deslocamento de profundidade usado é muito grande. Nesse caso, o deslocamento de profundidade faz com que o teste de profundidade seja aprovado erroneamente. Como acne de sombra, Peter Panning é agravado quando não há precisão suficiente no buffer de profundidade. Calcular aviões apertados perto de aviões e aviões distantes também ajuda a evitar Peter Panning.

Técnicas para melhorar mapas de sombra

Adicionar sombras a um título é um processo. A primeira etapa é fazer com que os mapas de sombra básicos funcionem. A segunda é garantir que todos os cálculos básicos sejam feitos de forma ideal: o ajuste de frusta o mais forte possível, planos próximos/distantes se encaixam firmemente, o viés em escala de inclinação é usado e assim por diante. Depois que as sombras básicas estiverem habilitadas e parecerem as melhores possíveis, o desenvolvedor terá uma ideia melhor de quais algoritmos são necessários para levar as sombras à fidelidade suficiente. Dicas básicas que podem ser necessárias para que os mapas de sombra básicos examinem o melhor deles são fornecidas nesta seção.

Slope-Scale viés de profundidade

Como mencionado anteriormente, o auto-sombreamento pode levar à acne de sombra. Adicionar muito viés pode resultar em Peter Panning. Além disso, polígonos com encostas íngremes (em relação à luz) sofrem mais com aliasamento projetivo do que polígonos com encostas rasas (em relação à luz). Por isso, cada valor do mapa de profundidade pode precisar de um deslocamento diferente dependendo da inclinação do polígono em relação à luz.

O hardware do Direct3D 10 tem a capacidade de influenciar um polígono com base em sua inclinação em relação à direção da exibição. Isso tem o efeito de aplicar um grande viés a um polígono que é exibido na direção da luz, mas não aplicar qualquer viés a um polígono voltado diretamente para a luz. A Figura 10 ilustra como dois pixels vizinhos podem alternar entre sombreados e sem sombra ao testar a mesma inclinação imparcial.

Figura 10. Inclinação dimensionada de viés de profundidade em comparação com profundidade imparcial

inclinação dimensionada de viés de profundidade em comparação com a profundidade imparcial

Calculando uma projeção apertada

Ajustar firmemente a projeção da luz ao frusto de exibição aumenta a cobertura do mapa de sombra. A Figura 11 ilustra que usar uma projeção arbitrária ou ajustar a projeção aos limites da cena resulta em alias de perspectiva mais alta.

Figura 11. Frusto de sombra arbitrário e frusto de sombra aptos à cena

frusto de sombra arbitrário e frusto de sombra aptos à cena

A exibição é do ponto de vista da luz. O trapezóide representa o frusto da câmera de exibição. A grade desenhada sobre a imagem representa o mapa de sombra. A imagem à direita mostra que o mesmo mapa de sombra de resolução cria mais cobertura texel quando é mais adequado para a cena.

A Figura 12 ilustra os frutos que se encaixam corretamente. Para calcular a projeção, os oito pontos que compõem o frusto de exibição são transformados em espaço leve. Em seguida, os valores mínimo e máximo em X e Y são encontrados. Esses valores compõem os limites de uma projeção ortográfica.

Figura 12. Projeção de sombra adequada para exibir o frusto

projeção de sombra adequada para exibir o frusto

Também é possível cortar o frusto para a cena AABB para obter um limite mais apertado. Isso não é aconselhável em todos os casos porque isso pode alterar o tamanho da projeção da câmera de luz de quadro para quadro. Muitas técnicas, como as descritas na seção Movendo a luz Texel-Sized incrementos, fornecem melhores resultados quando o tamanho da projeção da luz permanece constante em cada quadro.

Calculando o plano próximo e o plano distante

O plano próximo e o plano distante são as partes finais necessárias para calcular a matriz de projeção. Quanto mais próximos forem os planos, mais precisos serão os valores no buffer de profundidade.

O buffer de profundidade pode ser de 16 bits, 24 bits ou 32 bits, com valores entre 0 e 1. Em geral, os buffers de profundidade são um ponto fixo, com os valores próximos ao plano próximo agrupados mais de perto do que os valores próximos ao plano distante. O grau de precisão disponível para o buffer de profundidade é determinado pela proporção do plano próximo ao plano distante. Usar o plano mais próximo/distante possível pode permitir o uso de um buffer de profundidade de 16 bits. Um buffer de profundidade de 16 bits poderia reduzir o uso de memória enquanto aumentava a velocidade de processamento.

AABB-Based plano próximo e plano distante

Uma maneira fácil e ingênua de calcular o plano próximo e o plano distante é transformar o volume delimitado da cena em espaço leve. O menor valor da coordenada Z é o plano próximo e o maior valor da coordenada Z é o plano distante. Para muitas configurações da cena e da luz, essa abordagem é suficiente. No entanto, o pior cenário pode resultar em uma perda significativa de precisão no buffer de profundidade; A Figura 13 mostra esse cenário. Aqui, o alcance do plano próximo ao plano distante é quatro vezes maior do que o necessário.

O frusto de exibição na Figura 13 foi escolhido propositalmente para ser pequeno. Um pequeno frusto de exibição é mostrado em uma cena muito grande que consiste em pilares que se estendem para fora da câmera de exibição. O uso da AABB de Cena para os planos próximos e distantes não é ideal. O algoritmo CSM descrito no artigo técnico Mapas de Sombra em Cascata deve calcular planos próximos e distantes para frutos muito pequenos.

Figura 13. Planos próximos e distantes baseados na Cena AABB

planos próximos e distantes baseados em cena aabb

Frustum-Based plano próximo e plano distante

Outra técnica para calcular os planos próximos e distantes é transformar o frusto em espaço leve e usar os valores mínimos e máximos em Z como os planos próximos e distantes, respectivamente. A Figura 14 ilustra os dois problemas com essa abordagem. Primeiro, o cálculo é muito conservador, conforme mostrado quando o frusto se estende além da geometria da cena. Segundo, o plano próximo pode ser muito apertado, fazendo com que os rodízios de sombra sejam cortados.

Figura 14. Planos próximos e distantes baseados apenas no frusto de exibição

planos próximos e distantes baseados apenas no frusto de exibição

Frusto leve interseccionou-se com cena para calcular planos próximos e distantes

A maneira adequada de calcular os planos próximos e distantes é mostrada na Figura 15. Quatro dos planos do frusto de luz ortográfica foram calculados usando o mínimo e o máximo das coordenadas X e Y do frusto de exibição no espaço leve. Os dois últimos aviões do frusto de exibição ortogonal são os planos próximos e distantes. Para encontrar esses aviões, os limites da cena são cortados contra os quatro planos de frutos da luz conhecidos. Os menores e maiores valores Z do limite recém-recortado representam o plano próximo e o plano distante, respectivamente.

O código que executa essa operação está localizado no exemplo CascadedShadowMaps11. Os oito pontos que compõem a AABB do mundo são transformados em espaço leve. Transformar os pontos em espaço claro simplifica os testes de recorte. Os quatro planos conhecidos do frusto de luz agora podem ser representados como linhas. O volume delimitado de cenas no espaço claro pode ser representado como seis quadriláteros. Esses 6 quadriláteros podem então ser transformados em 12 triângulos para recorte baseado em triângulo. Os triângulos são recortados contra os planos conhecidos do frusto de exibição (são linhas horizontais e verticais em X e Y no espaço leve). Quando um ponto de interseção é encontrado em X e Y, o triângulo 3D é recortado nesse ponto. Os valores Z mínimos e máximos de todos os triângulos recortados são o plano próximo e o plano distante. O exemplo CascadedShadowMaps11 mostra como executar esse recorte na função ComputeNearAndFar .

Há mais duas técnicas que podem ser usadas para calcular os planos mais apertados possíveis próximos e distantes. Essas técnicas não são mostradas na amostra CascadedShadowMaps.

  • Planos mais próximos e distantes ainda mais apertados podem ser calculados cruzando uma hierarquia de uma cena ou objetos individuais em uma cena contra o frusto de luz. Isso seria computacionalmente mais complexo. Embora não seja ilustrado na amostra CascadedShadowMaps11, essa pode ser uma técnica válida para alguns blocos.

  • O plano distante pode ser calculado tomando o mínimo de:

    • A maior profundidade do frusto de exibição no espaço leve.
    • A maior profundidade da interseção do frusto de exibição e da cena AABB.

Essa abordagem pode ser problemática quando usada com mapas de sombra em cascata onde é possível indexar fora de um frusto de exibição. Nesse caso, o mapa de sombra pode estar faltando geometria.

Figura 15. Planos próximos e distantes baseados na interseção dos quatro planos calculados do frutos da luz e da geometria delimitador da cena

planos próximos e distantes com base na interseção dos quatro planos calculados do frusto de luz e da geometria delimitador da cena

Movendo a luz em incrementos de Texel-Sized

Um artefato comum em mapas de sombra é o efeito de borda cintilante. À medida que a câmera se move, os pixels ao longo das bordas das sombras se iluminam e escurecem. Isso não pode ser visto em imagens paradas, mas é muito perceptível e distrativo em tempo real. A Figura 16 realça esse problema e a Figura 17 mostra a aparência das bordas de sombra.

O erro de borda cintilante ocorre porque a matriz de projeção de luz está sendo recalculada toda vez que a câmera se move. Isso cria diferenças sutis nos mapas de sombra gerados. Todos os fatores a seguir podem influenciar a matriz criada para associar a cena.

  • Tamanho do frusto de exibição
  • Orientação do frusto de exibição
  • Local da luz
  • Local da câmera

Sempre que essa matriz muda, as bordas das sombras podem mudar.

Figura 16. Bordas de sombra cintilantes

bordas de sombra cintilantes

Os pixels ao longo da borda da sombra entram e saem da sombra à medida que a câmera se move da esquerda para a direita.

Figura 17. Sombras sem bordas cintilantes

sombras sem bordas cintilantes

As bordas de sombra permanecem constantes à medida que a câmera se move da esquerda para a direita.

Para luzes direcionais, a solução para esse problema é arredondar o valor mínimo/máximo em X e Y (que compõem os limites de projeção ortográfica) para incrementos de tamanho de pixel. Isso pode ser feito com uma operação de divisão, uma operação de piso e uma multiplicação.

        vLightCameraOrthographicMin /= vWorldUnitsPerTexel;
        vLightCameraOrthographicMin = XMVectorFloor( vLightCameraOrthographicMin );
        vLightCameraOrthographicMin *= vWorldUnitsPerTexel;
        vLightCameraOrthographicMax /= vWorldUnitsPerTexel;
        vLightCameraOrthographicMax = XMVectorFloor( vLightCameraOrthographicMax );
        vLightCameraOrthographicMax *= vWorldUnitsPerTexel;

O valor vWorldUnitsPerTexel é calculado tomando um limite do frusto de exibição e dividindo pelo tamanho do buffer.

        FLOAT fWorldUnitsPerTexel = fCascadeBound /
        (float)m_CopyOfCascadeConfig.m_iBufferSize;
        vWorldUnitsPerTexel = XMVectorSet( fWorldUnitsPerTexel, fWorldUnitsPerTexel,                            0.0f, 0.0f );

Alimitação do tamanho máximo do frusto de exibição resulta em um ajuste mais flexível para a projeção ortográfica.

É importante observar que a textura é 1 pixel maior em largura e altura ao usar essa técnica. Isso impede que as coordenadas de sombra de indexação fora do mapa de sombra.

Face traseira e face frontal

Os mapas de sombra devem ser renderizados com o abate padrão do back-face, um processo que ignora a rasterização de objetos que o visualizador não pode ver e acelera a renderização da cena. Outra opção comum é renderizar mapas de sombra com o abate frontal habilitado, o que significa que os objetos voltados para o visualizador são eliminados. O argumento para isso é que ele ajuda com o auto-sombreamento, pois a geometria que compõe a parte de trás dos objetos é ligeiramente deslocada. Há dois problemas com essa ideia.

  • Qualquer objeto com geometria de rosto frontal ou de rosto traseiro inadequado causa artefatos no mapa de sombra. No entanto, ter geometria frontal ou traseira incorreta causará outros problemas, portanto, pode ser seguro assumir que a geometria frontal e traseira é feita corretamente. Pode ser impraticável criar faces traseiras para geometria baseada em sprite, como folhagem.
  • Peter Panning e lacunas de sombra perto da base de objetos como paredes são mais propensos a ocorrer porque a disparidade de profundidade da sombra é muito pequena.

Mapa de Sombra – Geometria Amigável

Criar geometria que funciona bem em mapas de sombra permite mais flexibilidade ao combater artefatos como Peter Panning e acne de sombra.

Bordas duras são problemáticas para o auto-sombreamento. A disparidade de profundidade perto da ponta da borda é muito pequena. Mesmo um pequeno deslocamento pode fazer com que os objetos percam suas sombras (Figura 18).

Figura 18. Bordas afiadas causam artefatos decorrentes de disparidade de baixa profundidade com deslocamentos

bordas afiadas causam artefatos decorrentes da disparidade de baixa profundidade com deslocamentos

Objetos estreitos, como paredes, devem ter costas mesmo que nunca estejam visíveis. Isso aumentará a disparidade de profundidade.

Também é importante garantir que a direção que a geometria está voltada esteja correta; ou seja, o lado de fora de um objeto deve estar voltado para trás e o interior de um objeto deve estar voltado para a frente. Isso é importante para renderizar com o abate de face traseira habilitado, bem como para combater os efeitos do viés de profundidade.

Resumo

As técnicas descritas neste artigo podem ser usadas para aumentar a qualidade dos mapas de sombra padrão. A próxima etapa é examinar técnicas que podem funcionar bem com mapas de sombra padrão. Os CSMs são recomendados como uma técnica superior para combater o aliasing de perspectiva. Mapas de sombra de variância ou filtragem mais próximos percentuais podem ser usados para suavizar bordas de sombra. Consulte o artigo técnico mapas de sombra em cascata para obter mais informações.

Donnelly, W., e Lauritzen, A. Variance Shadow Maps. Simpósio em Elementos Gráficos Interativos 3D, Proceedings of the 2006 Symposium on Interactive 3D Graphics and Games. 2006, pp. 161 a 165.

Engel, Woflgang F. Seção 4. Mapas de sombra em cascata. ShaderX5, Advanced Rendering Techniques, Wolfgang F. Engel, Ed. Charles River Media, Boston, Massachusetts. 2006. pp. 197–206.

Stamminger, Marc e Drettakis, George. Mapas de Sombras de Perspectiva. Conferência Internacional sobre Computação Gráfica e Técnicas Interativas, Procedimentos da 29ª Conferência Anual sobre Computação Gráfica e Técnicas Interativas. 2002, pp 557–562.

Wimmer, M., Scherzer, D., e Purgathofer, W. Light Space Perspective Shadow Maps. Simpósio eurográfico na renderização. 2004. Revisado em 10 de junho de 2005. Technische Universität Wien.