Die Community zu .NET und Classic VB.
Menü

OpenGL in Visual Basic - Transparenz

 von 

Einleitung 

Nachdem wir nun ein wenig praktische Erfahrung im Erstellen von 3D-Objekten gesammelt haben, kommen wir zu dem wohl bekanntesten Spezialeffekt von OpenGL - der Transparenz. Nun ist Transparenz eigentlich kein eigener Effekt. Um Flächen mehr oder weniger durchsichtig zu gestalten, verwenden wir eine Technik, die sich Blending nennt. Genau genommen verwenden wir Alpha-Blending.
Was aber ist Alpha-Blending?


Abbildung 1: Auch wenn es kaum zu erkennen ist: Der Würfel ist hier teilweise durchsichtig!

Grundlagen  

Alpha-Blending ist die Addition zweier Farben unter Einbeziehung ihrer Transparenz. Dazu müssen wir unser derzeitiges Farbmodell verändern. Alle Farben, die wir bisher benutzten, hatten das RGB-Format. Nun kommt ein weiterer Wert hinzu - der Alphawert. Die meisten Leute stellen sich den Alphawert einfach als eine Angabe über die Transparenz eines Materials vor. Dieser reicht von 0 (durchsichtig) bis 1 (undurchsichtig). Diese Vorstellung stimmt zwar nicht so ganz genau, wird uns aber zur Zeit genügen. Haben wir bisher unsere Farben mit glColor3f definiert, verwenden wir jetzt glColor4f und hängen als 4. Parameter den Alpha-Wert an. Blending wird in OpenGL recht einfach aktiviert: glEnable glcBlend
Davor müssen wir OpenGL aber noch mitteilen, wie es mit den Flächen umgehen soll, und hier wird es etwas kompliziert.

Alle, die mit Mathematik etwas auf Kriegsfuß stehen, lesen bitte über die Formeln hinweg und testen das Ganze später einfach mit verschiedenen Einstellungen.

Sehen wir uns zuerst an, was OpenGL eigentlich bei eingeschaltetem Blending überhaupt tut.
Die Berechnung läuft nach folgender Formel:
R, G, und B sind die Farbwerte, A ist der Alphawert. Die S-Bezeichner stellen das Pixel der Quelle (Source) und die D-Bezeichner das Pixel des Ziels (Destination) dar. Das Ziel ist dabei keine 3D-Welt, sondern die bis dahin gerenderte Grafik im Puffer.

(Rs Sr + Rd Dr,
Gs Sg + Gd Dg,
Bs Sb + Bd Db,
As Sa + Ad Da)

Vielleicht haben Sie das nicht alles auf Anhieb verstanden, doch das soll uns im Moment nicht weiter stören.
Eigentlich werden nur 4 Werte addiert. Nehmen wir für den Quellbereich einfach den Alpha-Wert der Quelle (neues Pixel) und nennen das As sowie für den Zielbereich 1 - As, dann ergibt sich folgende Formel:

(Rs As + Rd (1 - As),
Gs As + Gd (1 - As),
Bs As + Bs (1 - As),
As As + Ad (1 - As))

Im Ergebnis wird das einen transparenten Effekt haben. Je kleiner der Alpha-Wert der Quelle ist, um so transparenter wird diese dargestellt. Dazu möchte ich hier noch eine Tabelle vorstellen, welche die entsprechenden Konstanten aus OpenGL enthält und aufzeigt, wie diese wirken:

Konstante Berücksichtigte Faktoren Berechneter Blend-Faktor
GL_ZERO Source oder Destination (0, 0, 0, 0)
GL_ONE Source oder Destination (1, 1, 1, 1)
GL_DST_COLOR Source (Rd, Gd, Bd, Ad)
GL_SRC_COLOR Destination (Rs, Gs, Bs, As)
GL_ONE_MINUS_DST_COLOR Source (1, 1, 1, 1)-(Rd, Gd, Bd, Ad)
GL_ONE_MINUS_SRC_COLOR Destination (1, 1, 1, 1)-(Rs, Gs, Bs, As)
GL_SRC_ALPHA Source oder Destination (As, As, As, As)
GL_ONE_MINUS_SRC_ALPHA Source oder Destination (1, 1, 1, 1)-(As, As, As, As)
GL_DST_ALPHA Source oder Destination (Ad, Ad, Ad, Ad)
GL_ONE_MINUS_DST_ALPHA Source oder Destination (1, 1, 1, 1)-(Ad, Ad, Ad, Ad)
GL_SRC_ALPHA_SATURATE Source (f, f, f, 1) / f=min(As, 1-Ad)

Abbildung 2: Konstanten für Blending

Das erschlägt Sie vermutlich etwas, aber mit ein wenig Experimentieren kommen Sie schnell hinter die Möglichkeiten. An OpenGL übergeben wird das Ganze mit der Funktion glBlendFunc. Diese erwartet als Parameter die Konstanten für Quelle und Ziel.

Bevor wir jetzt endlich so richtig loslegen, noch eine Kleinigkeit:
Transparente Flächen müssen immer zuletzt gerendert werden. Damit nicht genug müssen sie auch noch in der umgekehrten Reihenfolge ihrer Tiefe gezeichnet werden, sonst kommt es zu unschönen Artefakten. Das kann den Spaß an Transparenz ein wenig verderben, lässt sich aber leider nicht ändern.

