Jak stworzyć „retro” moduł cieniujący piksele dla przekształconych duszków 2D, który zachowuje wierność pikseli?

10

Poniższy obraz pokazuje dwa duszki renderowane z próbkowaniem punktowym na górze tła:

wprowadź opis zdjęcia tutaj

  • Do lewej czaszki nie zastosowano obrotu / skalowania, więc każdy piksel idealnie pasuje do tła.
  • Prawa czaszka jest obracana / skalowana, co powoduje, że większe piksele , które nie są już wyrównane względem osi .

Jak mogłem opracować moduł cieniujący piksele, który renderowałby przekształconego duszka po prawej stronie z pikselami wyrównanymi do osi o tym samym rozmiarze co reszta sceny?

Może to być związane z tym, jak skalowanie sprite zostało zaimplementowane w starych grach, takich jak Monkey Island, ponieważ taki efekt staram się osiągnąć, ale z dodaną rotacją.


Edytować

Zgodnie z sugestiami kaoD starałem się rozwiązać problem jako post-proces. Najłatwiejszym podejściem było najpierw renderowanie do oddzielnego celu renderowania (próbkowanie w dół w celu dopasowania do pożądanego rozmiaru pikseli), a następnie przeskalowanie go podczas renderowania po raz drugi. To spełniło moje wymagania powyżej.

Najpierw próbowałem to zrobić Linear -> Pointi wynik był następujący:

wprowadź opis zdjęcia tutaj

Nie ma zniekształceń, ale efekt wygląda rozmazany i traci większość kolorów świateł. Moim zdaniem psuje wygląd retro, którego potrzebowałem.

Drugi raz próbowałem Point -> Pointi wynik był następujący:

wprowadź opis zdjęcia tutaj

Pomimo zniekształceń, myślę, że może to być wystarczające na moje potrzeby, chociaż lepiej wygląda jako zdjęcie nieruchome niż w ruchu.

Aby to zademonstrować, oto film przedstawiający efekt, chociaż YouTube odfiltrował z niego piksele:

http://youtu.be/hqokk58KFmI

Pozostawię jednak pytanie otwarte na kilka dni, na wypadek, gdyby ktoś wpadł na lepsze rozwiązanie próbkowania, które zachowuje ostry wygląd, jednocześnie zmniejszając zniekształcenie podczas ruchu.

David Gouveia
źródło
To ma być czaszka ...?
DeadMG,
@DeadMG Chyba wół czaszka?
David Gouveia,
Fajny efekt, wygląda lepiej, niż się spodziewałem (wypróbowałem go NA WYSOKIEJ rozdzielczości i palecie, 40 x 30 EGA.) Tak wyglądasz, tworząc własny shader postfx. BTW, wątpię, czy istnieje lepsze rozwiązanie próbkowania, które zachowuje efekt zgodnie z twoimi zamierzeniami. NN jest prawie tym, co daje ten ostry wygląd, każde inne próbkowanie zamazuje ostateczny obraz (i tak tylko zgaduję.)
kaoD
@kaoD Pamiętaj jednak, że stosuję dwa podania. Drugie przejście, które upsampluje obraz, nadal będzie najbliższym sąsiadem, aby zachować wrażenie retro. Ale myślę, że może być pewna korzyść z wypróbowania różnych technik próbkowania dla pierwszego przejścia. Obecnie patrzę na Scale2x!
David Gouveia,
@ okoD Nie, poddaję się. Zmiana parametrów modułu cieniującego między każdym wywołaniem duszka SpriteBatchwymaga użycia trybu natychmiastowego, więc nie jest to warte kłopotu. Pójdę z tym :)
David Gouveia,

Odpowiedzi:

3

Powinieneś zastosować swój moduł cieniujący PO OBRÓBIE swojego duszka.

Jeśli cała scena nie została jeszcze zacieniona, a twoje duszki są w rzeczywistości pikselowane, potrzebujesz jakiegoś filtru post-FX dla całej sceny. Uśrednianie regionów pikseli będzie działać poprawnie. Nie jest to dokładnie to, co zamierzasz (będzie wyglądać trochę rozedrgano podczas przesuwania / obracania), ale może załatwić sprawę.

Jedynym sposobem, aby zachować wygląd retro zgodnie z tym, czego chcesz, jest samodzielne narysowanie rotacji duszka. Nie ma to nic wspólnego z tym, jak zaimplementowano skalowanie: rozdzielczość była w rzeczywistości słaba, a mówiąc o tym, czy próbowałeś z bardzo niskimi rozdzielczościami? Może to również załatwić sprawę i będzie wyglądać bardziej naturalnie, ponieważ, no cóż, to właśnie to spowodowało efekt, którego szukasz. I to jest tanie! Bardzo tani! W rzeczywistości będzie tańszy niż to, co już masz (mniej wykonywania shaderów fragmentów).

Efekt jest zrujnowany na twoim przykładowym obrazie, ponieważ twoja rozdzielczość jest wysoka w porównaniu do twoich duszków, więc pozwala zobaczyć prawdziwe piksele na scenie.

kaoD
źródło
Tak, nie używam jeszcze shaderów. To tylko zwykłe duszki z teksturami o bardzo niskiej rozdzielczości, renderowane z domyślnym XNA SpriteBatchz włączonym próbkowaniem punktowym. Ale post-fx może się naprawdę udać. Na początek spróbuję renderować z próbkowaniem liniowym do celu renderowania, a następnie wyrenderuję cały cel renderowania do bufora tylnego z próbkowaniem punktowym.
David Gouveia,
@DavidGouveia nie przegap okazji, aby rozpocząć swoją rozdzielczość. Jeśli naprawdę chcesz osiągnąć oryginalny efekt, jest to twój najlepszy strzał. Jeśli potrzebujesz wysokiej rozdzielczości (jeśli część twojego GFX jest w wysokiej rozdzielczości lub chcesz dopasować natywne rozdzielczości), możesz nadal renderować w buforze poza ekranem o niskiej rozdzielczości, a następnie pomalować go w buforze ramki wysokiej rozdzielczości jako pełny - quad ekranowy z wyłączonym filtrowaniem. Pamiętaj, że musisz dopasować proporcje, aby uniknąć prostokątnych pikseli.
kaoD
Sprawdź moją edycję :) Myślę, że to rozwiązało większość problemu, chociaż nadal jestem ciekawy, czy istnieje lepsze rozwiązanie próbkowania niż najbliższy sąsiad dla tego problemu. Pozwolę, by pytanie trwało dłużej.
David Gouveia,