Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 20:17 Titel: [C/C++] Interpolation (Farbwerte - RBG) |
|
|
Hi,
folgendes kleines Problem:
Ich möchte eine Farbe 1 in eine Farbe 2 über einer bestimme Zeit faden lassen, RGBA-Komponenten sind einzeln verfügbar. Ich dachte nun an eine simple lineare Interpolation in der Form:
Code: | X = A*t + B*(1-t) 0 <= t <= 1 |
Problem was sich an dieser Stelle ergibt ist Folgendes:
Wenn ich alle Kanäle einzeln interpolier, so hat das für die endgültige Farbe einige ziemlich unangenehme Zwischenstufen zur Folge.
Bsp.: Wenn man rot langsam zu gelb werden lassen will, erwartet man rein intuitiv doch als Zwischentöne verschiedene Orangeabstufungen. Das scheint mit der Formell jedoch so nicht möglich zusein, weiß jemand Rat, bzw. hat eine bessere Formell zu bieten?
Es wäre auch kein Problem, die Farbe als einen Wert zu betrachten (unsigned long), für den Fall, dass jemand da einen super optimierten Algo kennt. 
Zuletzt bearbeitet von GreveN am 26.01.2006, 23:09, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 24.01.2006, 20:28 Titel: |
|
|
Deine Formel ist doch richtig so wenn du sie für jeden Channel verwendest. Rot(255,0,0) zu Gelb (255,255,0) funktioniert doch astrein Oo
t: 0
Grün = GEnd*t + GStart*(1-t)
Grün = 255
t: 0.5
Grün = GEnd*t + GStart*(1-t)
Grün = 128
t: 1
Grün = GEnd*t + GStart*(1-t)
Grün = 255 _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 20:32 Titel: |
|
|
*kratz*
Also entweder hab ich in der Implementierung ein Fehler gemacht... oder... naja...
Jedenfalls ist Wechsel von einer Farbe in eine andere immer scheinbar nicht fließend verlaufen, sondern die Pixel waren zwischendurch auch mal grün, blau,... daher hatte ich geschlussfolgert, dass man die Kanäle nicht einfach getrennt voneinander interpolieren kann... =/
Nungut, ich klemm mich nochmal dahinter...
Danke erstmal und hast du eventuell noch ein paar Ideen für mögliche Optimierungen? |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 24.01.2006, 20:44 Titel: |
|
|
Viel gibt es da nicht zu optimieren ausser evtl auf float/... zu verzichten aber früher oder später wirst du die sicher noch brauchen. _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 20:53 Titel: |
|
|
Ich muss zu meiner eigenen Schande gestehen, dass es scheinbar wirklich an mir liegt.
Die Logik gebietet ja auch, dass beim Übergang von rot (255; 0; 0) nach gelb (255; 255; 0) nur der 2. Kanal überhaupt verändert werden muss, was wiederum bedeutet, dass irgendwelche blau- und grün-Töne überhaupt nicht zustande kommen können.
Btw.: Wäre "Interpolation" nicht mal was interessantes für die FAQ?  |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 24.01.2006, 21:09 Titel: |
|
|
Wenn du dafür einen schönen Beitrag schreibst könnte man sich das überlegen  _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 21:16 Titel: |
|
|
Oha, Fehler lag wirklich bei mir.
Dummer kleiner Fehler in den Settings, reden wir nicht drüber.
Problem: Der Spaß kostet mich im Moment ca. 120 FPS, mal schauen was sich da noch drehen lässt. =/
Hm... könnte ich eigentlich machen, aber dann nicht nur lineare Interpolation.  |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 24.01.2006, 21:19 Titel: |
|
|
Wenn dann bitte auch mit Matrizen Interpolation (also von einer Transformationsmatrix in eine andere)
Also ums zu optimeiren: Ich würde das ja nicht von Hand machen, sondern DirectX oder OGL überlassen. Man kann ja zum Beispiel VertexFarben nehmen und die jedesmal leicht verändern (dürfte sehr viel schneller sein, als jede Textur einzelnt zu machen) und in OGL gibt es sicherlich entsprechendes.
Ist aber nur ne vermutung, da du ja nicht mal geshcirebne hast, wofür du das brauchst  _________________ https://jonathank.de/games/ |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 24.01.2006, 21:19 Titel: |
|
|
Das ist heftig muss aber dennoch nichts bedeuten  _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 21:36 Titel: |
|
|
CPP: | float age_div_life = ps->particles[i].age / ps->particles[i].life;
ps->particles[i].color.r = (unsigned char)((1.0f - age_div_life) * ps->start_color.r) + (age_div_life * ps->end_color.r);
ps->particles[i].color.g = (unsigned char)((1.0f - age_div_life) * ps->start_color.g) + (age_div_life * ps->end_color.g);
ps->particles[i].color.b = (unsigned char)((1.0f - age_div_life) * ps->start_color.b) + (age_div_life * ps->end_color.b);
ps->particles[i].color.a = (unsigned char)((1.0f - age_div_life) * ps->start_color.a) + (age_div_life * ps->end_color.a); |
Dieses Fatzelchen Code kostet mich - zugegeben grade im Stresstest ca. 4000x pro Frame ausgeführt - ca. 120FPS. Hat jemand von den paar offensichtlichen Optimierungsmöglichkeiten (Cast; Vorberrechnen; ...) noch ein paar Tipps?
p.s.: Bitte ausnahmsweise mal keine Meckereien betreffs Style usw., wird 'ne einfache Lib für 'nen Kumpel, der in Basic schreibt und deshalb muss ich auf einfaches C zurück greifen. |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 24.01.2006, 21:46 Titel: |
|
|
Die Funktion inlinen und wie evtl. mal gesagt auf float bei solchen Berechnungen verzichten.
evtl geht ja auch sowas:
endfarbe zuweisung:
CPP: | short lengthR = startFarbe.r-endFarbe.r;
short lengthG = startFarbe.g-endFarbe.g;
short lengthB = startFarbe.b-endFarbe.b;
short lengthA = startFarbe.a-endFarbe.a;
float t = 0; |
berechnung:
CPP: | aktuelleFarbe.r = startFarbe.r+lengthR*t;
aktuelleFarbe.g = startFarbe.g+lengthG*t;
aktuelleFarbe.b = startFarbe.b+lengthB*t;
aktuelleFarbe.a = startFarbe.A+lengthA*t; |
_________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
GreveN JLI Master

Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 24.01.2006, 22:24 Titel: |
|
|
So, hab das ganze System jetzt auf 'unsigned long' umgestellt und verwende Masken:
CPP: | unsigned long t = (unsigned long)((ps->particles[i].age / ps->particles[i].life) * 256);
ps->particles[i].color = (((ps->start_color&0xff0000) * t + (ps->end_color&0xff0000) * (256 - t)) >> 8) | (((ps->start_color&0x00ff00) * t + (ps->end_color&0x00ff00)* (256-t)) >> 8) | (((ps->start_color&0x0000ff) * t + (ps->end_color&0x0000ff) * (256 - t)) >> 8); |
Meine Hoffnungen, mich damit wenigstens wieder etwas den 160FPS vom Anfang zu nähern wurden leicht übertroffen... Sind jetzt 320.
p.s.: Ist aber noch ein kleiner Fehler drin, aber ich bin optimistisch.  |
|
Nach oben |
|
 |
|