2016-06-04 9 views
3

Kürzlich arbeite ich an meiner SSAO-Implementierung, für meine Engine möchte ich Unterstützung sowohl für Vorwärts- als auch für Deferred-Renderer hinzufügen, daher wähle ich den Tiefenanflug-Ansatz und rekonstruiere normale aus der Tiefenkarte, hier ist der Code:Wie normal aus der Tiefe ohne Artefakte an der Kante zu rekonstruieren?

//Restore view space position with non-linear depth 
vec3 viewPos = getPosition(uv, depth, invProjMat); 
//Restore view space normal 
vec3 normal = normalize(cross(dFdx(viewPos), dFdy(viewPos))); 

Dann wende ich das normal auf meine SSAO Implementierung, erreichen sie ein ganz überwiegend gutes Ergebnis, mit Ausnahme der Kante:

enter image description here

ich bin sicher, das ist, weil die diskontinuierliche normalen kant , aber ich habe keine Ahnung, wie ich es beheben kann. Gibt es also einen Ansatz, um das Artefakt am Rand zu vermeiden, wenn man normal aus der Tiefe rekonstruiert? DANKE.

enter image description here

+2

Der richtige Weg, es zu tun ist, um Normalen zu einem Puffer zu rendern. Mit nur Tiefe wirst du an Kanten niemals gut sein. Sie können einige Heuristiken machen, aber es wird nie die ganze Zeit richtig sein. Selbst wenn Sie Objekt-Uids rendern, wird es für ein Pixel breite Linien brechen. Wenn Sie dies wirklich tun wollen, machen Sie einen Filter basierend auf der Tiefe statt dFd *. Anstelle von dFdx (pos) können Sie einen Wert (pos-1) - Wert (pos + 1) eingeben. Und nun mache einen Filter, der verschiedene Dinge macht, wenn die beiden Werte zu weit auseinander liegen. Aber auch dies wird scheitern, wenn beispielsweise ein einzelnes Pixel schattiert wird. – starmole

+1

@starmole: Warum ist das keine Antwort? –

Antwort

2

Es gibt keine Möglichkeit völlig alle Artefakte, um loszuwerden, außer durch einen Normalen gbuffer zu erzeugen. Aber es gibt eine Lösung für die Rekonstruktion von Normalen, die Ihnen viel bessere Ergebnisse liefert:

Was ich in meinem Motor mache, ist, nehme ich 5 Tiefe Proben für die normale Rekonstruktion. Sie sind wie ein Kreuz positioniert. Das mittlere Sample ist das Pixel, das Sie gerade rendern, und Sie probieren das Pixel oben, links, rechts und unter diesem Center-Sample aus. Dann nehmen Sie für die normale Rekonstruktion einfach die nächstliegende Y-Probe (entweder die oberhalb oder unterhalb der mittleren Probe) und die nächstliegende X-Probe (entweder die links oder rechts von der mittleren Probe) relativ zur mittleren Probe. Dies beseitigt in 99% der Fälle die normalen Kunsttakte, aber es führt Verzweigungen ein und benötigt mehr Texturproben. Daher ist es ein bisschen langsamer als nur das zu tun, was Sie bereits tun.

Klassische normale Rekonstruktion: classic normal reconstruction

Improved (Kreuzmuster) normale Rekonstruktion: improved (cross pattern) normal reconstruction

Klassische normale Rekonstruktion mit SSAO: classic normal reconstruction with SSAO

verbessern (Kreuzmuster) normale Rekonstruktion mit SSAO: improved (cross pattern) normal reconstruction with SSAO (Entschuldigung meine veralteten SSAO Screenshots)

Bitte beachten Sie auch, dass dFdx() und dFdy() verwendet, wird wahrscheinlich immer in mehr Artefakte führen als nur das Abtasten der Tiefe Textur dreimal (weil es keine guarante ist, dass die Werte von dFdx() oder dFdy() zurückgegeben wird genau sein), die eindeutig ist Fall in Ihrem Beispiel.