'mnożenie' kolorów

0

W kolorowej grafice często mamy do czynienia ze skalowaniem, formalnie z interpolacją kolorów.

Najprostszym przykładem jest ten zwykły gradient, czyli te takie popularne cieniowanie na ekranie,
od jasnego do ciemnego, a w ogólności przejście pomiędzy dwoma dowolnymi kolorami, w zadanym kawałku ekranu.

np.: zielony(0,1,0)--------------zielono-czerwony---------------> czerwony(1,0,0)

na ekranie: kolor = rgb = (r,g,b), gdzie r,g,b = 0...255;
w sumie 3 bajty, no ale że int32 ma 4B, więc kolory mają obecnie prawie zawsze: 4B = 32 bity - sprzętowo,

W związku z tym mam taki problemik:
jak wyliczyć najszybciej kolor pośredni z dwóch danych - krańcowych, tz.:

c = k*a + b(1-k); gdzie k = 0..255; oraz kolory mają r,g,b także z 0-255, ale są trzymane w int32 - z przyczyn obiektywnych.
rgb = (r,g,b,0); po prostu, 4-ty bajt = 0.

1

traktuj trzy kanały jako osobne sygnały, więc wyliczasz trzy wartości pośrednie niezależnie.

mam jednak wątpliwości, czy model RGB jest do tego odpowiedni. być może lepszy efekt wizualny będzie, jeśli zamiast RGB będziesz liczył na HSV (czyli najpierw RGB->HSV, potem interpolacja na trzech składowych niezależnie, HSV->RGB)

powyższe to tylko takie przemyślenia. nigdy tego nie robiłem.

0
Azarien napisał(a):

traktuj trzy kanały jako osobne sygnały, więc wyliczasz trzy wartości pośrednie niezależnie.

Mi chodziło właśnie o coś odwrotnego, tz. żeby jednym mnożeniem int32 załatwić te trzy kolory naraz...

No ale to chyba nie przejdzie - co najwyżej na mmx, czy też obecnie już na sse.

przykładowo:
gradient od czerwonego do niebieskiego, czyli od (255,0,0) do (0,0,255);

wtedy mamy: a = 0x0000FF, b = 0xFF0000;

i kolor pośredni z obu jest taki: c = k*b + (1-k)*a; gdzie k=<0..1>;
w szczególności dla k = 0.5, mamy środek: c = (127,0,127); jakiś tam fioletowy...

ale lepiej tak to obliczać: kb+(1-k)a = kb + a - ka = a + k(b-a);
i teraz mamy już tylko jedno mnożenie, zamiast dwóch.

w tym przypadku:
d = b-a = (-255, 0, 255); co się nam nie pomieści w 8 bitach... niestety.

a + 0.5d = (255, 0, 0) + 0.5(-255, 0, 255) = (255, 0, 0) + (-127, 0, 127) = (128, 0, 127);

1 użytkowników online, w tym zalogowanych: 0, gości: 1