Grafika 3D
 
  Zarejestruj się
::  Newsy  ::  Pliki  ::  Twoje Konto  ::  Forum  ::
Menu
· Strona główna
· Forum
· Linki
· Lista u?ytkowników
· O nas...
· Pliki
· Statystyki
· Twoje Konto
Tutoriale
· API
· Matematyka
· Teoria
· Direct3D
· OpenGL
· Techniki
Kto Jest Online
Aktualnie jest 47 gość(ci) i 0 użytkownik(ów) online.

Jesteś anonimowym użytkownikiem. Możesz się zarejestrować za darmo klikając tutaj
Tutoriale - OpenGL - Mgła

Witam wszystkich ponownie. W zasadzie od poprzedniego razu zaczęliśmy się pomału dowiadywać co to tak naprawdę jest grafika 3D. Otóż, jak na pewno większość z was zdążyła zauważyć, jest to jedna wielka ściema, a im bardziej ściemniamy, tym lepszy uzyskujemy efekt końcowy. Tak więc dziś nauki ściemnienia ciąg dalszy, czyli zajmiemy się mgłą :))). Kod nie uległ praktycznie zmianom. W zasadzie wszystko robimy w funkcji inicjującej, która też nie należy do zbyt skomplikowanych. Do dzieła więc!. Pierwszą nową rzeczą jest linijka
const float fog_color[] = {0.8f, 0.8f, 0.8f, 1.0f};
Jak nie trudno się domyślić jest to tablica przechowująca kolor naszej mgły - w tym wypadku jasno szary, ale możecie zmienić go na jakikolwiek inny. Teraz musimy trochę "przejechać" przez kod, bo kolejne zmiany są dopiero w funkcji inicjującej:

glEnable( GL_FOG );
No tej linijki, to chyba nikomu nie musze wyjaśniać :). Jak zwykle coś włączamy - tym razem mgłę. Zanim jednak powiem co dalej, to muszę wytłumaczyć na czym polega proces "zamglenia". Otóż jeśli ktokolwiek z was myśli, że idzie o nałożenie jakiegoś tam czegoś na ekran, co imituje mgłę, to się zawiedzie. Mgła w grafice nie jest niczym fizycznym (jeśli w ogóle można tak mówić o komputerze :))). Jej działanie opiera się na technice znanej z poprzedniego tutsa, czyli na mieszaniu. Jednym słowem mgła to dodanie pewnego koloru do wierzchołka (nie do końca, ale na nasze potrzeby przyjmijmy, że tak jest), zmieszanie go z kolorem obecnym i interpolacja na wielokącie (czyli ściema :))). Tak więc mgła występuje tylko tam, gdzie są obiekty - na pustej scenie nie zauważymy nic. Tutaj muszę zaznaczyć, że oprócz mgły "wierzchołkowej" występuje również mgła liczona dla poszczególnych pikseli. Nie wiem niestety jak to dokładnie jest zrobione w OpenGL, ale w dokumentacji piszą, że mgłę liczoną dla pikseli włącza się za pomocą funkcji
glHint( GL_FOG_HINT, GL_NICEST );
natomiast mgłę wierzchołkową za pomocą GL_FASTEST. Cóż teoretycznie jak coś piszą w dokumentacji, to tak być powinno, ale niestety piszą także, że OpenGL może zignorować wywołanie glHint() (mnie się to zdarzyło już parę razy), a podobno karty ATI w ogóle nie obsługują GL_POINT_SMOOTH_HINT (antyaliasing punktów - też ustawiany za pomocą glHint()) ustawionego na GL_NICEST. Tak więc, jak już mówiłem, przyjmijmy, że mgła liczona jest dla wierzchołków :).

Skoro już wiemy jak mgłą działa, powiedzmy sobie o niej coś więcej. Mgłę cechuje kilka parametrów, które zaraz omówię. Pierwszym z nich jest oczywiście kolor mgły. Ustalamy go za pomocą tej oto funkcji:
glFogfv( GL_FOG_COLOR, fog_color );
Jak widać OpenGL ma specjalną grupę funkcji przeznaczonych do zmian parametrów mgły. Pierwszy parametr określa czego dotyczy parametr drugi (wiem, wiem, trochę głupio to brzmi, ale trudno ;). Drugi wiadomo - zawiera wartości, którymi OpenGL ma zastąpić wartości obecne dla danego parametru. W tym wypadku ustawiamy sobie nowy kolor mgły (domyślnie jest czarny). Kolejną własnością mgły jest jej zasięg (tylko dla mgły liniowej - wyjaśnię później :)). Czyli należy określić wartość z, w której mgła się zaczyna i wartość z, w której się kończy. Służy do tego jedna funkcja, którą wywołujemy dwukrotnie:
glFogf( GL_FOG_START, 1.0f );
glFogf( GL_FOG_END, 100.0f );
Jak widać pierwsze wywołanie ustawia nam początek mgły, a drugie jej koniec. Nie będę tu nic tłumaczył, bo tak naprawdę nie ma co :)). Kolejną wartością mgły jest jej gęstość (nie używana w przypadku mgły liniowej). Określamy ją za pomocą tej samej funkcji, co poprzednio
glFogf( GL_FOG_DENSITY, 0.25f );
Wytłumaczenie jak działa gęstość zostawiam na później. Ostatnią z własności jest rodzaj mgły określany za pomocą poniższej funkcji:
glFogi( GL_FOG_MODE, GL_EXP2 );
W OpenGL wyróżniamy trzy rodzaje mgły:
  • liniowa,
  • eksponencjalna,
  • eksponencjalna kwadratowa.
