Técnicas de buffer de estêncil (Direct3D 9)

Os aplicativos usam o buffer de estêncil para mascarar pixels em uma imagem. A máscara controla se o pixel é desenhado ou não. Alguns dos efeitos mais comuns são mostrados abaixo.

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

Informações de buffer de estêncil são incorporadas nos dados do buffer z. Seu aplicativo pode usar o método IDirect3D9::CheckDeviceFormat para marcar para suporte ao estêncil de hardware, conforme mostrado no exemplo de código a seguir.

// Reject devices that cannot perform 8-bit stencil buffering. 
// The following example assumes that pCaps is a valid pointer 
// to an initialized D3DCAPS9 structure. 

if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
                                       pCaps->DeviceType,  
                                       Format,  
                                       D3DUSAGE_DEPTHSTENCIL, 
                                       D3DRTYPE_SURFACE,
                                       D3DFMT_D24S8 ) ) )
return E_FAIL;

IDirect3D9::CheckDeviceFormat permite que você escolha um dispositivo para criar com base nos recursos desse dispositivo. Nesse caso, os dispositivos que não dão suporte a buffers de estêncil de 8 bits são rejeitados. Observe que este é apenas um uso possível para IDirect3D9::CheckDeviceFormat; para obter detalhes, consulte Determinando o suporte a hardware (Direct3D 9).

Como funciona o buffer de estêncil

O Direct3D realiza um teste no conteúdo do buffer de estêncil em uma base de pixel por pixel. Para cada pixel na superfície do 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 executa uma ação. O teste é realizado usando as seguintes etapas.

  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 de buffer do estêncil do pixel atual com a máscara de estêncil.
  3. Compare o resultado da etapa 1 com o resultado da etapa 2, usando a função de comparação.

Essas etapas são mostradas no exemplo de código a seguir.

(StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)
StencilBufferValue

é o conteúdo do buffer de estêncil para o pixel atual. Este exemplo de código usa o símbolo de e comercial (&) para representar a operação AND bit a bit.

StencilMask

representa o valor da máscara de estêncil e

StencilRef

representa o valor de referência do estêncil.

CompFunc

é a função de comparação.

O pixel atual é escrito na superfície de destino se o teste de estêncil for aprovado, caso contrário, é ignorado. O comportamento de comparação padrão é gravar o pixel, não importa como cada operação bit a bit seja (D3DCMP_ALWAYS). Você pode alterar esse comportamento alterando o valor da D3DRS_STENCILFUNC estado de renderização, passando um membro do tipo enumerado D3DCMPFUNC 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 de estêncil. Ele também pode controlar a ação que o Direct3D executa quando o teste de estêncil passa ou falha. Para obter mais informações, consulte Estado do buffer de estêncil (Direct3D 9).

Exemplos

Os exemplos de código a seguir demonstram a configuração do buffer de estêncil.

// Enable stencil testing
pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);

// Specify the stencil comparison function
pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);

// Set the comparison reference value
pDevice->SetRenderState(D3DRS_STENCILREF, 0);

//  Specify a stencil mask 
pDevice->SetRenderState(D3DRS_STENCILMASK, 0);

Por padrão, o valor de referência do estêncil é zero. Qualquer valor inteiro é válido. O Direct3D executa um AND bit a bit do valor de referência do estêncil e um valor de máscara de estêncil antes do teste de estêncil.

Você pode controlar quais informações de pixel são gravadas dependendo da comparação de estêncil.

// A write mask controls what is written
pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, D3DSTENCILOP_KEEP);
// Specify when to write stencil data
pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);

Você pode escrever sua própria fórmula para o valor desejado gravado no buffer de estêncil, conforme mostrado no exemplo a seguir.

NewStencilBufferValue = (StencilBufferValue & ~StencilWriteMask) | 
                        (StencilWriteMask & StencilOp(StencilBufferValue))

Pixel Pipeline