[D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Krishty »

Hi,

Mal wieder etwas ganz Böses …

Ich brauche – trotz der desaströsen Performance – Alpha-to-Coverage für Order-independent-Transparency. Mit dem AlphaToCoverageEnable-Flag der D3D11_BLEND_DESC sollte das getan sein – aber scheinbar nicht, wenn man Dual-Source-Color-Blending nutzt (ja, man kann von GPUs eben nicht alles erwarten).

Also muss ich das Blending von Hand im Shader durchführen, so weit, so nervig. Nun stehe ich aber vor dem Problem: Wie komme ich von der alten und neuen Farbe des Render-Targets (vor Tonemapping!) auf einen Alpha-Wert, so dass Alpha-to-Coverage funktioniert? Die Abweichung des neuen Pixels festzustellen ist ja leicht … wäre sie im Bereich [-1, +1], würde ich den Absolutwert der größten Abweichung nehmen … aber wie soll das mit quasi unbegrenzten Helligkeiten funktionieren?

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Jörg »

Das klingt kompliziert, aber vielleicht gibt es noch einen anderen Weg, dein Problem zu loesen? Welcher Art sind die Artefakte, die du hoffst, ueber AtC zu minimieren?
Ich muss ehrlich sagen, dass ich nicht genau weiss, ob AtC wirklich das richtige ist, um reihenfolge-unabhaengige Transparenz zu bekommen, da m.E. nirgendwo definiert ist, wie die Auswahl der Sub-Samples genau stattfindet. Es funktioniert gut, um Alpha-Filterung und AA zu kombinieren (d.h. die harten "Kanten" verschwinden zu lassen), aber fuer mehr????

Bsp (4 MSAA) : 2 Passes, der erste liefert mit Alpha=0.25 ein Coverage von 1 Sub-Sample, der zweite Pass mit Alpha=0.5 ein Coverage von 2.
Welche der 4 Sub-Samples werden aber verwendet? Kann es passieren, dass der 2. Pass die Informationen des ersten voellig ueberschreibt, wenn die 2 Sub-Samples genau das eine des ersten Passes beinhalten? Ich glaube, es wird Zeit, wieder mal die Register-Doku's zu lesen, vllt. findet man dort mehr. Oder ein Testprogramm zu schreiben, bei dem wir die Resultate der verschiedenen GPUs mal zusammentragen...

Entschuldigung, dass ist sicherlich nicht die Problemloesung, die Du Dir erhofft hast...

Edit: Mein Beispiel ist schlecht, da ja trotzdem ein Alphablending mit dem ersten Sub-Sample durchgefuehrt wird, die Information ist also nicht verloren.

Edit2: Reicht es evtl, wenn Du das originala Alpha verwendest (mit dem Du urspruenglich die Coverage beschreiben wolltest) und fuer die Blending-Operation das Alpha dann deaktivierst ueber eine passende Blendfunc ? Dann wird das im PS manuell berechnete Blending nur in den durch Coverage beschriebenen Sub-Samples eingetragen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Krishty »

Die Probleme mit dem Masking sind mir bekannt - ich hatte Alpha-to-Coverage schonmal in einem Prototypen angetestet, dort wurde die Deckkraft dadurch auf rund die Hälfte reduziert. Wenn der Effekt explizit auf Alpha-to-Coverage ausgelegt wird, kann man das aber miteinbeziehen. Darüber hinaus gibt es noch Custom-Sample-Masks (die GPU weiß zwar nicht, wie die Samples optimal zu verteilen sind, aber ich) und Alpha-Dithering.

Es geht um Volume-Rendering ohne einen Alphawert im traditionellen Sinne, sondern mit einem multiplikativen und einem additiven Blending-Anteil. Da ich nie einen Alphawert besitze, ist die Frage, wie ich von meiner geblendeten Farbe zurück auf Alpha komme, mit das größte Problem. Im Grunde geht es aber um Folgendes:
Ich muss für jeden Pixel (auch bei Overdraw!) den Tiefenwert der dahinter liegenden Geometrie kennen. Darum finde ich hier A2C so angebracht: Ich kann (indem ich Depth-Writing aktiviere) garantieren, dass nie mehr als einmal pro Pixel geblendet wird (sich der Tiefenwert also nie ändert), dass also jedes Sample für sich gültig ist (und damit ergäben alle aufgelösten Samples eines Pixels einen gültigen Pixel).

Die Alternative - die in jeder Hinsicht sauberer wäre - wäre, das Ganze in rund 200 zusätzliche Passes für Back-to-Front-Rendering aufzulösen (vorsortiert wäre die Geometrie schon). Dann könnte ich in jedem Pass korrektes Blending anwenden und würde dabei die neuen Tiefenwerte für den nächsten Pass schreiben. Das ganze ginge ohne Hackerei an den Shadern und würde durch korrektes Blending wahrscheinlich auch qualitativ besser aussehen - ich weiß aber nicht, wie sich 200 zusätzliche Passes, in denen jeweils nur eine Handvoll Pixel gezeichnet und anschließend das ganze Render-Target per ID3D11DeviceContext::CopyResource() kopiert wird, auf die Performance auswirken würden. Ich befürchte, schlimmer als Alpha-to-Coverage mit Custom-Sample-Masks.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Jörg »

Nur damit ich richtig mitkomme ;)
Wie willst Du bei MSAA den Tiefenwert des letzten "Passes" (DrawCall) erhalten und verrechnen, so wie Du es in deinem Absatz ueber "korrektes Rendering" beschrieben hast?
Was mir absolut nicht klar wird aus der Beschreibung ist folgendes: Du blendest im PS, hast also eine Resultat-Farbe. Warum brauchst Du dann ein Alpha? Uber die SampleMask kannst Du doch genau einstellen, welches Subsample modifiziert wird und dein Ergebnis einfach hineinschreiben zu 100%...ich steh da auf dem Schlauch.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Krishty »