Na pewno niektórych przeraziła nazwa "eksponencjonalna". Cóż to takiego do ^%$!!. Ano w zasadzie jest to kolejna głupawa nazwa, jaką jajogłowi wymyślili do określenia funkcji wykładniczej o podstawie liczby e (e=2.718281828...). Ja będę używał nazwy "mgła wykładnicza", jako że jest chyba lepiej przyswajalna (ponadto nazwa jest znana ze szkoły ;)), pamiętajcie tylko, że podstawą funkcji wykładniczej określającej rozkład gęstości mgły jest liczba e. Typ mgły określa jakiego wzoru OpenGL ma używać do kalkulacji koloru. Jak już powiedziałem mgła to tak naprawdę blending. Wzór używany do tego celu wygląda następująco:

Cr' = f*Cr + (1-f)*Cf

Gdzie:
Cr' - to kolor końcowy,
Cr - to dotychczasowy kolor wierzchołka,
Cf - to kolor mgły.

natomiast f jest parametrem zależnym od rodzaju mgły. Dla mgły liniowej wzór używany do obliczenia tego parametru jest następujący:


gdzie end i start określają początek mgły, a d określa współrzędną z danego wierzchołka. Dla mgły wykładniczej używany jest inny wzór:


Jak widać w tym wypadku nie używamy zakresu mgły, ale jej gęstości ( density - którą ustaliliśmy poprzednio) i współrzędnej z wierzchołka. Ostatnim z możliwych rodzajów mgły (dostępnych standardowo - są jeszcze rozszerzenia :))) jest mgła wykładnicza kwadratowa (albo kwadratowa). Wzór do obliczenia f w tym wypadku wygląda następująco:


Czyli jest to w sumie prawie ten sam wzór tyle, że dodatkowo wykładnik jest podniesiony do kwadratu. W zasadzie, samo przedstawienie wzorów nikomu nic nie mówi (chyba, że ktoś potrafi sobie narysować odpowiednie wykresy w głowie :))), więc przedstawię wykres pokazujący jak zachowują się poszczególne rodzaje mgły (mam nadzieje, że przynajmniej części z was coś się rozjaśni jak go zobaczą):


Wykres ten służy temu, abyście mogli zobaczyć jak zachowują się poszczególne rodzaje mgły wykładniczej (liniowa jest zawsze taka sama) przy wzroście, bądź zmniejszeniu gęstości. Skoro mamy już omówione co to jest mgła, jakie są jej rodzaje oraz jak ją włączyć i ustawić wszystkie jej parametry, to zaglądnijmy do naszej funkcji renderującej, a raczej na pierwszą linijkę, bo reszta jest bez zmian.
glClearColor( fog_color[0], fog_color[1], fog_color[2], 1.0f );
Na pewno zastanawiacie się po kiego grzyba w funkcji ustawiającej kolor, którym ma być wypełniony bufor koloru po wyczyszczeniu, ustawiam kolor mgły. Ano, kolejna ściema :). Pamiętacie, jak na początku mówiłem, że jeśli na naszej scenie nie ma obiektów, to nie zobaczymy mgły? Tak więc ustawienie koloru czyszczenia na kolor mgły zapewnia nas, że ekran zostanie pokryty kolorem mgły, czyli de facto na ekranie zobaczymy mgłę nawet jeśli nie będzie tam obiektów. Tak, wiem, że na naszej scenie jest obiekt, ale jego rozmiar nie pokrywa w zupełności ekranu. Aby dokładnie zrozumieć o co mi chodzi zmieńcie kolor w powyższej linijce na np. czarny i uruchomcie. I co? Lipa! Kostka wygląda jak wyblakła od słońca, a nie jak we mgle.

To tyle na dzisiaj. Następnym razem będzie w wprowadzenie do trochę bardziej zaawansowanej grafiki, czyli multiteksturing. Jest to jedna z ważniejszych obecnie stosowanych technik, pozwalająca uzyskać takie efekty jak bumpmapping, mapowanie środowiskowe i wiele, wiele innych. Tak więc trzymajcie się i nie dajcie się szkole/pracy/życiu :). Narka.



Kod źródłowy

©Copyright by Domino   



Tutoriale - OpenGL
Nasze newsy s� w RSS: backend.php
PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Tworzenie strony: 0.28 sekund

:: Layout strony został stworzony przez www.nukemods.com w oparciu o styl phpbb2 Helius, którego autorem jest Cyberalien ::