Pixeldimma (Direct3D 9)
Pixeldimma hämtar sitt namn från det faktum att det beräknas per pixel i enhetsdrivrutinen. Detta skiljer sig från hörndimma, som beräknas av pipelinen under omvandlings- och belysningsberäkningar. Pixeldimma kallas ibland för tabelldimma eftersom vissa drivrutiner använder en förberäknad uppslagstabell för att fastställa dimfaktorn, med hjälp av djupet för varje pixel för att tillämpa i blandningsberäkningar. Den kan användas med hjälp av alla dimformler som identifieras av medlemmar av den D3DFOGMODE uppräknade typen. Implementeringarna av dessa formler är drivrutinsspecifika. Om en drivrutin inte stöder en komplex dimformel bör den degraderas till en mindre komplex formel.
Eye-Relative jämfört med Z-baserat djup
För att lindra dimrelaterade grafiska artefakter som orsakas av ojämn fördelning av z-värden i en djupbuffert använder de flesta maskinvaruenheter ögonrelativt djup i stället för z-baserade djupvärden för pixeldimma. Ögonrelativt djup är i huvudsak w-elementet från en homogen koordinatuppsättning. Microsoft Direct3D tar reciprocal för RHW-elementet från en koordinatuppsättning för enhetsutrymme för att återskapa true w. Om en enhet stöder ögonrelativ dimma anger den flaggan D3DPRASTERCAPS_WFOG i RasterCaps-medlemmen i D3DCAPS9-strukturen när du anropar metoden IDirect3DDevice9::GetDeviceCaps. Med undantag för referens rasterizern använder programvaruenheter alltid z för att beräkna pixeldimmaeffekter.
När ögonrelativ dimma stöds använder systemet automatiskt ögonrelativt djup i stället för z-baserat djup om den angivna projektionsmatrisen genererar z-värden i världsutrymmet som motsvarar w-värden i enhetsutrymmet. Du anger projektionsmatrisen genom att anropa metoden IDirect3DDevice9::SetTransform med hjälp av D3DTS_PROJECTION-värdet och skicka en D3DMATRIX struktur som representerar önskad matris. Om projektionsmatrisen inte är kompatibel med det här kravet tillämpas inte dimeffekter korrekt. Mer information om hur du skapar en kompatibel matris finns i Projection Transform (Direct3D 9).
Direct3D använder den för närvarande angivna projektionsmatrisen i sina w-baserade djupberäkningar. Därför måste ett program ange en kompatibel projektionsmatris för att ta emot önskade w-baserade funktioner, även om det inte använder Direct3D-transformeringspipelinen.
Direct3D kontrollerar den fjärde kolumnen i projektionsmatrisen. Om koefficienterna är [0,0,0,1] (för en affinprojektion) använder systemet z-baserade djupvärden för dimma. I det här fallet måste du också ange start- och slutavstånden för linjära dimmaeffekter i enhetsutrymmet, som sträcker sig från 0,0 vid närmaste punkt till användaren och 1,0 längst bort.
Använda pixeldimma
Använd följande steg för att aktivera pixeldimma i ditt program.
- Aktivera blandning av dimma genom att ange D3DRS_FOGENABLE återgivningstillstånd till TRUE.
- Ange önskad dimfärg i D3DRS_FOGCOLOR återgivningstillstånd.
- Välj den dimformel som ska användas genom att ange D3DRS_FOGTABLEMODE återgivningstillstånd till motsvarande medlem i den D3DFOGMODE uppräknade typen.
- Ange dimparametrarna som önskat för det valda dimläget i de associerade återgivningstillstånden. Detta inkluderar start- och slutavstånden för linjär dimma och dimmadensitet för exponentiellt dimläge.
I följande exempel 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 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));
}
Vissa dimparametrar krävs som flyttalsvärden, även om metoden IDirect3DDevice9::SetRenderState endast accepterar DWORD-värden i den andra parametern. Föregående exempel innehåller flyttalsvärdena till IDirect3DDevice9::SetRenderState utan dataöversättning genom att ange adresserna för flyttalsvariablerna som DWORD-pekare och sedan dereferencera dem.
Relaterade ämnen