OpenGL.org 3Dsource.de: Infos rund um 3D-Computergrafik, OpenGL und VRML
space Telefon-Tarife space VDI - Arbeitskreis Fahrzeugtechnik space Beschallungsanlagen und Elektroakustik space Heise-News space

15 Transparenz und Blending

15.010 Was ist der Unterschied zwischen Transparenz, Durchsichtigkeit und Blending ? Kann ich diese Effekte kombinieren ?

Ein physikalisch transparenter Stoff zeigt von ihm verdeckte Objekte deutlich erkennbar und reflektiert auch kein Licht. Klares Glas erfüllt in etwa diese Idealvorstellung, reflektiert aber auch einen Teil des einfallenden Lichts. Im absoluten Idealfall wäre ein transparenter Stoff unsichtbar.

Ein durchsichtiger Stoff (translucent) zeigt von ihm verdeckte Objekte nicht mehr unverändert, sondern verdunkelt Objekte oder verringert die klare Erkennbarkeit. Ausserdem wird ein Teil des einfallenden Lichts reflektiert, der durchsichtige Stoff dadurch sichtbar. Beispiele hierfür sind durchscheinende Bekleidung, dünnes Plastik oder Milchglas.

Die Begriffe Transparenz und Durchsichtigkeit (Translucency) werden meist identisch verwendet. Treffen beide Eigenschaften nicht auf das Material zu, so spricht man von undurchsichtigem Material (opaque).

Das Blending beschreibt den Möglichkeit, mit OpenGL die Farbwerte verschiedener Objekte miteinander zu kombinieren. Die Farbe des als nächstes gezeichneten Primitives wird zu dem vorhandenen Farbwert im Framebuffer auf bestimmte Weise addiert. Damit ist es möglich, durchlässiges Material mit der OpenGL darzustellen. Ein Beispiel dafür kann die Windschutzscheibe eines Fahrzeugs sein, die zuletzt gezeichnet wird und durch das Blending die dahinterliegenden Konturen des Fahrers undeutlicher macht.

15.020 Wie erhalte ich einen Transparenzeffekt ?

Die OpenGL bieten keinen direkten Zugriff auf die Darstellung von Objekten als durchsichtige Körper. Der Effekt kann aber durch das Blending und entsprechender Anordnung bzw. Zeichungsreihenfolge der Objekte nachgebildet werden (die nächste Frage kann auch weiterhelfen).

Das Blending wird wie folgt aktiviert:

    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Die Farbe jedes nachfolgend gezeichneten Primitives wird nun durch die bereits im Framebuffer vorhandenen Farbwerte verändert. Dabei bestimmt glBlendFunc() die Berechnungsmethode. Das "Mischungsverhältnis" der Farbwerte wird dabei durch die Alpha-Werte der vorhandenen Farbwerte im Framebuffer (alpha mal Farbwert) und den Alpha-Werten des gezeichneten Primitives (alpha-1 mal Farbwert) bestimmt. Die Summe dieser veränderten Farbwerte ist der endgültige Farbwert des betreffenden Pixels.

Die Angabe der Farb- und Alphawerte für ein Primitive erfolgt mittels glColor4*(R,G,B,A), wobei A(lpha) die Undurchsichtigkeit [0..1]bestimmt.

Wenn man den Z-Buffer nutzt, hat die Zeichnungsreihenfolge der einzelnen Objekte einen wesentlichen Einfluss auf die endgültige Darstellung der Szene. Zunächst sind daher die undurchsichtigen Objekte, dann die teilweise durchsichtigen, beginnend bei der grössten Entfernung, zu zeichnen. Wird diese Ordnung nicht berücksichtigt, kann ein normalerweise sichtbares Objekt auch durch ein davorliegendes, teilweise durchsichtiges Objekt vollständig verdeckt werden.

15.030 Wie erhalte ich eine unterbrochene Durchlässigkeit ?

Dies kann durch ein Polygon Stipple Muster erreicht werden (vergleichbar zu einer gestrichelten Linie in einer Technischen Zeichnung). Hierzu ist der Befehl glEnable(GL_POLYGON_STIPPLE) auszuführen. Die Anzahl der gesetzten Bits in dem Muster bestimmt dann den Grad der (Un)Durchsichtigkeit, je mehr Bits gesetzt sind, desto mehr wird das Objekt undurchsichtig. Der Vorteil dieser Lösung besteht in der Unabhängigkeit von der Zeichnungsreihenfolge.

15.040 Wie kann ich Glas mit OpenGL nachbilden ?

