Buffers de estêncil

Um buffer de estêncil é usado para mascarar pixels em uma imagem para produzir efeitos especiais. A máscara controla se o pixel é desenhado ou não. Esses efeitos especiais incluem composição, decalque, desintegração, desvanecimento e passagem de dedo, contornos e silhuetas e estêncil de dois lados. Alguns dos efeitos mais comuns são mostrados a seguir.

O buffer de estêncil habilita ou desabilita o desenho na superfície de destino de renderização pixel a pixel. No seu nível mais fundamental, ele permite que os aplicativos mascarem seções da imagem renderizada para que elas não sejam exibidas. Os aplicativos geralmente usam buffers de estêncil para efeitos especiais, como desintegração, decalque e contornos.

As informações do buffer de estêncil são incorporadas nos dados do buffer z.

Como o buffer de estêncil funciona

O Direct3D executa um teste no conteúdo do buffer de estêncil pixel a pixel. Para cada pixel na superfície de destino, ele executa um teste usando o valor correspondente no buffer de estêncil, um valor de referência de estêncil e um valor de máscara de estêncil. Se o teste for aprovado, o Direct3D executará uma ação. O teste é realizado por meio das etapas a seguir.

  1. Execute uma operação AND bit a bit do valor de referência do estêncil com a máscara de estêncil.
  2. Execute uma operação AND bit a bit do valor do buffer de estêncil para o pixel Atual com a máscara de estêncil.
  3. Compare o resultado da etapa 1 com o resultado da etapa 2, utilizando a função de comparação.

As etapas acima são mostradas na seguinte linha de código:

(StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)
  • StencilRef representa o valor de referência do estêncil.
  • StencilMask representa o valor da máscara do estêncil.
  • CompFunc é a função de comparação.
  • StencilBufferValue é o conteúdo do buffer de estêncil para o pixel atual.
  • O símbolo E comercial (&) representa a operação AND bit a bit.

O pixel atual será gravado na superfície de destino se o teste de estêncil for aprovado e será ignorado, caso contrário. O comportamento de comparação padrão é gravar o pixel, não importa como cada operação bit a bit resulte. Você pode alterar esse comportamento mudando o valor de um tipo enumerado para identificar a função de comparação desejada.

Seu aplicativo pode personalizar a operação do buffer de estêncil. Ele pode definir a função de comparação, a máscara de estêncil e o valor de referência do estêncil. Ele também pode controlar a ação que o Direct3D executa quando o teste de estêncil passa ou falha.

Composição

Seu aplicativo pode usar o buffer de estêncil para compor imagens 2D ou 3D em uma cena 3D. Uma máscara no buffer de estêncil é usada para ocluir uma área da superfície de destino de renderização. As informações 2D armazenadas, como texto ou bitmaps, podem ser gravadas na área ocluída. Como alternativa, seu aplicativo pode renderizar primitivas 3D adicionais para a região mascarada por estêncil da superfície de destino de renderização. Ele pode até renderizar uma cena inteira.

Os jogos muitas vezes compõem várias cenas 3D juntas. Por exemplo, os jogos de corrida normalmente exibem um espelho retrovisor. O espelho contém a visão da cena 3D atrás do motorista. É essencialmente uma segunda cena 3D composta com a visão frontal do motorista.

Decalque

Os aplicativos Direct3D usam decalque para controlar quais pixels de uma determinada imagem de primitiva são desenhados para a superfície de destino de renderização. Os aplicativos aplicam decalques às imagens de primitivas para permitir que os polígonos coplanares sejam renderizados corretamente.

Por exemplo, ao aplicar marcas de pneus e linhas amarelas em uma estrada, as marcações devem aparecer diretamente em cima da estrada. No entanto, os valores z das marcações e da estrada são os mesmos. Portanto, o buffer de profundidade pode não produzir uma separação limpa entre os dois. Alguns pixels da primitiva traseira podem ser renderizados na parte superior da primitiva frontal e vice-versa. A imagem resultante parece cintilar de quadro para quadro. Esse efeito é denominado z-fighting ou flimmering.

Para resolver esse problema, use um estêncil para mascarar a seção da primitiva traseira na qual o decalque aparecerá. Desative o buffer z e renderize a imagem da primitiva frontal na área mascarada da superfície de destino de renderização.

Embora a mistura de várias texturas possa ser usada para resolver esse problema, isso limita o número de outros efeitos especiais que o aplicativo pode produzir. Usar o buffer de estêncil para aplicar decalques libera estágios de combinação de textura para outros efeitos.

Desintegrações, desvanecimentos e passagens do dedo

Cada vez mais, os aplicativos empregam efeitos especiais que são comumente usados em filmes e vídeos, como desintegrações, desvanecimentos e passagens do dedo.

