[SOLVED] Überbeleuchtung mit Blending

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
PlainOldCJ
Beiträge: 11
Registriert: 03.12.2012, 20:56
Echter Name: Christian

[SOLVED] Überbeleuchtung mit Blending

Beitrag von PlainOldCJ »

Hi,

momentan hänge ich an der Implementierung einer einfachen Multi-Pass Beleuchtung und hoffe, dass
ihr mir helfen könnt :)
Wie im Bild zu sehen,
ist die Beleuchtung für den linken Mesh korrekt, während der rechte Mesh deutlich überbeleuchtet ist.
Die Meshes wurden mit unterschiedlichen Methoden erzeugt, wobei bei der zweiten vermutlich etwas
schief geht.
Leider weiss ich überhaupt nicht, was das sein könnte.
Folgende mögliche Fehlerursachen habe ich überprüft:
Die Normalenvektoren sind korrekt, das heisst die Richtungen stimmen und sie sind normalisiert.
Zudem habe ich die vom Pixelshader zurückgegebene Farbe komponentenweise auf [0, 1] geclamped.
Die beiden Meshes im Bild wurden übrigends völlig unabhängig voneinander gerendert und nicht im gleichen
Frame.

Was wären noch mögliche Fehlerquellen?

Meine Implementierung sieht in Pseudocode so aus:

Code: Alles auswählen

RenderAmbientPass();

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);

forall(lights in scene) {
  RenderDiffusePass();
}

glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
Seltsamerweise stimmt die Beleuchtung zumindest für die letzte Lichtquelle, wenn ich glBlendFunc(GL_ONE, GL_ZERO) setze oder Blending
direkt deaktiviere. Deshalb sind die Normalenvektoren vermutlich nicht das Problem.

Vielen Dank schonmal im Voraus! :)
Zuletzt geändert von PlainOldCJ am 04.12.2012, 19:10, insgesamt 1-mal geändert.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Überbeleuchtung mit Blending

Beitrag von Schrompf »

Eventuell addierst Du bei jeder Lichtquelle den Ambient-Anteil erneut. Den solltest Du für jede weitere Lichtquelle als der ersten abschalten, oder schlimmstenfalls in einem separaten Pass addieren.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
PlainOldCJ
Beiträge: 11
Registriert: 03.12.2012, 20:56
Echter Name: Christian

Re: Überbeleuchtung mit Blending

Beitrag von PlainOldCJ »

Hey Schrompf,

danke für deine schnelle Antwort, das ist eine gute Idee!
Für den Ambient-Pass und den Lighting-Pass habe ich zwei verschiedene Shader. Der Ambient-Pass wird einmal pro
Frame aufgerufen, vor den Lighting-Passes. Als Ambient-Farbe habe ich Schwarz (mit Alpha = 1.0f) gewählt, um
mehrmaliges Addieren vom Ambient-Light auszuschließen.

Hier im Bild siehst du (von links nach rechts) den Ambient-Pass,
die Beleuchtung ohne Blending und die Beleuchtung mit Blending für den problematischen
Mesh.

Den Lighting-Pass ohne Ambient-Pass siehst du ganz rechts. Den Ambient-Pass nutze ich, um den Depthbuffer zu füllen.
Ohne den gibts deshalb Overdraw, aber ansonsten sieht das so aus, wie erwartet.

Der Ambient-Pass ist deshalb okay, glaube ich. Sag an, welche Informationen du noch brauchst und
danke für deine Hilfe! :)
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Überbeleuchtung mit Blending

Beitrag von Schrompf »

Tja... war nur eine Vermutung. Ich kenne mich mit OpenGL nicht aus. Aber sag mal: was tut glDepthMask()? Schaltet das den Depth Buffer aus, oder nur den Stencil Buffer? Falls Depth Buffer, dann addierst Du da evtl. auch Rückseiten mit auf, was ebenso zu übermäßiger Helligkeit führt.

