Introdução com o Estágio do Rasterizador
Esta seção descreve como definir o visor, o retângulo da tesoura, o estado do rasterizador e a amostragem múltipla.
Definir o Visor
Um visor mapeia posições de vértice (no espaço de clipe) em posições de destino de renderização. Esta etapa dimensiona as posições 3D em espaço 2D. Um destino de renderização é orientado com os eixos Y apontando para baixo; isso requer que as coordenadas Y sejam invertidas durante a escala do visor. Além disso, as extensões x e y (intervalo dos valores x e y) são dimensionadas para se ajustarem ao tamanho do visor de acordo com as seguintes fórmulas:
X = (X + 1) * Viewport.Width * 0.5 + Viewport.TopLeftX
Y = (1 - Y) * Viewport.Height * 0.5 + Viewport.TopLeftY
Z = Viewport.MinDepth + Z * (Viewport.MaxDepth - Viewport.MinDepth)
O Tutorial 1 cria um visor 640 × 480 usando D3D11_VIEWPORT e chamando ID3D11DeviceContext::RSSetViewports.
D3D11_VIEWPORT vp[1];
vp[0].Width = 640.0f;
vp[0].Height = 480.0f;
vp[0].MinDepth = 0;
vp[0].MaxDepth = 1;
vp[0].TopLeftX = 0;
vp[0].TopLeftY = 0;
g_pd3dContext->RSSetViewports( 1, vp );
A descrição do visor especifica o tamanho do visor, o intervalo para o qual mapear a profundidade (usando MinDepth e MaxDepth) e o posicionamento da parte superior esquerda do visor. MinDepth deve ser menor ou igual a MaxDepth; O intervalo para MinDepth e MaxDepth está entre 0,0 e 1,0, inclusive. É comum que o visor seja mapeado para um destino de renderização, mas não é necessário; além disso, o visor não precisa ter o mesmo tamanho ou posição que o destino de renderização.
Você pode criar uma matriz de visores, mas apenas um pode ser aplicado a uma saída primitiva do sombreador de geometria. Somente um visor pode ser definido como ativo por vez. O pipeline usa um visor padrão (e um retângulo de tesoura, discutidos na próxima seção) durante a rasterização. O padrão é sempre o primeiro visor (ou retângulo de tesoura) na matriz. Para executar uma seleção por primitiva do visor no sombreador de geometria, especifique a semântica ViewportArrayIndex no componente de saída GS apropriado na declaração de assinatura de saída GS.
O número máximo de visores (e retângulos de tesoura) que podem ser associados ao estágio do rasterizador a qualquer momento é 16 (especificado por D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE).
Definir o Retângulo de Tesoura
Um retângulo de tesoura oferece outra oportunidade para reduzir o número de pixels que serão enviados para o estágio de fusão de saída. Pixels fora do retângulo da tesoura são descartados. O tamanho do retângulo da tesoura é especificado em inteiros. Somente um retângulo de tesoura (com base em ViewportArrayIndex na semântica de valor do sistema) pode ser aplicado a um triângulo durante a rasterização.
Para habilitar o retângulo da tesoura, use o membro ScissorEnable (em D3D11_RASTERIZER_DESC1). O retângulo da tesoura padrão é um retângulo vazio; ou seja, todos os valores de rect são 0. Em outras palavras, se você não configurar o retângulo de tesoura e a tesoura estiver habilitada, você não enviará nenhum pixel para o estágio de fusão de saída. A configuração mais comum é inicializar o retângulo de tesoura para o tamanho do visor.
Para definir uma matriz de retângulos de tesoura para o dispositivo, chame ID3D11DeviceContext::RSSetScissorRects com D3D11_RECT.
D3D11_RECT rects[1];
rects[0].left = 0;
rects[0].right = 640;
rects[0].top = 0;
rects[0].bottom = 480;
g_pd3dContext->RSSetScissorRects( 1, rects );
Esse método usa dois parâmetros: (1) o número de retângulos na matriz e (2) uma matriz de retângulos.
O pipeline usa um índice de retângulo de tesoura padrão durante a rasterização (o padrão é um retângulo de tamanho zero com recorte desabilitado). Para substituir isso, especifique a semântica SV_ViewportArrayIndex para um componente de saída GS na declaração de assinatura de saída GS. Isso fará com que o estágio GS marque esse componente de saída GS como um componente gerado pelo sistema com essa semântica. O estágio do rasterizador reconhece essa semântica e usará o parâmetro ao qual está anexado como o índice do retângulo de tesoura para acessar a matriz de retângulos de tesoura. Não se esqueça de dizer ao estágio do rasterizador para usar o retângulo de tesoura que você define habilitando o valor ScissorEnable na descrição do rasterizador antes de criar o objeto rasterizador.
Definir estado do rasterizador
A partir do Direct3D 10, o estado do rasterizador é encapsulado em um objeto de estado de rasterizador. Você pode criar até 4096 objetos de estado de rasterizador que podem ser definidos para o dispositivo passando um identificador para o objeto de estado.
Use ID3D11Device1::CreateRasterizerState1 para criar um objeto de estado do rasterizador de uma descrição do rasterizador (consulte D3D11_RASTERIZER_DESC1).
ID3D11RasterizerState1 * g_pRasterState;
D3D11_RASTERIZER_DESC1 rasterizerState;
rasterizerState.FillMode = D3D11_FILL_SOLID;
rasterizerState.CullMode = D3D11_CULL_FRONT;
rasterizerState.FrontCounterClockwise = true;
rasterizerState.DepthBias = false;
rasterizerState.DepthBiasClamp = 0;
rasterizerState.SlopeScaledDepthBias = 0;
rasterizerState.DepthClipEnable = true;
rasterizerState.ScissorEnable = true;
rasterizerState.MultisampleEnable = false;
rasterizerState.AntialiasedLineEnable = false;
rasterizerState.ForcedSampleCount = 0;
g_pd3dDevice->CreateRasterizerState1( &rasterizerState, &g_pRasterState );
Este conjunto de exemplo de estado realiza talvez a configuração mais básica do rasterizador:
- Modo de preenchimento sólido
- Eliminar ou remover faces traseiras; pressupor ordem de enrolamento no sentido anti-horário para primitivos
- Desativar o desvio de profundidade, mas habilitar o buffer de profundidade e habilitar o retângulo da tesoura
- Desativar a multisampling e o anti-aliasing de linha
Além disso, as operações básicas de rasterizador sempre incluem o seguinte: recorte (para o frusto de exibição), divisão de perspectiva e escala do visor. Depois de criar com êxito o objeto de estado do rasterizador, defina-o como o dispositivo desta forma:
g_pd3dContext->RSSetState(g_pRasterState);
Amostragem múltipla
O multisampling amostra alguns ou todos os componentes de uma imagem em uma resolução mais alta (seguido de redução para a resolução original) para reduzir a forma mais visível de aliasing causada pelo desenho de bordas de polígono. Embora a multiamostragem exija amostras de sub pixel, as GPUs modernas implementam várias amostras para que um sombreador de pixel seja executado uma vez por pixel. Isso fornece uma compensação aceitável entre o desempenho (especialmente em um aplicativo associado à GPU) e o anti-alias da imagem final.
Para usar várias amostras, defina o campo habilitar na descrição da rasterização, crie um destino de renderização com várias amostras e leia o destino de renderização com um sombreador para resolve os exemplos em uma única cor de pixel ou chame ID3D11DeviceContext::ResolveSubresource para resolve os exemplos usando o vídeo cartão. O cenário mais comum é desenhar para um ou mais destinos de renderização multisampled.
A multiamostragem é independente se uma máscara de exemplo é usada ou não, se a cobertura alfa está habilitada ou operações de estêncil (que são sempre executadas por amostra).
O teste de profundidade é afetado por várias amostras:
- Quando o multisampling está habilitado, a profundidade é interpolada por amostra e o teste de profundidade/estêncil é feito por amostra; a cor de saída do sombreador de pixel é duplicada para todas as amostras que passam. Se o sombreador de pixel gerar profundidade, o valor de profundidade será duplicado para todas as amostras (embora esse cenário perca o benefício da multiamostragem).
- Quando a multiamostragem está desabilitada, o teste de profundidade/estêncil ainda é feito por amostra, mas a profundidade não é interpolada por amostra.
Não há restrições para misturar renderização multisampled e não multisampled em um único destino de renderização. Se você habilitar a multiamostragem e desenhar em um destino de renderização não multiplataforma, produzirá o mesmo resultado que se o multisampling não estivesse habilitado; A amostragem é feita com uma única amostra por pixel.
Tópicos relacionados