Alpha blending

21 czerwca 2008

Potrzebowałem uzyskać jak najprostszym sposobem efekt alpha blendingu, a z racji, że nie miałem o tym pojęcia, i nadal zbytnio nie mam o grafice 2/3D próbowałem zaczerpnąć informacji w niezliczonych zasobach sieciowych ;)

Szukałem jakiegoś prostego sposobu wyznaczania średniej wartości składowej koloru danego piksela. W różnych źródłach znalazłem kilka różnych działań obliczających tą wartość, od bardzo prostych i wydajnych, to złożonych i ociężałych.

Poniżej kilka znalezionych wersji ;)

Mała legenda: r to wynikowa średnia wartość danej składowej koloru, s jest składowa źródłowa, a d docelowa, blend to stopień przenikalności z przedziału 0...255.

Pierwsze znaleziony wynik to:

r = (blend * ((s + 64) - d)) / 256 + d - (blend / 4)

Jak widać czyste samobójstwo i zarzynanie procesora, tyle operacji, a w tym dwa dzielenia, z czego jeden można by buforować.

Następnie było kilka ciekawych wyników, ale nie różniły one się specjalnie od tych znalezionych przypadkiem w źródłach Mesa 3D, biblioteki graficznej 3D.

Szybkie, mniej dokładne:

r = (s * blend + d * inv + 1) >> 8

Powolniejsze, dokładniejsze:

r = (s * blend + d * inv) / 255

gdzie inv to ‘odwrócony’ blend:

Inv = 255 - blend

Idąc dalej, typowe działanie szeroko stosowane:

r = ((s - d) * blend) / 255 + d

Jak wiadomo dzielenie jest dosyć kosztowną operacją w porównaniu do pozostałych prostych działań, dlatego niektórzy zamiast dzielenia wykorzystują przesunięcia bitowe, które są o wiele szybsze niż inne operacje.

x / 255 = ((x << 8) + x + 256) >> 16

No i wreszcie dochodzimy do najbardziej optymalnej metody:

r = (s - d) * (blend/255) + d

Wartość blend/255 jest stała dla danej wartości przeźroczystości, przez co możemy ja zbuforować i w pętli obliczającej kolory wszystkich pikselów obrazka wykonujemy tylko bardzo proste i szybkie działanie (s - d) * x + d, które nosi nazwę interpolacji liniowej.

Warto jeszcze wspomnieć, że w obecnych kartach graficznych interpolacja liniowa wykonywana jest w GPU w jednym cyklu/rozkazie.

Temat ten zahaczyłem głównie z powodu braku w wxImage jakiejś prostej funkcji do uzyskania blendingu danego obrazka z innym, bądź jakimś kolorem, co bardzo mi się przydałoby.
Może patcha napisze, bo aktualnie można jedynie pokombinować z alpha i nakładaniem dwóch obrazków na kontekście urządzenia ;)

Podobne notatki:

Może zainteresują Cię również następujące, pododbne notatki:

Komentarze i nawiązania (2)

Kanał RSS komentarzy

  1. Hej, co do liczenia na procesorze to możesz również się skusić na użycie jednostek SSE. W bibliotekach Microsoftu są intrinsic’i do tego: http://msdn.microsoft.com/en-us/library/y0dh78ez(VS.80).aspx – może się przyda

    Ogólnie to masz ciekawy blog :)

    Pozdrawiam

  2. Ciekawe, choc w asmie sie malo bawie :(

    A blog jak devblog, w sumie tez nic ciekawego sie nie dzieje, bo nie ma czasu i tematow :P

Dodaj swój komentarz

Możesz użyć tych tagów XHTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Jeśli chcesz wstawić kilku linijkowy fragment kodu, użyj tagów <pre lang="x"></pre> (gdzie x język kodu np. cpp, perl, html). W ten sposób kod zostanie odpowiednio sformatowany i pokolorowany przez system.

Uwaga!

Na tym blogu działa system cache oraz filtr antyspamowy. Twój komentarz może być widoczny na stronie z pewnym opóźnieniem. Proszę o cierpliwość. Jeśli utraciłeś już wszystkie jej zasoby poinformuj mnie o tym, być może system uznał Cię za spamera ;)