Deutsch
Forum

OpenGL die Zweite: Anti Aliasing

 
- Seite 1 -



Sven
Bader
Hallo,

OpenGL in XProfan macht richtig Spaß, mit einer Sache bin ich aber noch nicht ganz zufrieden. Ich hätte gerne glatte Kanten (Antialisasing). Was man so im Netz findet sind die Anleitungen eigentlich immer gleich und gut in XProfan nachzustellen, leider wird auch zwischen den Polygonen, die eigentlich zusammengehören geglättet - das führt zu Löchern
Ich habe schon probiert, mit StartList/Endlist/Drawlist Dinge zu gruppieren, auch habe ich testweise große Teile des Codes mit API Aufrufen ersetzt.

Vielleicht passiert im Init-Befehl etwas, dass sich nicht damit verträgt?

Hat sich von euch schonmal jemand mit dem Thema befasst? Ich fände es auch für Spiele mit einfacher Grafik recht wichitg, es gehört irgendwie dazu.

Viele Grüße
Sven

Im wesentlichen ist das der Code, der den Objekten vorangestellt werden muss:
oGL("glBlendFunc",&GL_SRC_ALPHA, &GL_ONE_MINUS_SRC_ALPHA)
oGL("glEnable", &GL_BLEND)
oGL("glEnable", &GL_POLYGON_SMOOTH);
oGL("glHint", &GL_POLYGON_SMOOTH_HINT, &GL_NICEST);

Ein lauffähiges Komplettbeispiel ist hier, mit Leertaste lässt sich die Glättung an und ausschalten:
'$H OpenGL.ph
Def &GL_POLYGON_SMOOTH	$B41;
Def &GL_NICEST	$1102;
Def &GL_ONE_MINUS_SRC_ALPHA	$303;
Def &GL_SRC_ALPHA	 $302;
Def &GL_POLYGON_SMOOTH_HINT	$C53;
Def &GL_ONE	1;
Def &GL_BLEND	3042;

proc DrawGLScene

    oGL("Clear")
    oGL("Color", 1,1,1,1)

    if (aa% = 1)

        oGL("glBlendFunc",&GL_SRC_ALPHA, &GL_ONE_MINUS_SRC_ALPHA)
        oGL("glEnable", &GL_BLEND)
        oGL("glEnable", &GL_POLYGON_SMOOTH);
        oGL("glHint", &GL_POLYGON_SMOOTH_HINT, &GL_NICEST);

    else

        oGL("glDisable",&GL_POLYGON_SMOOTH)
        oGL("glDisable", &GL_BLEND)
        oGL("glBlendFunc",&GL_ONE, &GL_ONE)

    endif

    oGL("Origin", 0, 0, -4.0)
    oGL("Rotate", 0, 0, 22.5)
    oGL("Origin", -1.0, 0, -4.0)
    oGL("Quad", 2, 2)
    oGL("Origin", 1.0, 0, -4.0)
    oGL("sphere", 1,20,20)
    oGL("Show")

endproc

declare ende%, aa%
window 600,400
oGL("Init", %hWnd, 0.5, 0.5, 0.5, 0)
oGL("PosMode", 1)
aa% = 1
DrawGLScene()
ende% = 0

WhileNot ende%

    WaitInput

    if (%key = 32)

        sleep 200
        aa% = abs(aa% - 1)

    elseif (%key = 27)

        ende% = 1

    endif

    DrawGLScene()

EndWhile

oGL("Done")
end

Antialiasing AN, die Ränder sind ok, aber alle Schnittkanten haben Löcher





Standardzustand Antialiasing AUS, Schnittkanten ok, aber keine Glättung





Hack: Anti Aliasing per Grafiktreiber erzwungen, so sollte es aussehen




an.jpg  
27 kB
Bezeichnung:AA an
Hochgeladen:12.07.2021
Ladeanzahl66
Herunterladen
17 kB
Bezeichnung:AA aus
Hochgeladen:12.07.2021
Ladeanzahl66
Herunterladen
17 kB
Bezeichnung:AA über den Treiber erzwungen
Hochgeladen:12.07.2021
Ladeanzahl71
Herunterladen
13 kB
Hochgeladen:12.07.2021
Ladeanzahl69
Herunterladen
6 kB
Hochgeladen:12.07.2021
Ladeanzahl72
Herunterladen
5 kB
Hochgeladen:12.07.2021
Ladeanzahl60
Herunterladen
 
12.07.2021  
 



« Dieser Beitrag wurde als Lösung gekennzeichnet. »


Sven
Bader
Für meine Zwecke habe ich eine Lösung, die leider in jedem etwas komplexerem Umfeld scheitern wird.

Ich lege auf das ungeglättete Objekt ....



... das mit den glatten Kanten ...



... das Ergebnis ist wie gewüsncht



