Neblina de Pixel (Direct3D 9)

A neblina de pixel obtém seu nome pelo fato de ser calculado por pixel no driver do dispositivo. Isso é diferente da neblina de vértice, que é calculada pelo pipeline durante cálculos de transformação e iluminação. Às vezes, a neblina de pixels é chamada de neblina de tabela porque alguns drivers usam uma tabela de pesquisa pré-calculada para determinar o fator de neblina, usando a profundidade de cada pixel a ser aplicada na combinação de cálculos. Ele pode ser aplicado usando qualquer fórmula de neblina identificada por membros do tipo enumerado D3DFOGMODE . As implementações dessas fórmulas são específicas do driver. Se um driver não oferecer suporte a uma fórmula de neblina complexa, ele deverá ser degradado para uma fórmula menos complexa.

profundidade baseada em Eye-Relative versus Z

Para aliviar artefatos gráficos relacionados à neblina causados pela distribuição desigual de valores z em um buffer de profundidade, a maioria dos dispositivos de hardware usa a profundidade relativa dos olhos em vez de valores de profundidade baseados em z para neblina de pixel. A profundidade relativa aos olhos é essencialmente o elemento w de um conjunto de coordenadas homogêneas. O Microsoft Direct3D usa a recíproca do elemento RHW de um conjunto de coordenadas de espaço do dispositivo para reproduzir true w. Se um dispositivo oferecer suporte à neblina relativa aos olhos, ele definirá o sinalizador D3DPRASTERCAPS_WFOG no membro RasterCaps da estrutura D3DCAPS9 quando você chamar o método IDirect3DDevice9::GetDeviceCaps . Com exceção do rasterizador de referência, os dispositivos de software sempre usam z para calcular efeitos de neblina de pixel.

Quando há suporte para a neblina relativa aos olhos, o sistema usa automaticamente a profundidade relativa dos olhos em vez da profundidade baseada em z se a matriz de projeção fornecida produzir valores z no espaço mundial equivalentes a w-values no espaço do dispositivo. Defina a matriz de projeção chamando o método IDirect3DDevice9::SetTransform , usando o valor D3DTS_PROJECTION e passando uma estrutura D3DMATRIX que representa a matriz desejada. Se a matriz de projeção não estiver em conformidade com esse requisito, os efeitos de neblina não serão aplicados corretamente. Para obter detalhes sobre como produzir uma matriz em conformidade, consulte a Transformação de Projeção (Direct3D 9).

Direct3D usa matriz de projeção atual definida em seus cálculos de profundidade com base em w. Como resultado, um aplicativo deve definir uma matriz de projeção em conformidade para receber os recursos desejados baseados em w, mesmo que ele não use o pipeline de transformação Direct3D.

O Direct3D verifica a quarta coluna da matriz de projeção. Se os coeficientes forem [0,0,0,1] (para uma projeção de affine), o sistema usará valores de profundidade baseados em z para neblina. Nesse caso, você também deve especificar as distâncias inicial e final para efeitos de neblina lineares no espaço do dispositivo, que varia de 0,0 no ponto mais próximo ao usuário e 1,0 no ponto mais distante.

Usando o Pixel Fog

Use as etapas a seguir para habilitar a neblina de pixel em seu aplicativo.

  1. Habilite a mistura de neblina definindo o estado de renderização D3DRS_FOGENABLE como TRUE.
  2. Defina a cor de neblina desejada no estado de renderização D3DRS_FOGCOLOR.
  3. Escolha a fórmula de neblina a ser usada definindo o estado de renderização D3DRS_FOGTABLEMODE para o membro correspondente do tipo enumerado D3DFOGMODE .
  4. Defina os parâmetros de neblina conforme desejado para o modo de neblina selecionado nos estados de renderização associados. Isso inclui as distâncias inicial e final para neblina linear e densidade de neblina para o modo de neblina exponencial.

O exemplo a seguir mostra como essas etapas podem ser no código.

// For brevity, error values in this example are not checked 
//   after each call. A real-world application should check 
//   these values appropriately.
//
// For the purposes of this example, g_pDevice is a valid
//   pointer to an IDirect3DDevice9 interface.
void SetupPixelFog(DWORD Color, DWORD Mode)
{
    float Start   = 0.5f;    // For linear mode
    float End     = 0.8f;
    float Density = 0.66f;   // For exponential modes
 
    // Enable fog blending.
    g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
 
    // Set the fog color.
    g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
    
    // Set fog parameters.
    if( Mode == D3DFOG_LINEAR )
    {
        g_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
        g_pDevice->SetRenderState(D3DRS_FOGEND,   *(DWORD *)(&End));
    }
    else
    {
        g_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
    }

Alguns parâmetros de neblina são necessários como valores de ponto flutuante, embora o método IDirect3DDevice9::SetRenderState aceite apenas valores DWORD no segundo parâmetro. O exemplo anterior fornece os valores de ponto flutuante para IDirect3DDevice9::SetRenderState sem tradução de dados, lançando os endereços das variáveis de ponto flutuante como ponteiros DWORD e, em seguida, desreferenciando-os.

Tipos de neblina