Jörg hat geschrieben:Nur damit ich richtig mitkomme ;)
Wie willst Du bei MSAA den Tiefenwert des letzten "Passes" (DrawCall) erhalten und verrechnen, so wie Du es in deinem Absatz ueber "korrektes Rendering" beschrieben hast?
Das richtige Lesen aus multi-sampled Texturen wird ja seit D3D10.1 unterstützt (durch SV_SampleIndex weiß ich, zu welchem Sample in der Textur der aktuell verarbeitete Pixel gehört).
Jörg hat geschrieben:Was mir absolut nicht klar wird aus der Beschreibung ist folgendes: Du blendest im PS, hast also eine Resultat-Farbe. Warum brauchst Du dann ein Alpha? Uber die SampleMask kannst Du doch genau einstellen, welches Subsample modifiziert wird und dein Ergebnis einfach hineinschreiben zu 100%...ich steh da auf dem Schlauch.
Wie gesagt, kann das Sampling mit der korrekten Farbe und dem korrekten Tiefenwert nur genau einmal durchgeführt werden. Jeder Overdraw führt danach zu falschen Ergebnissen.

Nun hat meine Geometrie aber teils starken Overdraw. Die Überlegung ist folgende: Alpha-to-Coverage wird eingesetzt, um in jeden Pixel eine gewisse Anzahl an Samples zu schreiben, von dem jedes einzelne nur einmal geblendet wurde. Das wird erreicht, indem die einzelnen Samples wie solide Geometrie in den Tiefenpuffer geschrieben werden. Mit 8×MSAA sollte man so pro Pixel bis zu 8-fachen Overdraw halbwegs korrekt hinbekommen.

Damit Alpha-to-Coverage funktioniert, braucht man aber einen Alpha-Wert. Bloß mit einer neuen Farbe kann man nichts anfangen – irgendwie muss man von der neuen und alten Farbe darauf kommen, wieviele der Samples nun decken oder durchlassen sollen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Jörg »

Oha, du nimmst SV_SampleIndex....ich wuerde nicht erwarten, dass A2C dann ueberhaupt funktioniert. Leider finde ich in der Doku dazu keine konkrete Aussage, aber ich habe keine Idee, wir man 8 Aufrufe des PS (bei 8xMSAA fuer jedes SubSample einen, der via SV_SampleIndex) am Ende mit einer aus welchem Alpha auch immer generierten Coverage-Mask (die sich ja auf alle SubSamples bezieht) kombinieren kann. Wie stellst Du Dir das vor?
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D11] Alpha-to-Coverage und Dual-Source-Color-Blending

Beitrag von Krishty »

Exzellentes Argument … wenn ich die Samples einzeln clippen muss ist es mir endgültig zu bunt … ich werde auf Multipass umsteigen und mich bemühen, die Passes so weit wie möglich zu reduzieren. Der Prototyp für A2C dümpelte bei 4 fps vor sich hin, schlimmer kann es auch mit tausend Passes kaum werden.

Danke für das Flicken der Löcher in meinen Überlegungen :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten