Mapy świateł
							
							
Mapy świateł 
(ang. Lightmap) służą do realizacji oświetlenia sceny. Zasada wykorzystania map świateł opiera się na renderowaniu wielokątów z właściwą teksturą oraz dodatkowo z teksturą mapy oświetlenia. Stosowane są dwie metody renderowania map świateł. Pierwsza metoda polega na równoczesnym renderowaniu tekstury i mapy światła dla tego samego wielokąta i podanego trybu mieszania kolorów tekstury 
(ang. multi-blender texture operations). Druga metoda polega na dwukrotnym renderowaniu tego samego wielokąta. Pierwszy raz renderujemy wielokąt z właściwą teksturą, drugi raz renderujemy ten sam wielokąt z mapą światła i ustawionym trybem przezroczystości 
(ang. Alpha blending) oraz odpowiednimi parametrami bufora głębokości 
(ang. Z-buffer or Depth Buffer).
Poniżej została opisana jedna z metod liczenia składowych koloru dla tekseli mapy światła.
1. Wyznaczamy współrzędne mapy światła lu i lv:
	
		
		
if (fabs(N.x) > fabs(N.y) && fabs(N.x) > fabs(N.z))
			{
			    Typ = 1;
			    for(i = 0; i < IloscWierz; i++)
			    {
			        Wierz[i].lu = Wierz[i].y;
			        Wierz[i].lv = Wierz[i].z;
			    }
			}
			else if (fabs(N.y) > fabs(N.x) && fabs(N.y) > fabs(N.z))
			    {
			        Typ = 2;
			        for(i = 0; i < IloscWierz; i++)
			        {
			            Wierz[i].lu = Wierz[i].x;
			            Wierz[i].lv = Wierz[i].z;
			        }
			    }
			    else
			    {
			        Typ = 3;
			        for(i = 0; i < IloscWierz; i++)
			        {
			            Wierz[i].lu = Wierz[i].x;
			            Wierz[i].lv = Wierz[i].y;
			        }
			    }
 
Gdzie:
N i D - to współrzędne płaszczyzny, na której znajduje się wielokąt. 
Wierz - to tablica wierzchołków wielokąta.
IloscWierz - to ilość wierzchołków w tablicy Wierz.
2. Normalizujemy współrzędne mapy światła lu i lv:
	
	
minu = Wierz[0].lu;
		minv = Wierz[0].lv;
		maxu = Wierz[0].lu;
		maxv = Wierz[0].lv;
		for (i = 0; i < IloscWierz; i++)
		{
		    if (Wierz[i].lu < minu) minu = Wierz[i].lu;
		    if (Wierz[i].lv < minv) minv = Wierz[i].lv;
		    if (Wierz[i].lu > maxu) maxu = Wierz[i].lu;
		    if (Wierz[i].lv > maxv) maxv = Wierz[i].lv;
		}
		du = maxu - minu;
		dv = maxv - minv;
		for (i = 0; i < IloscWierz; i++)
		{
		    Wierz[i].lu -= minu;
		    Wierz[i].lv -= minv;
		    Wierz[i].lu /= du;
		    Wierz[i].lv /= dv;
		}
Dla wszystkich wielokątów sceny zapamiętujemy wartości minu, minv, maxu i maxv oraz Typ.
3. Wyznaczamy trzy wektory mapy światła uvvect, kieru, kierv.
Wektory te służą do wyznaczenia pozycji każdego teksela mapy światła w przestrzeni 3D:
	
	
switch( Typ )
		{
		    case 1: //YZ
		        vectx = - ( N.y * minu + N.z * minv + D ) / N.x;
		        uvvect = D3DVECTOR( vectx, minu, minv );
		        vectx = - ( N.y * maxu + N.z * minv + D ) / N.x;
		        vect1 = D3DVECTOR( vectx, maxu, minv);
		        vectx = - ( N.y * minu + N.z * maxv + D ) / N.x;
		        vect2 = D3DVECTOR( vectx, minu, maxv);
		        break;
		    case 2: //XZ
		        vecty = - ( N.x * minu + N.z * minv + D ) / N.y;
		        uvvect = D3DVECTOR( minu, vecty, minv);
		        vecty = - ( N.x * maxu + N.z * minv + D ) / N.y;
		        vect1 = D3DVECTOR( maxu, vecty, minv);
		        vecty = - ( N.x * minu + N.z * maxv + D ) / N.y;
		        vect2 = D3DVECTOR( minu, vecty, maxv);
		        break;
		case 3: //XY
		        vectz = - ( N.x * minu + N.y * minv + D ) / N.z;
		        uvvect = D3DVECTOR( minu, minv,vectz);
		        vectz = - ( N.x * maxu + N.y * minv + D ) / N.z;
		        vect1 = D3DVECTOR( maxu, minv, vectz);
		        vectz = - ( N.x * minu + N.y * maxv + D ) / N.z;
		        vect2 = D3DVECTOR( minu, maxv, vectz);
		        break; 
		}
		kieru = vect1 - uvvect;
		kierv = vect2 - uvvect;
Dla wszystkich wielokątów sceny zapamiętujemy wektory uvvect, kieru, kierv.
4. Wyznaczamy składowe koloru dla każdego teksela mapy światła. 
	
	
for(x = 0; x < szerokosc; x++)
		{
		    for(y = 0; y < wysokosc; y++)
		    {
		        du = x / szerokosc;
		        dv = y / wysokosc;
		        teksel_poz = uvvect + kieru * du + kierv * dv;
		        // tutaj powinien zostać umieszczony program wyznaczający wartości koloru (r, g, b) dla teksel_poz
		        // wypadkowy kolor powinien być wyznaczony od kolejnych źródeł światła
		        lightmap[x + y * wys * 3] = (char)r;
		        lightmap[x + y * wys * 3 + 1] = (char)g;
		        lightmap[x + y * wys * 3 + 2] = (char)b;
		    }
		}
Gdzie:
szerokosc i wysokosc - to szerokość i wysokość mapy światła np. 8, 16, 32 ...
teksel_poz - to pozycja teksela w przestrzeni 3D.
r, g, b - to składowe koloru teksela mapy światła
							
							
							
								Numer artykułu: 5
								Wysłany: Sun, Jan 24, 2010 4:31 PM
								Ostatnio zmieniony: Sun, Jan 24, 2010 6:32 PM
								
							
							Adres URL: https://www.komires.net/article.php?id=5