Was übrigens auch sein kann: dass das alles richtig funktioniert und Du nur das optische Ergebnis für falsch hälst. Belies Dich mal zu Gamma-Kurven des Monitors und gamma-korrekter Beleuchtung. In Kurzform: der Monitor, mit dem Du das Bild betrachtest, wendet eine nichtlineare Kurve an, die helle Farbtöne stark übertreibt, weil Deine Augen für dunkle Bildpunkte empfindlicher sind. Wenn Du also einfach die Wirkungen zweier Lichtquellen aufsummierst, erscheint die Ergebnis-Helligkeit auf dem Bildschirm deutlich heller als in der Natur. Und dort würden sich die Helligkeiten zweier Lichtquellen auf einem Punkt ja auch nur aufaddieren, die Natur muss es also wissen :-)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
PlainOldCJ
Beiträge: 11
Registriert: 03.12.2012, 20:56
Echter Name: Christian

Re: Überbeleuchtung mit Blending

Beitrag von PlainOldCJ »

Hi,

die Funktion glDepthMask() aktiviert (GL_TRUE) oder deaktiviert (GL_FALSE) Schreiben in den Depthbuffer.
Der Stencilbuffer ist davon nichtbetroffen. Für den gibts mit glStencilMask() eine eigene Funktion.

Dass Rückseiten mit aufaddiert werden ist eine gute Idee, die Befürchtung hatte ich auch.
Um das zu vermeiden mache ich Folgendes:
Im Ambient-Pass wird der Depthbuffer gefüllt.
Vor dem Rendern der Light-Passes setze ich glDepthFunc(GL_EQUAL), was bewirken soll, dass nur
solche Pixel den Depth-Test bestehen, die auch sichtbar sind.

So, dann ist wohl jetzt der Zeitpunkt rauszufinden, was dieses Gamme eigentlich ist, über das alle reden :)
Eine Sache noch: Siehst du die Bilder, die ich gepostet habe, auch überbeleutet? Kann es sein, dass
schon meine Grafikkarte eine falsche (bzw. falsch eingestellte) Gamma-Korrektur macht?
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Überbeleuchtung mit Blending

Beitrag von Artificial Mind »

Moin,

ich sehe auch das rechte Bild überbeleuchtet.

Kannst du vielleicht mal kurz deine Lichtquellen angeben? Bzw. mehr zu dem "renderDiffusePass"?
Es kann ja auch sein, dass das erste Bild falsch ist und deine Lichtquellen einfach zu hell sind.
PlainOldCJ
Beiträge: 11
Registriert: 03.12.2012, 20:56
Echter Name: Christian

Re: Überbeleuchtung mit Blending

Beitrag von PlainOldCJ »

Hey Artificial Mind,

daran, dass das erste Bild das fehlerhafte sein kann, habe ich gar nicht gedacht! :)

Hier ist mein Pixelshader für den Lighting-Pass:

Code: Alles auswählen

in vec3 vNormal;

uniform vec3 uLightDir;
uniform vec4 uColor;

out vec4 fragColor; // Farbe des zu zeichnenden Pixels

void main() {
  fragColor = clamp(dot(uLightDir, normalize(vNormal)), 0.0, 1.0) *
  uColor + vec4(0.0, 0.0, 0.0, 1.0);
}
Der Fehler tritt bereits bei einer einzigen Lichtquelle mit Richtung uLightDir = (0, 0, 1) und Farbe uColor = (1, 1, 1, 1) auf.

Wenn ich auf Blending verzichte und alle Lichter in einem Shaderdurchlauf aufaddiere,
stimmt die Beleuchtung.
Hier der relevante Code dazu:

Code: Alles auswählen

fragColor = vec4(0.0, 0.0, 0.0, 1.0);
fragColor += clamp(dot(uLightDir0, normalize(vNormal)), 0.0, 1.0) * uColor0;
fragColor += clamp(dot(uLightDir1, normalize(vNormal)), 0.0, 1.0) * uColor1;
fragColor += clamp(dot(uLightDir2, normalize(vNormal)), 0.0, 1.0) * uColor2;
Allerdings ist das doch genau die Berechnung, die auch das Blending durchführen sollte? :)

EDIT: Okay, was sein könnte: beim fehlerhaften Mesh könnten Seiten mehrmals vorhanden sein! Das wird jetzt überprüft! :)

EDIT2: Oh Mann, das wars tatsächlich... Entschuldigt bitte eure Zeit verschwendet zu haben und vielen Dank für eure Hilfe! :oops:
Antworten