Em uma desintegração, uma imagem é gradualmente substituída por outra em uma sequência suave de quadros. Embora o Direct3D forneça métodos de usar a combinação de várias texturas para obter o mesmo efeito, os aplicativos que usam o buffer de estêncil para desintegrações podem usar recursos de combinação de textura para outros efeitos enquanto fazem uma desintegração.

Quando o aplicativo executa uma desintegração, ele deve renderizar duas imagens diferentes. Ele usa o buffer de estêncil para controlar quais pixels de cada imagem são desenhados para a superfície de destino de renderização. Você pode definir uma série de máscaras de estêncil e copiá-las para o buffer de estêncil em quadros sucessivos. Como alternativa, você pode definir uma máscara de estêncil básica para o primeiro quadro e alterá-la incrementalmente.

No início da desintegraçã, o aplicativo define a função de estêncil e a máscara de estêncil para que a maioria dos pixels da imagem inicial passe no teste de estêncil. A maioria dos pixels da imagem final deve falhar no teste de estêncil. Em quadros sucessivos, a máscara de estêncil é atualizada para que cada vez menos pixels da imagem inicial passem no teste. À medida que os quadros progridem, cada vez menos pixels da imagem final falham no teste. Dessa maneira, o aplicativo pode executar uma desintegração usando um padrão de desintegração arbitrária.

Abertura ou encerramento gradual são casos especiais de desintegração. Na abertura gradual, o buffer de estêncil é usado para desintegrar uma imagem em preto ou branco para uma renderização de uma cena 3D. Encerramento gradual é o oposto, o aplicativo começa com uma renderização de uma cena 3D e desintegra para preto ou branco. O desvanecimento pode ser feito usando um padrão arbitrário que você queira empregar.

Os aplicativos Direct3D usam uma técnica semelhante para passagens do dedo. Por exemplo, quando um aplicativo executa um gesto de passagem do dedo da esquerda para a direita, a imagem final parece deslizar gradualmente sobre a imagem inicial da esquerda para a direita. Como em uma desintegração, você deve definir uma série de máscaras de estêncil que são carregadas no buffer de estêncil em quadros sucessivos ou modificar sucessivamente a máscara de estêncil inicial. As máscaras de estêncil são usadas para desabilitar a gravação de pixels da imagem inicial e para habilitar a gravação de pixels da imagem final.

Uma passagem do dedo é um pouco mais complexa do que uma desintegração, pois o aplicativo tem de ler os píxeis da imagem final na ordem inversa da passagem do dedo. Ou seja, se a passagem do dedo se mover da esquerda para a direita, o aplicativo terá de ler os píxeis da imagem final da direita para a esquerda.

Contornos e silhuetas

Você pode usar o buffer de estêncil para efeitos mais abstratos, como contornos e silhuetas.

Se o aplicativo aplicar uma máscara de estêncil à imagem de uma primitiva que tenha a mesma forma, mas um pouco menor, a imagem resultante conterá apenas o contorno da primitiva. O aplicativo pode preencher a área mascarada por estêncil da imagem com uma cor sólida, dando à primitiva uma aparência em alto-relevo.

Se a máscara de estêncil tiver mesmos tamanho e forma que a primitiva que você está renderizando, a imagem resultante conterá um espaço onde a primitiva deverá estar. O aplicativo pode preencher o espaço com preto para produzir uma silhueta da primitiva.

Estêncil de dois lados

Os volumes de sombra são usados para desenhar sombras com o buffer de estêncil. O aplicativo calcula os volumes de sombra lançados pela geometria de oclusão ao calcular as bordas da silhueta e lançá-las para longe da luz para um conjunto de volumes 3D. Esses volumes são renderizados duas vezes no buffer de estêncil.

A primeira renderização desenha polígonos frontais e incrementa os valores do buffer de estêncil. A segunda renderização desenha os polígonos traseiros do volume de sombra e diminui os valores do buffer de estêncil. Normalmente, todos os valores incrementados e diminuídos se anulam. No entanto, a cena já foi renderizada com geometria normal, fazendo com que alguns pixels falhem no teste de buffer z à medida que o volume de sombra é renderizado. Os valores deixados no buffer de estêncil correspondem aos pixels que estão na sombra. Esse conteúdo remanescente do buffer de estêncil é usado como uma máscara, para fazer uma combinação alfa de um grande e abrangente quadrupleto preto na cena. Com o buffer de estêncil agindo como uma máscara, o resultado é o escurecimento dos pixels que estão nas sombras.

Isso significa que a geometria da sombra é desenhada duas vezes por fonte de luz, pressionando a produtividade do vértice da GPU. O recurso de estêncil de dois lados foi projetado para mitigar essa situação. Nessa abordagem, existem dois conjuntos de estado de estêncil (nomeados abaixo), um conjunto cada para os triângulos frontais e o outro para os triângulos traseiros. Dessa forma, apenas uma única passagem é desenhada por volume de sombra, por luz.

Buffers de profundidade e estêncil