Nebbia pixel (Direct3D 9)

La nebbia pixel ottiene il nome dal fatto che viene calcolato in base al pixel nel driver del dispositivo. Questo è diverso dalla nebbia dei vertici, calcolata dalla pipeline durante i calcoli di trasformazione e illuminazione. La nebbia pixel è talvolta chiamata nebbia di tabella perché alcuni driver usano una tabella di ricerca precalcolata per determinare il fattore di nebbia, usando la profondità di ogni pixel da applicare nei calcoli di fusione. Può essere applicato usando qualsiasi formula di nebbia identificata dai membri del tipo enumerato D3DFOGMODE . Le implementazioni di queste formule sono specifiche del driver. Se un conducente non supporta una formula di nebbia complessa, dovrebbe degradarsi a una formula meno complessa.

Eye-Relative e profondità basata su Z

Per alleviare gli artefatti grafici correlati alla nebbia causati da una distribuzione irregolare di valori z in un buffer di profondità, la maggior parte dei dispositivi hardware utilizza la profondità oculare invece dei valori di profondità basati su z per la nebbia dei pixel. La profondità relativa all'occhio è essenzialmente l'elemento w di un set di coordinate omogeneo. Microsoft Direct3D accetta il reciproco dell'elemento RHW da una coordinata dello spazio del dispositivo impostata per riprodurre true w. Se un dispositivo supporta la nebbia oculare, imposta il flag di D3DPRASTERCAPS_WFOG nel membro RasterCaps della struttura D3DCAPS9 quando si chiama il metodo IDirect3DDevice9::GetDeviceCaps . Ad eccezione del rasterizzatore di riferimento, i dispositivi software usano sempre z per calcolare gli effetti di nebbia pixel.

Quando è supportata la nebbia oculare, il sistema usa automaticamente la profondità relativa agli occhi anziché la profondità basata su z se la matrice di proiezione fornita produce valori z nello spazio mondiale equivalenti ai valori w-value nello spazio del dispositivo. È stata impostata la matrice di proiezione chiamando il metodo IDirect3DDevice9::SetTransform usando il valore D3DTS_PROJECTION e passando una struttura D3DMATRIX che rappresenta la matrice desiderata. Se la matrice di proiezione non è conforme a questo requisito, gli effetti della nebbia non vengono applicati correttamente. Per informazioni dettagliate sulla produzione di una matrice conforme, vedere Trasformazione di proiezione (Direct3D 9).

Direct3D usa la matrice di proiezione attualmente impostata nei calcoli di profondità basati su w. Di conseguenza, un'applicazione deve impostare una matrice di proiezione conforme per ricevere le funzionalità basate su w desiderate, anche se non usa la pipeline di trasformazione Direct3D.

Direct3D controlla la quarta colonna della matrice di proiezione. Se i coefficienti sono [0,0,0,1] (per una proiezione affine) il sistema userà valori di profondità basati su z per la nebbia. In questo caso, è necessario specificare anche le distanze di inizio e fine per effetti di nebbia lineare nello spazio del dispositivo, che varia da 0,0 al punto più vicino all'utente e 1,0 al punto più lontano.

Uso di Pixel Fog

Seguire questa procedura per abilitare la nebbia pixel nell'applicazione.

  1. Abilitare la fusione della nebbia impostando lo stato di rendering D3DRS_FOGENABLE su TRUE.
  2. Impostare il colore di nebbia desiderato nello stato di rendering D3DRS_FOGCOLOR.
  3. Scegliere la formula di nebbia da usare impostando lo stato di rendering D3DRS_FOGTABLEMODE sul membro corrispondente del tipo enumerato D3DFOGMODE .
  4. Impostare i parametri di nebbia come desiderato per la modalità nebbia selezionata negli stati di rendering associati. Ciò include le distanze di inizio e fine per la nebbia lineare e la densità di nebbia per la modalità nebbia esponenziale.

Nell'esempio seguente viene illustrato il aspetto di questi passaggi nel codice.

// 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));
    }

Alcuni parametri fog sono necessari come valori a virgola mobile, anche se il metodo IDirect3DDevice9::SetRenderState accetta solo valori DWORD nel secondo parametro. L'esempio precedente fornisce i valori a virgola mobile a IDirect3DDevice9::SetRenderState senza conversione dei dati eseguendo il cast degli indirizzi delle variabili a virgola mobile come puntatori DWORD e quindi dereferenziandoli.

Tipi di nebbia