Praxis  

Wir verwenden für ein Beispielprojekt unseren Würfel aus Kapitel 5. Allerdings habe ich die Oberseite, die jetzt transparent werden soll, herausgenommen und mit einer eigenen Textur versehen. Die wenigen neuen Anweisungen stellen keine Herausforderung dar und so ist hier nur der relevante Teil der Sub Main aufgelistet.

glBegin bmQuads 'Ein Würfel ohne Deckel
  glColor4f 0.5, 0.5, 0.5, 1 'mittel Grau für Ausleuchtung / volles Alpha = undurchsichtig
  glNormal3f 0#, 1#, 0# 'Normale der Oberseite zeigt positiv entlang der Y Achse
  glTexCoord2f 1#, 1#: glVertex3f 1#, 1#, -1# 'Oben Rechts (Oberseite)
  glTexCoord2f 0#, 1#: glVertex3f -1#, 1#, -1# 'Oben Links (Oberseite)
  glTexCoord2f 0#, 0#: glVertex3f -1#, 1#, 1# 'Unten Links (Oberseite)
  glTexCoord2f 1#, 0#: glVertex3f 1#, 1#, 1# 'Unten Rechts (Oberseite)
  glNormal3f 0#, -1#, 0# 'Normale der Unterseite zeigt negativ entlang der Y Achse
  glTexCoord2f 1#, 1#: glVertex3f 1#, -1#, 1# 'Oben Rechts (Unterseite)
  glTexCoord2f 0#, 1#: glVertex3f -1#, -1#, 1# 'Oben Links (Unterseite)
  glTexCoord2f 0#, 0#: glVertex3f -1#, -1#, -1# 'Unten Links (Unterseite)
  glTexCoord2f 1#, 0#: glVertex3f 1#, -1#, -1# 'Unten Rechts (Unterseite)
  glNormal3f 0#, 0#, 1# 'Normale der Vorderseite zeigt positiv entlang der Z Achse
  glTexCoord2f 1#, 1#: glVertex3f 1#, 1#, 1# 'Oben Rechts (Vorderseite)
  glTexCoord2f 0#, 1#: glVertex3f -1#, 1#, 1# 'Oben Links (Vorderseite)
  glTexCoord2f 0#, 0#: glVertex3f -1#, -1#, 1# 'Unten Links (Vorderseite)
  glTexCoord2f 1#, 0#: glVertex3f 1#, -1#, 1# 'Unten Rechts (Vorderseite)
  glNormal3f 0#, 0#, -1# 'Normale der Rückseite zeigt negativ entlang der Z Achse
  glTexCoord2f 0#, 0#: glVertex3f 1#, -1#, -1# 'Unten Links (Rückseite)
  glTexCoord2f 1#, 0#: glVertex3f -1#, -1#, -1# 'Unten Rechts (Rückseite)
  glTexCoord2f 1#, 1#: glVertex3f -1#, 1#, -1# 'Oben Rechts (Rückseite)
  glTexCoord2f 0#, 1#: glVertex3f 1#, 1#, -1# 'Oben Links (Rückseite)
  glNormal3f -1#, 0#, 0# 'Normale der linke Seite zeigt negativ entlang der X Achse
  glTexCoord2f 1#, 1#: glVertex3f -1#, 1#, 1# 'Oben Rechts (Links)
  glTexCoord2f 0#, 1#: glVertex3f -1#, 1#, -1# 'Oben Links (Links)
  glTexCoord2f 0#, 0#: glVertex3f -1#, -1#, -1# 'Unten Links (Links)
  glTexCoord2f 1#, 0#: glVertex3f -1#, -1#, 1# 'Unten Rechts (Links)
glEnd

glBindTexture GL_TEXTURE_2D, Texture(2) 'Auswahl der gewünschten Textur

glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA 'Alpha-Blending für einfache Transparenz
glEnable glcBlend 'Blending einschalten

glBegin bmQuads 'Deckel
  glColor4f 1#, 1#, 1#, 0.2 'volle Ausleuchtung und 80% transparent
  glNormal3f 1#, 0#, 0# 'Normale der rechten Seite zeigt positiv entlang der X Achse
  glTexCoord2f 1#, 1#: glVertex3f 1#, 1#, -1# 'Oben Rechts (Rechts)
  glTexCoord2f 0#, 1#: glVertex3f 1#, 1#, 1# 'Oben Links (Rechts)
  glTexCoord2f 0#, 0#: glVertex3f 1#, -1#, 1# 'Unten Links (Rechts)
  glTexCoord2f 1#, 0#: glVertex3f 1#, -1#, -1# 'Unten Rechts (Rechts)
glEnd 'Ende des Deckels

glDisable glcBlend 'Blending ausschalten

Listing 1: Transparente Flächen erzeugen

Es geht weiter  

Das waren die Grundlagen zum Alpha-Blending. Damit ist das Thema Blending allerdings noch lange nicht erschöpft. Blending kann auch auf Grundlage der RGB-Werte betrieben werden und macht viele exzellente Effekte mit übereinander liegenden Texturen möglich. Darauf werde ich aber erst in einem späteren Kapitel genauer eingehen. Im Kapitel 7 verlassen wir die fest im Quellcode verankerten Objekte und sehen, wie man dynamische Welten kreiert.

Beispielprojekt  

Beispielprojekt zum Tutorial [404382 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.