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.
|