Perihelion
Link do postu autora gry o grze + sama gra do ściągnięcia: click
A teraz trzy wybrane screeny (źrodło: link powyżej):
32colors.cpp
Jak pisałem we wstępie do postu, tak bardzo spodobał mi się osiągnięty przez autorów efekt, że postanowiłem "naklepać" konwerter, który miał konwertować dowolny obrazek właśnie do dwu-gradientowej palety łącznie 32 kolorów. Konwerter działa następująco:
- dla każdego pixela
-- wylicz odległość koloru od pomarańczowego
-- jeśli odległość jest mniejsza lub równa A, to użyj palety pomarańczowej
-- w przeciwnym wypadku użyj palety szarej
-- wylicz jasność pixela
-- dodaj do niej wartość wynikającą z ditheringu
-- zmniejsz "głębie" jasności do 4 bitów (16 odcieni)
-- pomnóż przez wybraną paletę kolorów
-- i wstaw jako nowy pixel
Jeśli chodzi o dithering, to użyłem ditheringu Bayera (sentyment do Windowsa z czasów sprzed >=24bpp) z macierzą 4x4. Unavowed zasugerował użycie ditheringu Stuckie (Stuckiego?), natomiast z powodów różnych zostałem przy Bayerze.
Co do odległości, to to jest ciekawy problem - jak wyliczyć jakąś wartość, która powie coś o tym jak bardzo dany kolor jest podobny do innego.
Moja wstępna koncepcja zakładała znormalizowanie obu kolorów (gdzie przez "znormalizowanie" mam na myśli potraktowanie RGB jako wektora 3D i podzielenie x,y,z przez długość wektora), a następnie znowu potraktowanie obu kolorów jako punkty 3D i policzenie odległości między nimi.
Natomiast Arashi podsunęła mi pomysł, żeby z RGB wyciągnąć barwę (hue), która btw jest wyrażana w stopniach, i policzyć odległość kątową kolorów (liczenie odległości kątowej na kole jest ciekawe ;>).
Ostatecznie zaimplementowałem oba rozwiązania.
Jeśli chodzi o A, to jest to parametr wyrażony w jednostkach odległości między RGB (0.0 do 1.0) dla pierwszego przypadku, oraz w stopniach dla drugiego (0 do 359).
Anyway, kod + binarka windowsowa jest do ściągnięcia tutaj: 32colors.zip (392kb) (src+win32 bin).
Oczywiście należy pamiętać, że to kod robiony for fun, więc ma trochę błędów (np. zakładam, że szerokość obrazka jest podzielna przez 4, oraz że input będzie 24 bpp), i zresztą całość jest robiona "na oko" ;>
OK, a teraz kilka screenów (skonwertowane można "zoomować"):
I dwa bonusy (skonwertowana fotka by Arashi i .S.K.Y. z inną paletą kolorów):
I tyle...
Comments:
nice graphics indeed ( more http://hol.abime.net/1029/screenshot ), very "bitmap brothers"-like ;)
the dual palette trick is nice and the automatic conversion proves it's very useful.
http://www.gamesector.net/wp-content/uploads/2011/02/killzone-2-02.jpg
http://dabroz.scythe.pl/upload/2011/11/killzone-2-02.png_040.png
Pixel po pixelu co jedną klatkę?
Agreed! "Gods" was one of the first games that came into my mind after seeing the screenshots :)
@Dab
Hmm, there is no difference between the original an converted image. You sure they are using more than 32 colors? </joke>
@D
Hehe szczerze, to sam chetnie bym sie dowiedzial jak efektywnie pracowac/uczyc sie/etc :)
@Xevaquer
Plz share ur results :)
@Albi
;>
@Drraven
Jesli by uzyc strikte software'owego approach, to jest to kwestia przejscia po kazdym pixelu i przeliczenia koloru (szybkie).
Na shaderach bylo by jeszcze szybsze :)
Uh, twój komentarz brzmi trochę jak ten kawał:
Mąż do żony:
- Kochanie powiedz mi coś takiego co mnie jednocześnie ucieszy i zasmuci.
Żona:
- masz dłuższego niż twój brat.
;D
@Blastboy
Ba! I rzucę Ci jeszcze dwie ciekawostki, jedna ad GIF, a druga ad Atari :)
1. Z uwagi na możliwość definiowania lokalnej palety w GIFach per logical image (obrazek GIFa składa się z jednego lub więcej logical image'ów; w animowanych GIF'ach są to frame'y, ale nie każdy GIF musi być animowany), można zrobić GIF który po złożeniu będzie miał więcej niż 256 kolorów (wystarczy złożyć finalny obrazek np. z "logicznych" kwadratów 16x16, gdzie każdy taki kwadrat ma własną paletę).
(W sumie chyba wspominałem o tym w jakimś arcie który kiedyś publikowałem (Hakin9 5/2k8: Format GIF okiem hakera) i jest też o tym na wiki http://en.wikipedia.org/wiki/Graphics_Interchange_Format#True_color)
2. Atari 800 XL umie na raz wyświetlać tylko 16 kolorów z palety 256 kolorów. Ale, jeśli zsynchronizować zmianę palety kolorów ze scan line'ami, (czyli zmieniać paletę kolorów po narysowaniu danej linii na monitorze przez kartę graf), to można uzyskać 256 kolorów na ekranie (ale tylko 16 kolorów na linię).
(O tym dowiedziałem się od Tomka Cieślewicza na CONFidence 2010 - http://gynvael.coldwind.pl/?id=314).
http://gynvael.vexillium.org/dump/atari_256_colors.png - screen z emulatora (programik nie był mojego autorstwa, skądś go przepisałem, ale niestety nie pamiętam skąd ;<)
O metodzie na wyświetlanie 256 kolorów na Atari dowiedziałem się na zajęciach ze sprzętu peryferyjnego pctów. W użyciu była także myszka optyczna jako skaner (prawie 10 lat temu). To tak odnośnie artykułu o studiowaniu (wszystko zależy od tego na jakich ludzi się trafi w życiu :)
Wrażenie na mnie zrobiło, jakie triki są tam zastosowane, aby za pomocą 8 bit'owej palety mieszać tekstury wraz z radiosity. Zacytuje artykuł: "it is awesome to manage to fake 64 gradients of 256 colors....will only 256 colors". Pewnie źródła kolejnych wersji ID Tech, ktore można sobie poprzeglądać, to kopalnia wiedzy i tego typu trików.
PS. Dzięki za Syndicate Wars Port :D
PS2. Można liczyć na port Moonstone? :>
:)
@VGT
Thx za linka, poczytam :)
@QrA
HAM6 to jest jeden z moich ulubionych tricków :)
Działało to następująco:
Miałeś 6 bitów per pixel, z czego:
* 2 to był bit trybu
* pozostałe 4 (a więc wartości 0-15) to była wartość
Do tego miałeś do dyspozycji 16 kolorową paletę kolorów.
I do tego był hmm, niejawny rejestr obecnego R,G,B.
I teraz tak, bity trybu mogły ustawić jeden z czterech trybów dla danego pixela:
- Wybierz kolor z palety: wtedy bity Wartości były traktowane jako numer koloru w palecie. Niejawny rejestr RGB był ustawiany na RGB pobrane z palety.
- Zmień Red: bity Wartości były traktowane jako kanał R, a więc R z niejawnego rejestru RGB było zmieniane na Wartość.
- Zmień Green bity Wartości były traktowane jako kanał G, a więc G z niejawnego rejestru RGB było zmieniane na Wartość.
- Zmień Blue: bity Wartości były traktowane jako kanał B, a więc B z niejawnego rejestru RGB było zmieniane na Wartość.
Dany pixel miał kolor który był w niejawnym rejestrze RGB po wykonaniu jednej z powyższych operacji.
Czyli de facto miałeś 4 bity na R, 4 na G i 4 na B, a więc 12 bitów per kolor (czyli 4096 kolorów). Problem jest tylko taki, że nie możesz zmieniać więcej niż jednej barwy per pixel (chyba, że chcesz pobrać kolor z palety) :)
Więc... owszem, można było wyświetlić obraz który miał 4096 kolory, ale to nie znaczy, że dowolny pixel mógł mieć dowolny kolor. Kolory kolejnych pixeli zależały od kolorów poprzednich pixeli (tj kolor danego pixel zależał od dwóch z trzech kanałów poprzedniego pixela), albo były kolorami wybranymi z palety kolorów.
To niestety bardzo ogranicza zastosowania - głównie do jakiś splash screenów, etc. (co nie zmienia faktu, że jest świetne ;>)
Bodajże chipset AGA miał tryb HAM8 w którym było 6 bitów na wartość (0-63), co dawało 2**18 kolorów.
Ad PS2. Niestety nie hehe, chwilowo mam portowania dość ;)
Cheers!
Add a comment: