Z-Buffer und Transparenz - Wieso wird das nicht aussortiert?



  • Wenn man Transparente Dreicke zeichnen möchte, dann muss man dies ja bekanntermaßen in der richtigen Reihenfolge machen, damit die Pixel der 100 % deckenden Dreicke nicht im Z-Buffer, welcher ja nur einen Wert pro Pixel halten kann, überschrieben werden.

    Jetzt würde ich aber gerne wissen, warum man transparente Dreiecke nicht einfach aussortiert und in einen zweiten separaten Z-Buffer schreibt?
    Man hat doch den Alpha Kanal zu jedem Dreick, weiß also ob das 100 % deckt oder nicht.

    Anhand von diesem könnte man dann doch entscheiden, ob das Dreieck in den normalen Z-Buffer, oder den zweiten (den ich hier vorschlage) gechrieben wird.

    Und am Ende, wenn man beie Z-Buffer berechnet hat, dann vereint man sie einfach in der richtigen Reihenfolge.
    Den deckenden mit dem transparenten.

    Würden das heutige Grafikkarten so machen, dann könnte man sich als Programmierer den Aufwand, die Transparenten Dreiecke in der richtigen Reihenfolge zu zeichnen, sparen, denn das alles würde so mit zwei Buffer automatisch gehen.

    Wieso macht man das also nicht?

    Speicherplatz kann heute ja nun wahrlich kein Argument mehr sein.



  • Für diesen 2. Buffer bräuchte man allerdings einen a-Buffer und keinen z-Buffer der eine Liste aller Fragmente enthält und nicht nur des obersten. Diese müsste man dann Sortieren und Blenden.

    Und sowas ist halt extrem langsam. Ein normaler z-Buffer ist ganz gut im Cache zu halten. Verkettete Listen nicht.

    Wenn man wirklich Hardwaretransparenz will würde man eher Tiled Rendering[1] nehmen. Dies passiert (aus anderen Gründen) im mobilen Bereich (z.B. iPhone mit PowerVR GPU).

    Allerdings lässt sich dein Vorschlag auch einfach in D3D11 oder OpenGL 4.0(4.2?) umsetzen. Mit Atomic Read/Write ist das ganz gut machbar. Es gibt sogar schon länger eine Demo von AMD die genau das macht[2].

    Wenn man dies nicht nur mit transpartenten sondern allen Fragmenten macht, kann man sogar (quasi) perfektes Antialiasing kriegen. (Ist nur halt alles nicht grade schnell)

    [1]: http://en.wikipedia.org/wiki/Tiled_rendering
    [2]: http://developer.amd.com/resources/documentation-articles/samples-demos/gpu-demos/ati-radeon-hd-5000-series-graphics-real-time-demos/



  • blard schrieb:

    Für diesen 2. Buffer bräuchte man allerdings einen a-Buffer und keinen z-Buffer der eine Liste aller Fragmente enthält und nicht nur des obersten. Diese müsste man dann Sortieren und Blenden.

    Und sowas ist halt extrem langsam. Ein normaler z-Buffer ist ganz gut im Cache zu halten. Verkettete Listen nicht.

    Wenn man weiß, dass in den a-Buffer (wie du ihn nennst) sowieso nur transparente Pixel reinkommen, dann kann man die auch gleich, wenn man sie reinsteckt mit dem alten Wert verrechnen. Daraus ergibt sich dann ein neuer Transparenzwert.

    Man braucht also, wie auch beim Z-Buffer nur einen Wert pro Pixel und somit keine Liste.



  • @Wozu sortieren?

    Soso.

    Sagen wir du hast 4 Fragments, A bis D. A hat die kleinste Entfernung, dann kommt B dann C und zuletzt D.
    Und nu sagen wir die werden in folgender Reihenfolge gerendert: A, C, D, B.

    Und nu überlegt dir was du für Werte bräuchtest um den Farbwert von "B" korrekt "integrieren" zu können.

    => geht nicht

    Weil nämlich, je nachdem wo "B" von der Entfernung her einzuordnen ist, ein anderer Farbwert rauskommt. (Und um den zu berechnen reicht es auch nicht zu wissen wo B z-mässig zwischen A, C und D einzuordnen ist, sondern man bräuchte auch noch deren einzelne Farb- und Transparenzwerte.)

    Wenn du anderer Meinung bist, dann zeig mal her die Formeln mit denen man das hinbekommt. Am besten schickst du mir die Formeln per Email statt sie öffentlich zu posten, weil ich verkauf die dann um nen sechsstelligen Betrag an nVIDIA.



  • hustbaer schrieb:

    @Wozu sortieren?

    Soso.

    Sagen wir du hast 4 Fragments, A bis D. A hat die kleinste Entfernung, dann kommt B dann C und zuletzt D.
    Und nu sagen wir die werden in folgender Reihenfolge gerendert: A, C, D, B.

    Und nu überlegt dir was du für Werte bräuchtest um den Farbwert von "B" korrekt "integrieren" zu können.

    => geht nicht

    Weil nämlich, je nachdem wo "B" von der Entfernung her einzuordnen ist, ein anderer Farbwert rauskommt. (Und um den zu berechnen reicht es auch nicht zu wissen wo Z zwischen A, C und D einzuordnen ist, sondern man bräuchte auch noch deren einzelne Farb- und Transparenzwerte.)

    Wenn du anderer Meinung bist, dann zeig mal her die Formeln mit denen man das hinbekommt. Am besten schickst du mir die Formeln per Email statt sie öffentlich zu posten, weil ich verkauf die dann um nen sechsstelligen Betrag an nVIDIA.

    Ist doch ganz einfach.
    Das muss man wissen.

    <wozu sortieren macht sich auf den Weg zu NVidia>



  • Na dann ist ja gut.
    Poste nachher wie viel sie dir bezahlt haben.



  • Wozu sortieren? schrieb:

    <wozu sortieren macht sich auf den Weg zu NVidia>

    Wenn du dich nicht blamieren willst, solltest du dir vielleicht doch noch einen Moment Zeit nehmen, darüber nachzudenken. Von Premultiplied Alpha haben die bei NVIDIA sicher schon gehört und das ist nicht die Lösung für alle Probleme. Nicht jede beliebige Art zwei Werte zu verrechnen ist kommutativ. Insbesondere das gängige lineare Blending ist es nicht...




Log in to reply