Udostępnij przez


Filtrowanie tekstur za pomocą map mipmap (Direct3D 9)

Mipmap to sekwencja tekstur, z których każda jest stopniowo niższą rozdzielczością tego samego obrazu. Wysokość i szerokość każdego obrazu lub poziomu w mapie mipmap jest potęgą dwójki mniejszą niż poprzedni poziom. Mipmapy nie muszą być kwadratowe.

Obraz mipmap o wysokiej rozdzielczości jest używany w przypadku obiektów znajdujących się blisko użytkownika. Obrazy o niższej rozdzielczości są używane, ponieważ obiekt pojawia się dalej. Mipmapping poprawia jakość renderowanych tekstur kosztem korzystania z większej ilości pamięci.

Direct3D reprezentuje mipmapy jako łańcuch dołączonych powierzchni. Tekstura o najwyższej rozdzielczości znajduje się na czele łańcucha i ma następny poziom mipmap jako załącznik. Z kolei ten poziom ma powiązanie, które jest następnym poziomem w mipmapu, i tak dalej, aż do poziomu o najniższej rozdzielczości w mipmapu.

Na poniższych ilustracjach przedstawiono przykład tych poziomów. Tekstury bitmapowe reprezentują znak na kontenerze w grze z perspektywy pierwszej osoby 3D. Po utworzeniu jako mipmapa, tekstura o najwyższej rozdzielczości znajduje się jako pierwsza w zestawie. Każda kolejna tekstura w zestawie mipmap jest mniejsza w wysokości i szerokości o potęgę 2. W tym przypadku maksymalna rozdzielczość mipmapy wynosi 256 pikseli na 256 pikseli. Następna tekstura ma rozmiar 128x128. Ostatnia tekstura w łańcuchu to 64x64.

Ten znak ma maksymalną odległość, od której jest widoczna. Jeśli użytkownik zaczyna daleko od znaku, gra wyświetla najmniejszą teksturę w łańcuchu mipmap, co w tym przypadku oznacza teksturę 64x64.

ilustracja tekstury o wymiarach 64x64 znaku zagrożenia

Gdy użytkownik przenosi punkt widzenia bliżej znaku, używane są tekstury o wyższej rozdzielczości w łańcuchu mipmap. Rozdzielczość na poniższej ilustracji to 128x128.

ilustracja 128x128 tekstury znaku zagrożenia

Tekstura o najwyższej rozdzielczości jest używana, gdy punkt widzenia użytkownika ma minimalną dozwoloną odległość od znaku, jak pokazano na poniższej ilustracji.

ilustracja 256x256 tekstury znaku zagrożenia

Jest to bardziej wydajny sposób symulowania perspektywy tekstur. Zamiast renderować jedną teksturę w wielu rozdzielczościach, szybsze jest używanie wielu tekstur w różnych rozdzielczościach.

Funkcja Direct3D może ocenić, która tekstura w zestawie mipmap jest najbliższą rozdzielczością do żądanego wyjścia i może mapować piksele na swoją przestrzeń texeli. Jeśli rozdzielczość obrazu końcowego znajduje się między rozdzielczościami tekstur w zestawie mipmap, Direct3D może zbadać texels w obu mipmapach i połączyć ich wartości kolorów.

Aby używać mipmap, aplikacja musi utworzyć zestaw mipmap. Aplikacje stosują mipmapy, wybierając zestaw mipmap jako pierwszą teksturę w zestawie bieżących tekstur. Aby uzyskać więcej informacji, zobacz Texture Blending (Direct3D 9).

Następnie Twoja aplikacja musi ustawić metodę filtrowania, której Direct3D używa do próbkowania tekseli. Najszybszą metodą filtrowania mipmap jest wybranie najbliższego texela w trybie Direct3D. Użyj wartości D3DTEXF_POINT wyliczonej, aby wybrać tę opcję. Direct3D może generować lepsze wyniki filtrowania, jeśli aplikacja używa wartości z wyliczenia D3DTEXF_LINEAR. Opcja ta wybiera najbliższą mipmapę, następnie oblicza średnią ważoną teskeli otaczających miejsce w teksturze, do którego jest przypisany bieżący piksel.

Tekstury mipmap są używane w scenach 3D, aby skrócić czas wymagany do renderowania sceny. Poprawiają również realizm sceny. Jednak często wymagają dużej ilości pamięci.

Tworzenie zbioru mipmapów