Diese Frage ist nicht ganz eindeutig zu beantworten, da es von der Betrachtungsweise des Einzelnen abhängt, wie Glas auszusehen hat. Im folgenden wird deshalb nur ein allgemeiner Algorithmus angegeben.

Zunächst sollten alle undurchsichtigen Objekte der Szene gezeichnet werden. Dann ist das Licht abzuschalten, das Blending zu aktivieren und das glasähnliche Objekt mit einem kleinen Alpha-Wert zu zeichnen. Dadurch sollte das Glas als kaum erkennbares Objekt in den Framebuffer gezeichnet werden. Die Reihenfolge der Objekte (mit jeweils abnehmender Entfernung zeichnen) spielt auch hier eine Rolle.

Jetzt ist der Oberflächenglanz hinzuzufügen (Specular Lighting). Ambientes und diffuses Material wird als schwarz, direkt reflektierende Flächen und die Lichtfarbe als weiss definiert. Nun wird die Tiefenfunktion auf glDepthFunc(GL_EQUAL) gesetzt und das glasähnliche Objekt ein zweites mal gezeichnet.

15.050 Muss ich meine Objekte von fern zu nah zeichnen, um eine korrekte Darstellung von halbdurchlässigen Primitiven zu erreichen ?

Falls die Hardware Destination Alpha unterstützt, kann man einmal verschiedene Werte für glBlendFunc() ausprobieren, die auf diese spezielle Technik zurückgreifen. Allerdings ist nicht davon auszugehen, dass der völlige Verzicht auf Sortierung der Objekte ohne Darstellungsfehler möglich ist. Die Zeichnungsreihenfolge sollte also wo immer möglich von fern zu nah realisiert werden.

15.060 Ich möchte Blending nutzen, aber Destination Alpha arbeitet nicht. Kann ich Blending oder Transparenz trotzdem nutzen ?

Viele OpenGL Implementationen unterstützen kein Destination Alpha. Unter anderem die OpenGL 1.1 Bibliotheken von Microsoft bieten keine Unterstützung, da es durch die Spezifikation nicht gefordert wird.

Um herauszufinden, ob das vorhandene OpenGL System diese Technik unterstützt, kann man beim Erzeugen des Fensters einfach danach fragen. Das geht mit GLUT z.B. durch den Parameter GLUT_ALPHA für glutInitDisplayMode(). Danach wird Blending wie folgt aktiviert:

    glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA);

Der Hintergrund für die Frage ist oftmals darin zu finden, dass man Destination Alpha als Voraussetzung für Blending ansieht, was allerdings nicht zutrifft. Man kann Blending problemlos auch mit Source Alpha anstatt Destination Alpha realisieren. Das Red Book bietet im Kapitel 6 weitere Informationen zum Blending.

15.070 Wenn ich ein halbdurchlässiges Objekt zeichne, müsste ein anderes dahinter ja zu sehen sein. Aber es ist nichts zu erkennen. Warum ?

Eine Gegenfrage sei erlaubt: Ist der Tiefenbuffer aktiviert ? ;-)

Falls Du ein Polygon zeichnen willst, das hinter einem anderen Objekt liegt und der Tiefentest aktiviert wurde, dann wird das zweite, vom anderen Objekt verborgene Polygon gar nicht erst gezeichnet werden und damit auch kein Blending eintreten. Andererseits wird das Blending bei abgeschaltetem Tiefentest immer durchgeführt, auch wenn das durch die rämliche Anordnung der Polygone das eigentlich nicht gar nicht beabsichtigt ist. Die Reihenfolge des Zeichnens von hinten nach vorn sollte daher soweit möglich immer eingehalten werden (siehe Frage 15.020).

15.080 Wie kann ich einen Teil meiner Textur durchsichtig oder halbdurchlässig darstellen ?

Das hängt davon ab, was man genau erreichen will.

Soll das Blending für ein bereits texturiertes Objekt genutzt werden, kann man das OpenGL Blending nutzen, z.B. so:

    glEnable (GL_BLEND);
    glBlendFunc (GL_ONE, GL_ONE);

Man kann für das Blending die Alpha-Werte der Textur nutzen, z.B. mit diesem Parameter: GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA.

Um allerdings den Effekt zu erreichen, dass die Farbe eines Objektes teilweise durch die darüberliegende Textur durchscheint, kann das OpenGL Blending nicht mehr genutzt werden. Hierfür eignet sich aber glTexEnv() in Verbindung mit dem Texture Environment Modus GL_BLEND. Hier sollte man die Grundfarbe der Textur auf Weiss (0,0,0,0) einstellen.

Seite durchsuchen nach:

Fragen oder Ideen an:
Thomas.Kern@3Dsource.de
Linux-Counter
(C) Thomas Kern