Névoa de pixel (Direct3D 9)
Pixel fog recebe seu nome do fato de que ele é calculado em uma base por pixel no driver de dispositivo. Isso é diferente da névoa de vértice, que é calculada pela tubulação durante os cálculos de transformação e iluminação. A névoa de pixel às vezes é chamada de névoa 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 mistura. Ele pode ser aplicado usando qualquer fórmula de névoa identificada por membros do D3DFOGMODE tipo enumerado. As implementações dessas fórmulas são específicas do driver. Se um condutor não suportar uma fórmula de nevoeiro complexa, esta deve degradar-se para uma fórmula menos complexa.
Eye-Relative vs. profundidade baseada em Z
Para aliviar artefatos gráficos relacionados à névoa causados pela distribuição desigual 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 névoa de pixel. A profundidade relativa aos olhos é essencialmente o elemento w de um conjunto de coordenadas homogêneo. O Microsoft Direct3D obtém a recíproca do elemento RHW de um conjunto de coordenadas de espaço de dispositivo para reproduzir true w. Se um dispositivo suportar névoa relativa aos olhos, ele definirá o sinalizador de D3DPRASTERCAPS_WFOG no membro RasterCaps da estrutura D3DCAPS9 quando você chamar o IDirect3DDevice9::GetDeviceCaps método. Com exceção do rasterizador de referência, os dispositivos de software sempre usam z para calcular os efeitos de névoa de pixel.
Quando a névoa relativa aos olhos é suportada, 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 que são equivalentes aos valores w no espaço do dispositivo. Você define a matriz de projeção chamando o IDirect3DDevice9::SetTransform método, 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 este requisito, os efeitos de nevoeiro não são aplicados corretamente. Para obter detalhes sobre como produzir uma matriz compatível, consulte Projection Transform (Direct3D 9).
O Direct3D usa a matriz de projeção atualmente definida em seus cálculos de profundidade baseados em w. Como resultado, um aplicativo deve definir uma matriz de projeção compatível para receber os recursos baseados em w desejados, mesmo que 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 afim), o sistema utilizará valores de profundidade baseados em z para nevoeiro. Nesse caso, você também deve especificar as distâncias de início e fim para efeitos de névoa linear no espaço do dispositivo, que varia de 0,0 no ponto mais próximo do usuário e 1,0 no ponto mais distante.
Usando o Pixel Fog
Use as etapas a seguir para habilitar a névoa de pixel em seu aplicativo.
- Habilite a mistura de névoa definindo o estado de renderização D3DRS_FOGENABLE como TRUE.
- Defina a cor de névoa desejada no estado de renderização D3DRS_FOGCOLOR.
- Escolha a fórmula de névoa a ser usada definindo o estado de renderização de D3DRS_FOGTABLEMODE para o membro correspondente do tipo D3DFOGMODE enumerado.
- Defina os parâmetros de névoa conforme desejado para o modo de névoa selecionado nos estados de renderização associados. Isto inclui as distâncias de início e fim para o nevoeiro linear e a densidade do nevoeiro para o modo de nevoeiro exponencial.
O exemplo a seguir mostra como essas etapas podem parecer 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 névoa são necessários como valores de ponto flutuante, mesmo que 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 conversão de dados, convertendo os endereços das variáveis de ponto flutuante como ponteiros DWORD e, em seguida, desreferenciando-os.
Tópicos relacionados