W poniższym przykładzie pokazano, jak aplikacja może wywołać metodę IDirect3DDevice9::CreateTexture, aby utworzyć łańcuch pięciu poziomów mipmap: 256x256, 128x128, 64x64, 32x32 i 16x16.

// This code example assumes that m_d3dDevice is a
// valid pointer to a IDirect3DDevice9 interface

IDirect3DTexture9 * pMipMap;
m_pD3DDevice->CreateTexture(256, 256, 5, 0, D3DFMT_R8G8B8, 
    D3DPOOL_MANAGED, &pMipMap);

Dwa pierwsze parametry akceptowane przez IDirect3DDevice9::CreateTexture to rozmiar i szerokość tekstury najwyższego poziomu. Trzeci parametr określa liczbę poziomów w teksturze. Jeśli ustawisz tę wartość na zero, Direct3D tworzy łańcuch powierzchni, z których każda kolejna ma rozmiar będący potęgą dwójki mniejszą od poprzedniej, aż do najmniejszego możliwego rozmiaru 1x1. Czwarty parametr określa użycie tego zasobu; w tym przypadku określono wartość 0, aby wskazać żadne konkretne użycie zasobu. Piąty parametr określa format powierzchni tekstury. Użyj wartości z D3DFORMAT wyliczonego typu dla tego parametru. Szósty parametr określa element D3DPOOL wyliczonego typu wskazującego klasę pamięci, do której ma być przypisany utworzony zasób. Jeśli nie używasz tekstur dynamicznych, zaleca się D3DPOOL_MANAGED. Końcowy parametr przyjmuje adres wskaźnika, który wskazuje na interfejs IDirect3DTexture9.

Notatka

Każda powierzchnia w łańcuchu mipmap ma wymiary, które stanowią połowę poprzedniej powierzchni w łańcuchu. Jeśli mapa mip najwyższego poziomu ma wymiary 256x128, wymiary mapy mip drugiego poziomu to 128x64, trzeci poziom to 64x32 i tak dalej, aż do 1x1. Nie można zażądać wielu poziomów mipmap w poziomach, które mogłyby spowodować, że szerokość lub wysokość dowolnej mipmapy w łańcuchu będą mniejsze niż 1. W prostym przypadku powierzchni mipmap najwyższego poziomu 4x2 maksymalna wartość dozwolona dla poziomów wynosi trzy. Wymiary najwyższego poziomu to 4x2, wymiary drugiego poziomu to 2x1, a wymiary trzeciego poziomu to 1x1. Wartość większa niż 3 w poziomach prowadzi do ułamkowej wartości wysokości mipmap drugiego poziomu i dlatego jest niedozwolona.

 

Wybieranie i wyświetlanie mipmapy

Wywołaj metodę IDirect3DDevice9::SetTexture, aby ustawić teksturę mipmap jako pierwszą teksturę na liście bieżących tekstur. Aby uzyskać więcej informacji, zobacz Texture Blending (Direct3D 9).

Po wybraniu zestawu tekstury mipmap aplikacja musi przypisać wartości z D3DTEXTUREFILTERTYPE wyliczonego typu do stanu próbkatora D3DSAMP_MIPFILTER. Direct3D automatycznie filtruje tekstury mipmap. Włączenie filtrowania tekstury mipmap zostało pokazane w poniższym przykładzie kodu.

m_pD3DDevice->SetTexture(0, pMipMap);
m_pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

Aplikacja może również ręcznie przemieszczać się przez łańcuch powierzchni mipmap, używając metody IDirect3DTexture9::GetSurfaceLevel, aby określić poziom mipmap do pobrania. Poniższy przykład przemierza łańcuch mipmap od najwyższej do najniższej rozdzielczości.

IDirect3DSurface9 * pSurfaceLevel;
for (int iLevel = 0; iLevel < pMipMap->GetLevelCount(); iLevel++)
{
    pMipMap->GetSurfaceLevel(iLevel, &pSurfaceLevel);
    // Process this level
    pSurfaceLevel->Release();
}

Aplikacje muszą ręcznie przechodzić przez łańcuch mipmap, aby załadować dane mapy bitowej do każdej powierzchni w łańcuchu. Jest to zazwyczaj jedyny powód, by przechodzić przez łańcuch. Aplikacja może pobrać liczbę poziomów w mapie mipmap, wywołując IDirect3DBaseTexture9::GetLevelCount.

filtrowanie tekstur