Neblina de Pixel (Direct3D 9)

A neblina de pixel obtém seu nome do fato de que ele é calculado por pixel no driver do dispositivo. Isso é diferente da neblina de vértice, que é calculada pelo pipeline durante os cálculos de transformação e iluminação. Às vezes, a neblina de pixel é 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 para aplicar em cálculos de mesclagem. 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 der 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 irregular de valores z em um buffer de profundidade, a maioria dos dispositivos de hardware usa profundidade relativa aos 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 der 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 aos 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. Você define 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 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 w desejados, 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 afim), 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 a neblina de pixel

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

  1. Habilite a mesclagem 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 convertendo os endereços das variáveis de ponto flutuante como ponteiros DWORD e, em seguida, desreferenciando-os.

Tipos de neblina