Zum einen ist es falsch und unperformant das ganze Objekt noch einmal zu zeichnen, zum anderen kann diese Methode zu anderen Problemen führen wenn das Objekt keine "culled faces" also unsichtbare Rückseiten hätte oder man je nach Beschaffenheit des Objekts Teile von sich selbst durch die Löcher sieht. Auch Kombination mit transparenten Objekten sorgt bei dieser Lösung für Durcheinander.

Interessant zu sehen ist, dass das Originalobjekt etwas kleiner ist und die Glättung außen dazu kommt - da fragt man sich, wie es überhaupt zu den Löchern im Innenbereich kommt ...

Eine Interessante Variante ist angwendetes Smoothing aber mit deaktiviertem Blending, so bekommt man das "größere" Objekt, aber das nur am Rande.





Liegt die Lösung einfach nur in der richtigen glBlendFunc(), welche letztendlich das tut, was ich mit zwei identischen Objekten nachbilde oder kann es etwas mit Buffern oder oGL Grundeinstellungen zu tun haben?

Hier der neue Code
 $H OpenGL.ph

proc DrawGLScene

    oGL("Clear")
    oGL("Color", 1,1,1,1)

    if (aa%)

        oGL("glDisable", ~GL_BLEND)
        oGL("glDisable", ~GL_POLYGON_SMOOTH)
        'Objekt mit harten Kanten
        oGL("Push")
        oGL("Rotate", 0, 0, 22.5)
        oGL("Origin", -1.0, 0, -4.0)
        oGL("Quad", 2, 2)
        oGL("Origin", 1.0, 0, -4.0)
        oGL("sphere", 1,30,30)
        oGL("Pop")
        oGL("glBlendFunc",~GL_SRC_ALPHA, ~GL_ONE_MINUS_SRC_ALPHA)
        oGL("glEnable", ~GL_POLYGON_SMOOTH)
        oGL("glEnable", ~GL_BLEND)
        'Gleiches Objekt geglätten darüber
        oGL("Push")
        oGL("Rotate", 0, 0, 22.5)
        oGL("Origin", -1.0, 0, -4.0)
        oGL("Quad", 2, 2)
        oGL("Origin", 1.0, 0, -4.0)
        oGL("sphere", 1,30,30)
        oGL("Pop")

    else

        oGL("glDisable", ~GL_BLEND)
        oGL("glDisable", ~GL_POLYGON_SMOOTH)
        oGL("Push")
        oGL("Rotate", 0, 0, 22.5)
        oGL("Origin", -1.0, 0, -4.0)
        oGL("Quad", 2, 2)
        oGL("Origin", 1.0, 0, -4.0)
        oGL("sphere", 1,30,30)
        oGL("Pop")

    endif

    oGL("Show")

endproc

declare ende%, aa%
window 600,400
oGL("Init", %hWnd, 0.5, 0.5, 0.5, 0)
oGL("PosMode", 1)
oGL("glHint", ~GL_POLYGON_SMOOTH_HINT, ~GL_NICEST);
ende% = 0
aa% = 1
DrawGLScene()

WhileNot ende%

    WaitInput

    if (%key = 32)

        sleep 200
        aa% = abs(aa% - 1)

    elseif (%key = 27)

        ende% = 1

    endif

    DrawGLScene()

EndWhile

oGL("Done")
end

1.png  
4 kB
Bezeichnung:1
Hochgeladen:19.07.2021
Ladeanzahl74
Herunterladen
2.png  
4 kB
Bezeichnung:2
Hochgeladen:19.07.2021
Ladeanzahl73
Herunterladen
3.png  
4 kB
Bezeichnung:3
Hochgeladen:19.07.2021
Ladeanzahl62
Herunterladen
4.png  
4 kB
Bezeichnung:4
Hochgeladen:19.07.2021
Ladeanzahl79
Herunterladen
 
19.07.2021  
 




Sven
Bader
Ich habe den Beitrag als gelöst deklariert obwohl es keine perfekte Lösung gibt.

Es ist wohl einfach so, dass die ursprüngliche Möglichkeit über GL_POLYGON_SMOOTH von heutigen Grafiktreibern nicht mehr korrekt behandelt wird und man auf zeitgemäßere (und komplexe) Technologien zurückgreifen sollte. Eine Lösungsansatz mit oldschool OpenGL wäre noch das mehrfache leicht versetzte Rendern in den Accumulation Buffer (glAccum), den habe ich auch schon erfolgreich für Motion Blur verwendet.
 
07.09.2021  
 



Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

2.635 Betrachtungen

Unbenanntvor 0 min.
Sven Bader07.03.2023
Alibre14.01.2023
Ernst29.05.2022
Thomas Zielinski07.10.2021
Mehr...

Themeninformationen

Dieses Thema hat 1 Teilnehmer:

Sven Bader (3x)


Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie