Dela via


Hörndimma (Direct3D 9)

När systemet utför hörnfogging tillämpar det dimberäkningar vid varje hörn i en polygon och interpolerar sedan resultaten över polygonens ansikte under rastreringen. Hörndimmaeffekter beräknas av Direct3D-belysnings- och transformeringsmotorn. Mer information finns i Fog Parameters (Direct3D 9).

Om programmet inte använder Direct3D för omvandling och belysning måste programmet utföra dimberäkningar. I det här fallet placerar du den dimfaktor som beräknas i alfakomponenten i den spektulära färgen för varje hörn. Du kan använda de formler du vill ha – intervallbaserad, volymtrisk eller på annat sätt. Direct3D använder den angivna dimfaktorn för att interpolera över ansiktet på varje polygon. Program som utför sin egen omvandling och belysning måste också utföra sina egna hörndimmaberäkningar. Därför behöver ett sådant program bara aktivera dimblandning och ange dimfärgen genom de associerade återgivningstillstånden, enligt beskrivningen i Fog Blending (Direct3D 9) och Fog Color (Direct3D 9).

Not

När du använder en hörnskuggning måste du använda hörndimma. Detta uppnås med hjälp av hörnskuggningen för att skriva dimmans intensitet per hörn till oFog-registret. När pixelskuggningen är klar används oFog-data för att linjärt interpolera med dimfärgen. Den här intensiteten är inte tillgänglig i en pixelskuggning.

 

Range-Based Dimma

Not

Direct3D använder endast intervallbaserade dimberäkningar när du använder hörndimma med Direct3D-transformerings- och belysningsmotorn. Det beror på att pixeldimma implementeras i enhetsdrivrutinen och det för närvarande inte finns någon maskinvara som stöder intervallbaserad dimma per pixel. Om programmet utför sin egen omvandling och belysning måste det utföra sina egna dimberäkningar, intervallbaserade eller på annat sätt.

 

Ibland kan användning av dimma introducera grafiska artefakter som gör att objekt blandas med dimfärgen på icke-intuitiva sätt. Tänk dig till exempel en scen där det finns två synliga objekt: en tillräckligt avlägsen för att påverkas av dimma och den andra tillräckligt nära för att inte påverkas. Om visningsområdet roterar på plats kan de uppenbara dimeffekterna ändras, även om objekten är stationära. Följande diagram visar en vy uppifrån och ned av en sådan situation.

diagram över två synpunkter och hur de påverkar dimma för två objekt

Intervallbaserad dimma är ett annat, mer exakt, sätt att fastställa dimmans effekter. I intervallbaserad dimma använder Direct3D det faktiska avståndet från synpunkt till ett hörn för dess dimberäkningar. Direct3D ökar effekten av dimma när avståndet mellan de två punkterna ökar, snarare än djupet av hörnen i scenen, vilket undviker rotationsartefakter.

Om den aktuella enheten stöder intervallbaserad dimma anger den värdet D3DPRASTERCAPS_FOGRANGE i RasterCaps-medlemmen i D3DCAPS9 när du anropar metoden IDirect3DDevice9::GetDeviceCaps. Om du vill aktivera intervallbaserad dimma anger du återgivningstillståndet för D3DRS_RANGEFOGENABLE till TRUE.

Intervallbaserad dimma beräknas av Direct3D under omvandling och belysning. Program som inte använder Direct3D-transformerings- och belysningsmotorn måste också utföra sina egna hörndimmaberäkningar. I det här fallet anger du den intervallbaserade dimmafaktorn i alfakomponenten i den spektulära komponenten för varje hörn.

Använda hörndimma

Använd följande steg för att aktivera hörndimma i programmet.

  1. Aktivera blandning av dimma genom att ange D3DRS_FOGENABLE till TRUE.
  2. Ange dimfärgen i D3DRS_FOGCOLOR återgivningstillstånd.
  3. Välj önskad dimformel genom att ange D3DRS_FOGVERTEXMODE återgivningstillståndet till en medlem av den D3DFOGMODE uppräknade typen.
  4. Ange dimmaparametrarna som du vill för den valda dimformeln i återgivningstillstånden.

I följande exempel, skrivet i C++, visas hur de här stegen kan se ut i kod.

// 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 SetupVertexFog(DWORD Color, DWORD Mode, BOOL UseRange, FLOAT Density)
{
    float Start = 0.5f,    // Linear fog distances
          End   = 0.8f;
 
    // Enable fog blending.
    g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
 
    // Set the fog color.
    g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
    
    // Set fog parameters.
    if(D3DFOG_LINEAR == Mode)
    {
        g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
        g_pDevice->SetRenderState(D3DRS_FOGEND,   *(DWORD *)(&End));
    }
    else
    {
        g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
        g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
    }

    // Enable range-based fog if desired (only supported for
    //   vertex fog). For this example, it is assumed that UseRange
    //   is set to a nonzero value only if the driver exposes the 
    //   D3DPRASTERCAPS_FOGRANGE capability.
    // Note: This is slightly more performance intensive
    //   than non-range-based fog.
    if(UseRange)
        g_pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
}

Vissa dimparametrar krävs som flyttalsvärden, även om metoden IDirect3DDevice9::SetRenderState endast accepterar DWORD-värden i den andra parametern. Det här exemplet tillhandahåller flyttalsvärdena till dessa metoder utan dataöversättning genom att ange adresserna för flyttalsvariablerna som DWORD-pekare och sedan dereferera dem.