GRAFIKA KOMPUTEROWA
Sprawozdanie z pracy laboratoryjnej numer 4. |
---|
Temat |
Prowadzący |
Autor |
Grupa |
Data wykonania |
Zestaw |
Treść zadania:
2. Wstęp teoretyczny:
Model oświetlenia zastosowany w bibliotece OpenGL opiera się na trzech rodzajach światła. Pierwszy rodzaj to światło otaczające (ang. ambient light), które nie pochodzi z żadnego konkretnego kierunku i równomiernie oświetla wszystkie elementy sceny 3D. Drugim rodzajem światła jest światło rozproszone (ang. diffuse light), które pada na obiekt z określonego kierunku, ale jest na nim rozpraszane we wszystkich kierunkach. Ostatnim rodzajem światła obsługiwanego przez OpenGL jest światło odbite (ang. specular light), zwane także światłem kierunkowym, które pada na obiekt w określonym kierunku i odbijane jest także w ściśle określonym kierunku.
W bibliotece OpenGL ze światłem ściśle związane jest pojęcia materiałów określające właściwości oświetlanych obiektów. Właściwości materiału, poza reakcją na opisane wyżej trzy rodzaje światła, uwzględniają także możliwość emitowania światła.
Włączanie oświetlenia
Domyślnie biblioteka OpenGL nie wykonuje obliczeń związanych z oświetleniem. Uruchomienie oświetlenia wymaga wywołania funkcji glEnable z parametrem GL_LIGHTING. Ponadto należy włączyć bufor głębokości. Nie jest to wprawdzie konieczne ale znacząco wpływa na realizm generowanej sceny 3D. Oczywiście wyłączenie oświetlenia sprowadza się do wywołania funkcji glDisable z parametrem GL_LIGHTING.
Parametry źródła światła
Parametry każdego ze źródła światła można modyfikować niezależnie od pozostałych źródeł światła. Służą do tego funkcje z grupy glLight, które można podzielić na dwie podgrupy. Pierwsza pozwala na modyfikację parametrów źródła światła określanych pojedynczą wartością; druga grupa funkcji przyjmuje wskaźniki na tablice z wartościami parametrów, przy czym można ich także używać do modyfikacji parametrów źródła światła określanych pojedynczą wartością.
Zmianę parametru źródła światła określanego pojedynczą wartością umożliwiają funkcje:
void glLightf( GLenum light, GLenum pname, GLfloat param )
void glLighti( GLenum light, GLenum pname, GLint param )
Natomiast zmianę parametru źródła światła określanego tablicą wartości umożliwiają funkcje:
void glLightfv( GLenum light, GLenum pname, const GLfloat * params )
void glLightiv( GLenum light, GLenum pname, const GLint * params )
Materiały
Integralnym elementem modelu oświetlenia przyjętego w bibliotece OpenGL jest opis sposobu zachowania się powierzchni obiektów na poszczególne rodzaje światła, czyli opis właściwości materiałów. Modyfikowanie właściwości materiałów umożliwiają funkcje z grupy glMaterial:
void glMaterialf( GLenum face, GLenum pname, GLfloat para )
void glMateriali( GLenum face, GLenum pname, GLint para )
void glMaterialfv( GLenum face, GLenum pname, const GLfloat * params )
void glMaterialiv( GLenum face, GLenum pname, const GLint * params )
Te funkcje występują w dwóch wersjach różniących się sposobem przekazywania parametrów.
Parametr face ustala, którą stronę wielokąta dotyczy modyfikowany parametr. Dopuszczalne są wartości: GL_FRONT - przednia strona wielokąta, GL_BACK - tylna strona wielokąta i GL_FRONT_AND_BACK - obie strony wielokąta.
Parametr pname określa zmienianą wartość parametru materiału. Dopuszczalne są poniższe wartości:
GL_AMBIENT - składowe RGBA określające stopień odbicia światła otaczającego,
GL_DIFFUSE - składowe RGBA określające stopień rozproszenia światła rozproszonego,
GL_AMBIENT_AND_DIFFUSE - składowe RGBA określające jednocześnie stopień odbicia światła otaczającego i stopień rozproszenia światła rozproszonego i jest to wartość domyślna,
GL_SPECULAR - składowe RGBA określające stopień odbicia światła odbitego,
GL_SHININESS - stała z przedziału [0, 128] określająca wykładnik odbłysku światła (ang. specular exponent) czyli regulację stopnia występowania efektu rozbłysku obiektu; im większa wartość parametru, tym większe skupienie rozbłysku światła na obiekcie,
GL_EMISSION - składowe RGBA światła emitowanego przez obiekt; taki obiekt nie staje się źródłem światła i nie oświetla innych obiektów sceny, wymaga to także utworzenia źródła światła,
GL_COLOR_INDEXES - w indeksowym trybie kolorów trzy indeksy do tablicy kolorów określające kolejno składowe RGBA określające reakcję na światło otaczające, rozproszone i odbite.
Wektory normalne
Do prawidłowego generowania efektów oświetlenia, a w szczególności określenia orientacji wierzchołków obiektów względem źródeł światła, biblioteka OpenGL wymaga definiowania wektorów normalnych (prostopadłych). Ponieważ obliczenia związane z oświetleniem OpenGL wykonuje dla każdego wierzchołka, stąd każdy wierzchołek ma przypisany swój wektor normalny.
Wektor normalny definiują funkcje z grupy glNormal3, które dzielą się na dwie grupy. Pierwsza grupa posiada trzy parametry określające składowe wektora normalnego:
void glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz )
void glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz )
void glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz )
void glNormal3i( GLint nx, GLint ny, GLint nz )
void glNormal3s( GLshort nx, GLshort ny, GLshort nz )
Druga grupa funkcji posiada jeden parametr będący wskaźnikiem na tablicę ze składowymi wektora normalnego:
void glNormal3bv( const GLbyte * v )
void glNormal3dv( const GLdouble * v )
void glNormal3fv( const GLfloat * v )
void glNormal3iv( const GLint * v )
void glNormal3sv( const GLshort * v )
Podobnie jak w przypadku kolorów czy własności materiału dany wektor normalny obowiązuje do czasu zdefiniowania kolejnego. W szczególności można użyć jednego wektora normalnego do grupy wierzchołków opisujących płaski obiekt. Początkowa wartość wektora normalnego wynosi [0, 0, 1].
Do wyznaczania wektora normalnego można użyć iloczynu wektorowego. Przy obliczeniach wykorzystujemy wektory utworzone z krawędzi ściany obiektu, pamiętając o zachowaniu odpowiedniej orientacji. Jeżeli ściany mają sprawiać wrażenie płaskich, wówczas obliczamy wektor normalny tylko dla pierwszego wierzchołka. Pozostałe wierzchołki będą korzystały z tego samego wektora.
Jeżeli natomiast zależy nam na uzyskaniu wrażenia gładkości oświetlanego obiektu wykorzystujemy technikę uśredniania wektorów normalnych. Polega ona na obliczaniu wektora normalnego dla każdego wierzchołka obiektu 3D. Tym razem wektor ten obliczamy nie na podstawie krawędzi jednej ściany ale wszystkich krawędzi wychodzących z wierzchołka. Można do tego celu wykorzystać złożenie (sumę) wektorów normalnych wszystkich ścian zawierających dany wierzchołek. Technika ta pozwala na zwiększenie realizmu sceny bez radykalnego zwiększania złożoności renderowanych obiektów.
Aby obliczenia oświetlenia były wykonywane poprawne wektor normalny musi mieć długość jednostkową, inaczej mówiąc musi być znormalizowany (jednostkowy). Normalizację wektorów można wykonać programowo, przy czym należy uwzględniać przekształcenia macierzy modelowania, które modyfikują także wektory normalne i mogą przy okazji zmienić ich długość. W szczególności dotyczy to operacji skalowania macierzy modelowania.
Drugim sposobem normalizacji wektorów normalnych jest skorzystanie z mechanizmu udostępnianego przez OpenGL, który automatycznie normalizuje wektory normalne. W tym celu trzeba wywołać funkcję glEnable z parametrem GL_NORMALIZE. Domyślnie mechanizm ten jest nieaktywny. Wyłączenie automatycznej normalizacji wektorów normalnych wymaga wywołania funkcji glDisable z parametrem GL_NORMALIZE.
Odczyt parametrów źródła światła i materiałów
Odczyt ustawień wybranego źródła światła umożliwiają funkcje z grupy glGetLight:
void glGetLightfv( GLenum light, GLenum pname, GLfloat * params )
void glGetLightiv( GLenum light, GLenum pname, GLint * params )
Znaczenie parametrów light i pname jest takie same jak analogicznych parametrów funkcji z grupy glLight. Wartości pobieranych ustawień źródła światła umieszczane są w tablicy, do której wskaźnik należy podać w parametrze params.
3. Cel ćwiczenia i sposób rozwiązania:
Celem zadania jest stworzenie obiektu: 2/3 walca o zmiennej, parzystej liczbie podziałów pionowych i poziomych, który można będzie oświetlić za pomocą dwóch źródeł światła i stworzyć dwie właściwości powierzchni, by pokazać w jaki sposób reaguje one na docierające do nich światło.
W tym sprawozdaniu skupie się na przedstawieniu sposobu (metody) tworzenia światła jak i materiałów. Natomiast sposób wykonania (zamodelowania) 2/3 walca, czy też innych powtarzających się elementów ominę ze względu na wcześniejszą realizacje tych założeń na poprzednich zajęciach laboratoryjnych.
Kombinacja trzech typów światła pozwala na przybliżanie rzeczywistych zjawisk świetlnych występujących w przyrodzie. Do skomponowania modelu oświetlenia sceny należy podać założone proporcje intensywności poszczególnych składników światła, a także określić składowe RGB koloru światła.
Od momentu rozpoczęcia posługiwania się oświetleniem w OpenGL nie opisujemy wielokątów poprzez ich kolor, a raczej poprzez właściwości materiału, którym są pokryte (dany obiekt zbudowany jest z materiału, który odbija większość danego światła). Oprócz tego że zdefiniujemy kolor materiału, należy określić w jaki sposób dany materiał reagować będzie na poszczególne składniki modelu światła.
Trzeba mieć duże doświadczenie, aby od razu wybrać (dobrać) odpowiednie właściwości źródeł światła i cech materiałów, lecz mimo tego z łatwością możemy sobie z tym poradzić korzystając z narzędzia MATLIGHT. Dzięki niemu możemy sprawdzać (dobierać) poszczególne parametry oświetlenia sceny. Umożliwia on interaktywne modyfikowanie składników światła i własności materiałów, oraz obserwację zachodzących na scenie zmian.
Wykorzystałem wyżej wymienione narzędzie do pomocy podczas dobierania odpowiednich składników do modelu oświetlenia i materiałów.
Rys1. Przedstawiający okno programu Matlight.
4. Implementacja oraz efekty działania programu.
Macierze odpowiadające za kolor:
-Żółty emitujący:
GLfloat material_zolty[5][4]=
{
{1,1,0,1},// wspolczynnik odbicia swiatla otoczenia
{1,0,1,1},// wspolczynnik odbicia swiatla rozproszonego
{1,1,1,1},// wspolczynnik odbicia swiatla lustrzanego
{0,0,0,0},// polysk
{0.9,0.9,0.0,1}// kolor swiatla emitowanego
};
-Zielony matowy
GLfloat material_zielony[5][4]=
{
{0,1,0,1},// wspolczynnik odbicia swiatla otoczenia
{0,1,0,1},// wspolczynnik odbicia swiatla rozproszonego
{0,1,0,1},// wspolczynnik odbicia swiatla lustrzanego
{0,0,0,0},// polysk
{0,0,0,0}// kolor swiatla emitowanego
};
Funkcje ładujące macierze z parametrami kolorów:
void material1()
{
glMaterialfv(GL_FRONT, GL_AMBIENT, material_zolty[0]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_zolty[1]);
glMaterialfv(GL_FRONT, GL_SPECULAR, material_zolty[2]);
glMaterialfv(GL_FRONT, GL_SHININESS, material_zolty[3]);
glMaterialfv(GL_FRONT, GL_EMISSION, material_zolty[4]);
}
void material2()
{
glMaterialfv(GL_FRONT, GL_AMBIENT, material_zielony[0]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, material_zielony[1]);
glMaterialfv(GL_FRONT, GL_SPECULAR, material_zielony[2]);
glMaterialfv(GL_FRONT, GL_SHININESS, material_zielony[3]);
glMaterialfv(GL_FRONT, GL_EMISSION, material_zielony[4]);
}
Macierze odpowiadające za parametry świateł:
-kierunkowe (zielone):
GLfloat swiatlo1[10][4]= {
{0.0, 1.0, 0.0, 0.0}, // [0] otoczenie
{0.0, 1.0, 0.0, 0.0}, // [1] rozproszenie
{0.0, 1.0, 0.0, 0.0}, // [2] lustrzane
{-10.0, -5.0, 10.0, 1.0}, // [3] polozenie
{0.0, 0.0, 1.0, 0.0}, // [4] kierunek swiecenia
{1.0, 1.0, 1.0, 0.0}, // [5] tlumienie katowe swiatla
{360.0, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla
{0.0, 0.0, 0.0, 0.0}, // [7] stale tlumienie
{0.7, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe
{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe;
-reflektor (fioletowe):
GLfloat swiatlo2[10][4]= {
{0.0, 0.0, 0.0, 0.0}, // [0] otoczenie
{1.0, 0.0, 1.0, 0.0}, // [1] rozproszenie
{1.0, 0.0, 1.0, 0.0}, // [2] lustrzane
{-10.0, -5.0, 10.0, 1.0}, // [3] polozenie
{0.0, 0.0, 1.0, 0.0}, // [4] kierunek swiecenia
{0.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla
{7.5, 0.0, 0.0, 0.0},// [6] kat odciecia swiatla
{0.9, 0.0, 0.0, 0.0}, // [7] stale tlumienie
{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe
{0.0, 0.0, 0.0, 0.0}};
Załadowanie parametrów oświetlenia oraz sterowanie (on/off):
void WlaczOswietlenie(void)
{
// Odblokowanie oswietlenia
glEnable(GL_LIGHTING);
if(swiecenie==1){
// Odblokowanie zerowego zrodla swiatla
glEnable(GL_LIGHT0);
// Inicjowanie zrodla swiatla
glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);
glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);
glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);
glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, swiatlo[7][0]);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, swiatlo[8][0]);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, swiatlo[9][0]);
}
else glDisable(GL_LIGHT0);
if(swiecenie1==1){
// Odblokowanie zrodla swiatla
glEnable(GL_LIGHT1);
// Inicjowanie zrodla swiatla
glLightfv(GL_LIGHT1, GL_AMBIENT, swiatlo1[0]);
glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo1[1]);
glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo1[2]);
glLightfv(GL_LIGHT1, GL_POSITION, swiatlo1[3]);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, swiatlo1[4]);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, swiatlo1[5][0]);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, swiatlo1[6][0]);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, swiatlo1[7][0]);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, swiatlo1[8][0]);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, swiatlo1[9][0]);
}
else glDisable(GL_LIGHT1);
}
Funkcja rysująca walec:
void RysujWalec(double h, double r, int nv, int nh)
{
float POZi=0.0, pj=0.0, i2=0.0, j2=0.0 ,x1=0.0 ,y1=0.0 ,z1=0.0 ,x2=0.0 ,y2=0.0 ,z2=0.0 ,x3=0.0 ,y3=0.0 ,z3=0.0 ,x4=0.0 ,y4=0.0 ,y5=0.0;
int poziomy=0;
int b=0;
glTranslatef(0.0,-2.5,0.0);
for(POZi=0;POZi<=(H-0.001); POZi=POZi +H/podzial_poziomy)
{
poziomy =0;
for(pj=0;pj<=Kp-1;pj = pj +Kp/podzial_pionowy)
{
switch(poziomy)
{
case 0:
Material1();
poziomy++;
break;
case 1:
Material2();
poziomy--;
break;
}
x1=rC*cos(pj*PI/180);
y1=0;
z1=rC*sin(pj*PI/180);
j2 = pj +Kp/podzial_pionowy;
x2=rC*cos(j2*PI/180);
y2=0;
z2=rC*sin(j2*PI/180);
y3=H;
y4=POZi;
y5=POZi +H/podzial_poziomy;
//dolna
glNormal3f(0.0, -1.0, 0.0);
glBegin(GL_QUADS);
glVertex3f(0.0,0.0,0.0);
glVertex3f(x1,y1,z1);
glVertex3f(x2,y2,z2);
glVertex3f(0.0,0.0,0.0);
glEnd();
//gorna
glNormal3f(0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glVertex3f(0.0,y3,0.0);
glVertex3f(x1,y3,z1);
glVertex3f(x2,y3,z2);
glVertex3f(0.0,y3,0.0);
//bok
glBegin(GL_QUADS);
glNormal3f(cos(pj*PI/180),0.0,rC*sin(pj*PI/180));
glVertex3f(x1,y4,z1);
glVertex3f(x1,y5,z1);
glNormal3f(cos(j2*PI/180),0.0,rC*sin(j2*PI/180));
glVertex3f(x2,y5,z2);
glVertex3f(x2,y4,z2);
glEnd();
if(pj==0)
{
glBegin(GL_QUADS);
glNormal3f(0, 0, -1);
glVertex3f(0,y4,0);
glVertex3f(0,y5,0);
glNormal3f(0, 0, -1);
glVertex3f(x1,y5,z1);
glVertex3f(x1,y4,z1);
glEnd();
}
if(j2>=Kp-1)
{
glBegin(GL_QUADS);
glNormal3f(0, 0, -1);
glVertex3f(0,y4,0);
glVertex3f(0,y5,0);
glNormal3f(0, 0, -1);
glVertex3f(x2,y5,z2);
glVertex3f(x2,y4,z2);
glEnd();
}
}}
Swiatlo1();
Swiatlo2();
}
Funkcja obsługi klawiatury:
void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
{
switch(klawisz)
{
case 'e':
wysObs -= 1.0;
break;
case 'r':
wysObs += 1.0;
break;
case 'q':
podzial_pionowy = (podzial_pionowy == LPION_MAX)? LPION_MAX : podzial_pionowy + 2; //zwiekszenie liczby podzia3ów pionowych
break;
case 'Q':
podzial_pionowy = (podzial_pionowy == LPION_MIN)? LPION_MIN : podzial_pionowy - 2; //zmniejszenie liczby podzia3ów pionowych
break;
case 't':
podzial_poziomy = (podzial_poziomy == LPOZ_MAX)? LPOZ_MAX : podzial_poziomy + 2; //zwiekszenie liczby podzia3ów poziomych
break;
case 'T':
podzial_poziomy = (podzial_poziomy == LPOZ_MIN)? LPOZ_MIN : podzial_poziomy - 2; //zmniejszenie liczby podzia3ów poziomych
break;
case 'z' : R_L1 += 0.1;
break;
case 'Z' : R_L1 -= 0.1;
break;
case '#' : (c=0);
break;
case '-' : odleglosc++;
break;
case '+' : odleglosc--;
break;
case ',' : obrot = (obrot == 360) ? 0 : obrot + 1;
break;
case '.' : obrot = (obrot == 0) ? 360 : obrot - 1;
break;
case 'c':
UstawDomyslneWartosciParametrow();
break;
case 'f':
katRX=(katRX>-90) ? katRX-1 : -90; //zmniejszenie kata nachylenia osi X orbity owiat3a
break;
case 'g':
katRX=(katRX<90) ? katRX+1 : 90; //zwiekszenie kata nachylenia osi X orbity owiat3a
break;
case 'o':
katRZ=(katRZ>-90) ? katRZ-1 : -90; //zmniejszenie kata nachylenia osi Y orbity owiat3a
break;
case 'i':
katRZ=(katRZ<90) ? katRZ+1 : 90;
break;
case '1' : (a=1);
break;
case '!' : (a=0);
break;
case '2' : (b=1);
break;
case '@' : (b=0);
break;
// Wcisniecie klawisza ESC powoduje wyjscie z programu
case 27:
exit(0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja klawiszy specjalnych
void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y)
{
switch(klawisz)
{
case GLUT_KEY_UP:
kat2 = (kat2 == 360) ? 0 : kat2 + 1;
break;
case GLUT_KEY_DOWN:
kat2 = (kat2 == 0) ? 360 : kat2 - 1;
break;
case GLUT_KEY_RIGHT:
kat = (kat == 360) ? 0 : kat + 1;
break;
case GLUT_KEY_LEFT:
kat = (kat == 0) ? 360 : kat - 1;
break;
}
}
Zrzuty ekranu działania programu:
Rys1. Uruchomiony program z parametrami jak w wcześniejszym kodzie.
Rys2. Uruchomiony program z parametrami jak w wcześniejszym kodzie.
Rys3. Światło reflektora oświetlające walec ze zwiększoną liczbą podziałów pionowych.
Rys4. Światło reflektora oraz oraz światło kierunkowe oświetlające walec ze zwiększoną liczbą podziałów pionowych.
6. Wnioski:
Zadanie nie zostało wykonane w pełni na zajęciach laboratoryjnych, brakowało oświetlenia reflektorem, a sama bryła niedomykała ścian. W domu poprawiłem swój program i otrzymałem poprawne wyniki, zdecydowanie lepsze niż na zajęciach.
Samo pokrycie materiałem nie sprawia większej trudności, można uzyskać różne ciekawe efekty, w moim przypadku były to pasy pionowe. Większy problem sprawia natomiast odpowiednie dobranie parametrów oświetlenia.
Powyższe ćwiczenia miało na celu zapoznanie nas z technikami, które są potrzebne do zamodelowania oświetlenia za pomocą biblioteki OpenGL. W trakcie wykonywania ćwiczeń musiałem skorzystać z wiedzy nabytej na poprzednich zajęciach laboratoryjnych, a także wykazać się nowymi informacjami na temat oświetlenia. Podczas użytkowania programu zarejestrowałem kilka ciekawych spostrzeżeń oraz wniosków:
Zarówno definiowanie oraz utworzenie materiałów budujących naszą figurę jest dość proste (o ile się zna i rozumie poszczególne parametry opisujące materiał) . Ponadto wypadałoby w sposób umiejętny obsługiwać się paletą RGB i umieć szybko liczyć odwrotności danej liczby reprezentującej kolor.
Definiowanie i tworzenie światła jest wręcz podobne do tej samej operacji dotyczącej materiałów.
Aby zaobserwować bardziej realistyczne zachowanie oświetlenia trzeba zwiększyć liczbę podziałów pionowych jak i poziomych.
Nie można jednak z liczbą podziałów „przesadzić”, gdyż zbyt duża ich liczba powoduje zwiększanie zapotrzebowanie programu na pamięć i procesor, które służą mu do obliczenia. W takim momencie wiele zależy od wydajności komputera, na którym pracujemy.
Przy innym świetle kierunkowym (mocniejszym) można zaobserwować nakładanie się świateł co powoduje, że kolor, który pokrywa nasz materiał potrafi zmienić kolor na całkowicie inny.