antialiasing manuell (software-mode) nachprogrammieren.



  • hi leute!

    ich will in eine 2d-engine ein software-basiertes anti-aliasing implementieren.

    jetzt brauche ich tips für die theorie dahinter.

    ich habe einfach ein hintergrundbild, auf dass ein objekt aus einer BMP-datei geblittet wird. im objekt habe ich den RGB-wert FF00FF als durchsichtig definiert.

    momentan stelle ich mir das so vor:

    ich gehe jedes pixel des objekts durch, und wenn es nicht FF00FF entspricht (also sichtbar ist), werden die angrenzenden 8 pixel mit OR auf FFOOFF überprüft. wenn das stimmt (also ein angrenzendes pixel durchsichtig ist), wird das aktuelle pixel mit dem darunterliegenden pixel des hintergrundes addiert und durch 2 dividiert.
    ich denke mal die berechnung muss für jeden farbwert einzeln erfolgen, also Rot = Rot von vordergrung + Rot von hintergrund / 2.... usw.

    durch dieses vorgehen werden theorethischerweise die ränder des objekts verfälscht, aber ich denke mal wenn das ergebnis visuell anspricht kann man das hinnehmen.

    also, stimmt die theorie soweit? oder welche dinge habe ich noch zu beachten?

    mfg,

    ---loki



  • Anti-Aliasin ist eigentlich erst mal nichts weiter als das Weichzeichnen eines Bildes.

    Relativ simpel ist das hier : gehst jeden Pixel einzeln durch und errechnest mit seinen 8 Nachbarn den Durchschnittswert hierfür.
    Ein Median Filter beispielsweise sucht sich aus einem Fenster von 3*3 Pixeln den Wert aus, der in der Mitte aller enthaltenen Pixel ist und setzt ihn auf den mittelpunkt:

    Beispiel mit Grauwerten:

    .. | 60 | 64 | 61 | ..
    ---+----+----+----+---
    .. | 42 | 20 | 54 | ..
    ---+----+----+----+---
    .. | 58 | 62 | 47 | ..
    

    die Werte werden nun nach Größe sortiert:
    20, 42, 47, 54, 58, 60, 61, 62, 64

    Der Wert 58 ist aus der Liste der mittlere und wird jetzt in die Mitte des Fensters gesetzt:

    .. | 60 | 64 | 61 | ..
    ---+----+----+----+---
    .. | 42 |>58<| 54 | ..
    ---+----+----+----+---
    .. | 58 | 62 | 47 | ..
    

    Die Ergebnisse sollen toll sein - hab meine Webcam vergessen und kanns deshalb grade nicht ausprobieren. 🙄



  • DocJunioR schrieb:

    Anti-Aliasin ist eigentlich erst mal nichts weiter als das Weichzeichnen eines Bildes.

    Das ist nicht Anti-Aliasing.
    Beim Anti-Aliasing sampelt man das Bild beispielsweise vierfach (doppelte Breite, doppelte Höhe) und rechnet dieses Bild anschließend auf die Ausgangsgröße herunter. Was Du beschreibst, ist einfach nur ein Weichzeichner, aber kein Anti-Aliasing.

    siehe auch:
    http://de.wikipedia.org/wiki/Antialiasing



  • Hi!

    Stimmt beim Anti Aliasing (Multi Sampling) wird ein Bild vergößert, und anschließend auf die Ausgangsgröße gerendert.

    Wenn du hilfe brauchst schau mal hier rein:
    [url] www.spieleprogrammierer.de[/url]

    Es geht hier zwar um 3D aber ich bin mir sicher du findest hier hilfe.

    Wieso willst du es eigentlich Software - mäßig implementieren?

    mfg LastManStandind



  • LastManStanding schrieb:

    Hi!

    Stimmt beim Anti Aliasing (Multi Sampling) wird ein Bild vergößert, und anschließend auf die Ausgangsgröße gerendert.

    Nein. Das was du beschreibst ist Supersampling und ist EINE (zienlich schlechte) Möglichkeit Anti-Aliasing zu implementieren. D3D verwendet z.B. Multisampling.



  • Ist Antialiasing nicht einfach nur eine Faltung.

    Bye, TGGC (Wähle deine Helden)



  • *gg* also wenn ich bilder sehe, die aus einem Faltungsalgorithmus kommen, denk ich schon, dass sie einfach nur weicher gezeichnet sind 😉

    Was aber am Ende beim Antialiasing rauskommt sind einfach nur weiche Übergänge bei hohen Kontrasten. Wäre auch ne Möglichkeit, dieses "Weichzeichnen" nur da anzuwenden wo der Farbunterschied einen bestimmten Wert überschreitet.


  • Mod

    interpreter schrieb:

    LastManStanding schrieb:

    Hi!

    Stimmt beim Anti Aliasing (Multi Sampling) wird ein Bild vergößert, und anschließend auf die Ausgangsgröße gerendert.

    Nein. Das was du beschreibst ist Supersampling und ist EINE (zienlich schlechte) Möglichkeit Anti-Aliasing zu implementieren. D3D verwendet z.B. Multisampling.

    auch bei multisampling wird das bild in vielfacher auflösung gerendert und dann runterskaliert. informier dich über den wahren unterschied 😉

    DocJunioR schrieb:

    *gg* also wenn ich bilder sehe, die aus einem Faltungsalgorithmus kommen, denk ich schon, dass sie einfach nur weicher gezeichnet sind

    TGGC schrieb:

    Ist Antialiasing nicht einfach nur eine Faltung.

    😉

    rapso->greets();



  • Anhand der Stellung der Worte in dem Satz erkenne ich den Kommentar
    IST ANTI-ALIASING NICHT NUR EINE FALTUNG.
    Trotz des Punktes am Ende als Fragesatz.

    Wenn ich das jetzt fehlinterpretiert hab, dann liegts an meiner Brainware, die wurde seit Tagen nicht runtergefahren..



  • ok, nach nochmaliger untersuchung der wikipedia habe ich gemerkt, dass es verschiedene methoden gibt, mein ansatz aber scheinbar nicht dazugehört. das problem ist dass ich das ganze möglichst schnell (da nicht HW-beschleunigt) und wenn möglich speicher-sparend implementieren möchte.

    ich persönlich glaube zum beispiel, dass die methode mit dem vergrößern und dann wieder runtersampeln etwas zu krass ist für realtime-rendering.

    gibts da irgendwelche simplen methoden (auch wenn das ergebnis dann nicht so dolle ist) ?


  • Mod

    manche systeme (z.b. ps2) machen "edge antialiasing"

    dabei ist es wichtig dass man von hinten nach vorne zeichnet. das zeichnen der einzelnen elemente z.b. dreiecke läuft dann so ab, dass erst das innere gezeichnet wird (auf normale art und weise).
    danach (jetzt kommt's 😉 ) die kanten des elementes, dabei wird "line antialiasing" gemacht, das kann man ziemlich gut optimieren und muss schlussendlich auch keine vergrößerte version des ganzen bildes zeichnen, sondern mischt temporär pro linie.

    natürlich ist das ab einer gewissen anzahl von linien langsammer als normales MSAA.

    rapso->greets();



  • Was aber am Ende beim Antialiasing rauskommt sind einfach nur weiche Übergänge bei hohen Kontrasten. Wäre auch ne Möglichkeit, dieses "Weichzeichnen" nur da anzuwenden wo der Farbunterschied einen bestimmten Wert überschreitet.

    Anti-Aliasing hat absolut gar nichts mit Weichzeichnen zu tun.

    Offensichtlicher wird das ganze, wenn man das ganze aus dem Audio-Bereich kennt. Dann versteht man z.B. auch warum das überhaupt Aliasing heißt: Bei einer bestimmten Samplerate kann man maximal Frequenzen darstellen, die halb so hoch sind, wie die Samperate. Wenn man versucht eine höhere Frequenz darzustellen erhäklt man stattdessen einen Alias, der dem eigentlichen ton entspricht, nur um die halbe Samplerate gespiegelt (Nyquist-Frequenz). Solche Aliasse stören. Die lösung ist einfach eine höhere Samplerate zu nehmen (z.B. doppelt so hoch) und anschließend alle Frequenzen über der halben Ziel-Samplerate rauszufiltern und dann die Samplerate runterzurechnen.

    Bei der Bildbearbeitung ist es nicht anders. Dinge, die quasi eine zu hohe "Frequenz" für die Auflösung haben (sprich kleiner sind als ein Pixel) führen zu Aliasen (das Phänomen des Alias könnte man nur wirklich erkennen, wenn man das Bild in den Frequenz-Bereich transformieren würde). Wenn man eine höhere Auflösung verwendet sind Dinge, die vorher zu klein waren möglicherweise nicht mehr zu klein und passen nun auf einen Pixel.
    Kanten von Objekten sind quasi unendlich dünn. Deswegen kann man sie auch durch Oversampling nie komplett Alias-frei halten. Dennoch kann man die Qualität deutlich verbessern.



  • [quote="rapso"
    auch bei multisampling wird das bild in vielfacher auflösung gerendert und dann runterskaliert. informier dich über den wahren unterschied 😉
    [/quote]
    Quellen? Bei Multisampling wird eben nicht in höherer Auflösung gerendert.


  • Mod

    interpreter schrieb:

    rapso schrieb:

    auch bei multisampling wird das bild in vielfacher auflösung gerendert und dann runterskaliert. informier dich über den wahren unterschied 😉

    Quellen?

    informier dich einfach. nvidia.com ati.com usw.

    interpreter schrieb:

    Bei Multisampling wird eben nicht in höherer Auflösung gerendert.

    sind wir im kindergarten?
    doch
    nein
    doch
    nein

    rapso->greets();



  • rapso schrieb:

    informier dich einfach. nvidia.com ati.com usw.

    Ich habe meine Infos aus der DX9 Doku. Die Infos da sollten wohl stimmen, oder?



  • @loki:

    Wie wäre es mit einem Alphakanal für die Bitmap? Entweder Du tust ihn schon im Grafikprogramm dazu oder erechnest ihn beim Laden der Bitmap. Benötigt zwar 33% mehr Speicher, aber dafür ersparst Du Dir die ganzen Vergleiche beim blitten.


  • Mod

    interpreter schrieb:

    rapso schrieb:

    informier dich einfach. nvidia.com ati.com usw.

    Ich habe meine Infos aus der DX9 Doku. Die Infos da sollten wohl stimmen, oder?

    die infos stimmen, vielleicht aber deine interpretation davon nicht, oder dein englisch.

    schau dir einfach diese presentation von nvidia an, die haben sogar bunte bildchen die das verdeutlichen dass auch bei msaa der framebuffer in vielfacher größe existiert.

    rapso->greets();


  • Mod

    0x00000001 schrieb:

    @loki:

    Wie wäre es mit einem Alphakanal für die Bitmap? Entweder Du tust ihn schon im Grafikprogramm dazu oder erechnest ihn beim Laden der Bitmap. Benötigt zwar 33% mehr Speicher, aber dafür ersparst Du Dir die ganzen Vergleiche beim blitten.

    die vergleiche beim blitten resultieren in zwei "and" und einem "or". beim blenden müßte er hingegen 2"mul" und ein "add" haben.

    aber er hätte weniger aliasing, da hast du recht 😉

    rapso->greets();



  • 0x00000001 schrieb:

    @loki:

    Wie wäre es mit einem Alphakanal für die Bitmap? Entweder Du tust ihn schon im Grafikprogramm dazu oder erechnest ihn beim Laden der Bitmap. Benötigt zwar 33% mehr Speicher, aber dafür ersparst Du Dir die ganzen Vergleiche beim blitten.

    auch keine schlechte idee.... ich denke das teste ich mal aus.

    dürfte ja fast meiner ersten überlegung entsprechen.



  • rapso schrieb:

    die vergleiche beim blitten resultieren in zwei "and" und einem "or". beim blenden müßte er hingegen 2"mul" und ein "add" haben.

    Versteh ich nicht. 2 AND und 1 OR? Er muss doch die Pixel in der Nachbarschaft anschauen ob die transparent sind. Wenn man das ganz naiv implementiert hat man schonmal 8 Vergleiche.
    Mit dem alphakanal hat man zwar die langsameren operationen, aber dafür nur einmal pro Pixel.

    Erklär mal bitte genauer wie Du das meinst, ich komm nicht drauf 🙂


  • Mod

    0x00000001 schrieb:

    rapso schrieb:

    die vergleiche beim blitten resultieren in zwei "and" und einem "or". beim blenden müßte er hingegen 2"mul" und ein "add" haben.

    Versteh ich nicht. 2 AND und 1 OR? Er muss doch die Pixel in der Nachbarschaft anschauen ob die transparent sind. Wenn man das ganz naiv implementiert hat man schonmal 8 Vergleiche.
    Mit dem alphakanal hat man zwar die langsameren operationen, aber dafür nur einmal pro Pixel.

    Erklär mal bitte genauer wie Du das meinst, ich komm nicht drauf 🙂

    da er ja auf geschwindigkeit aus ist, unterstell ich ihm dass er das möglichst schnell machen möchte.

    eine möglichkeit wäre

    im main loop

    for(u32 a=0;a<pixelzahl;a++)
    {
      u32 MaskIndex = (pScreen[a]==ALPHAPIXEL);
      MaskIndex--;
    //hier die 2und und ein or, kann man mit mmx schneller machen, oder cmov
    //man sparrt zwar den vergleich nicht, doch der kostet kaum was,
    //was man einsparrt ist ein conditionaljump was auf nem p4 bis zu 30takte kostet
      pOut[a]  = (pScreen[a]&MaskIndex) | (pOut[a]&(MaskIndex^0xffffffff)); 
    }
    

    rapso->greets();


Anmelden zum Antworten