Dauert das Rendern einer detaillierten Textur länger?

22

Angenommen, ich möchte ein Quadrat rendern. Die Textur ist "square.png".

Ist es für den Computer einfacher, es zu rendern, wenn die Textur nur eine einfache Farbe ist?

Und was ist, wenn es eine sehr laute Textur mit hier und da völlig zufälligen Farben ist?

Oder was ist, wenn diese Textur in dem Sinne verrauscht ist, dass sich jedes Pixel darin von einem zum anderen unterscheidet, aber nur um ein winziges Stückchen?

user3491043
quelle

Antworten:

39

Wie die meisten Dinge in der Spieleentwicklung und insbesondere in der Spielgrafik lautet die Antwort "es kommt darauf an".

Texturgröße

Die Auflösung Ihrer Textur kann sich auf die Rendergeschwindigkeit auswirken. Je mehr Pixel es enthält, desto mehr Rohdaten müssen auf die GPU hochgeladen werden und desto weniger Textur können wir gleichzeitig in den Cache einpassen, sodass der Shader möglicherweise mehr Pausen einlegt, während er auf den richtigen Teil der Textur wartet in den Cache gezogen werden.

Die Verwendung von Mipmapping kann die Auswirkungen verringern. Mit Mipmaps speichern wir eine Reihe von verkleinerten Versionen der Textur, die auf den ersten Blick nach noch mehr Speicher klingt. Wir können jedoch aus den kleineren Versionen lesen, wenn die Textur in einer kleinen Größe auf dem Bildschirm angezeigt wird (wie ein entferntes Objekt in der Perspektive), sodass unsere Beispiele den Textur-Cache besser nutzen, anstatt von einem Ort zum anderen zu springen. Dies reduziert auch das Aliasing.

Textur Detail

Der Inhalt Ihrer Texturen hat die meiste Zeit keinen Einfluss auf die Rendereffizienz.

Eine Farbe ist für die GPU nur ein Bündel von Zahlen, daher ist es unerheblich, was diese Zahlen sind, sondern sie werden in der Mathematik auf die gleiche Weise behandelt. Es ist nichts Besonderes, als sich daran zu erinnern, dass "Oh, ich habe schon einmal ein Pixel in diesem Grün gesehen. Ich werde einfach die gleiche Ausgabe wiederverwenden, die ich zuletzt berechnet habe, als ich diese Eingabe gesehen habe." oder zufälliges Funkeln, Ihre GPU erledigt die gleiche Arbeit.

Im Gegensatz zu Formaten wie PNG und JPG, die in vorhersagbaren Bildbereichen effizienter komprimiert werden und in komplexen Bereichen mehr Bits verbrauchen, verwenden GPU-Texturformate wie BTC, ETC, PVRTC oder sogar RGBA-Rohdaten eine feste Anzahl von Bits pro Block von Pixel. Wenn Sie also Ihre Textur mehr oder weniger detailliert gestalten, während Sie das gleiche Komprimierungsformat beibehalten, wird sich dies nicht auf die Datengröße oder die Datenübertragung sowie auf die Cache-bezogene Effizienz auswirken.

Wenn Sie jedoch eine bestimmte Art von Detail verwenden, die bei der vorherigen Komprimierung nicht gut erhalten bleibt, müssen Sie möglicherweise Ihr gesamtes Bild ändern, um ein anderes Format zu verwenden, wodurch sich wiederum die Datengröße ändern kann.

Shader Branching & Indirection

Hier ist der größte Stern in der Situation: Möglicherweise verwenden Sie diese Texturfarbeneingabe, um Entscheidungen zu treffen, wie bei einer if()Verzweigung. Hier kommt es auf das Detail an.

GPU-Schattierungseinheiten arbeiten stapelweise mit Pixelblöcken und führen dieselben Anweisungen parallel für mehrere Datenströme aus. Wenn also einige Pixel im Block einen Zweig ifund andere Pixel den anderen nehmen, muss der gesamte Stapel beide Zweige durchlaufen (wobei die Ergebnisse ausgeblendet werden, die für den einen oder den anderen Satz von Pixeln nicht zutreffen).

Wenn sich Ihre Eingabe auf eine reibungslose / vorhersehbare Weise ändert, werden wahrscheinlich viele Blöcke vorhanden sein, die nur eine einzige Verzweigung benötigen, und diese beiden Verzweigungsfälle sind auf schmale Bänder um die Übergangsgrenze beschränkt. Wenn Ihre Eingabe jedoch zufällig ist, erwarten wir, dass die meisten Blöcke beide Zweige verwenden und das Rendern verlangsamen.

Dies kann auch passieren, wenn Sie eine Textur verwenden, um Lookups in eine zweite Textur umzuwandeln, z. B. eine Verzerrungs- oder Index-Map. Wenn die erste Textur zufällig herumspringt, werden wir von verstreuten, zufälligen Stellen der zweiten Textur abtasten, unseren Textur-Cache weniger konsistent nutzen und im Durchschnitt länger warten, bis wir die benötigten Daten erhalten.


Insgesamt: Nein, der Inhalt der Textur hat keinen großen Einfluss auf die Rendergeschwindigkeit, außer in den Fällen, in denen dies der Fall ist. ;)

DMGregory
quelle
Niedrig aufgelöste Texturen (denke Minecraft) würden mit größerer Wahrscheinlichkeit Texel für benachbarte Pixel in den Cache laden, wenn ein bestimmtes Texel in den Cache geladen wird, oder?
user253751
6
@immibis Minecraft hat winzige Texturen. Die Standardeinstellung ist nur 16x16, was so einfach in den Textur-Cache jedes Kerns passt, dass es nicht einmal witzig ist: D Und ja, die meisten Textur-Samples werden dasselbe Texel sein, es sei denn, Sie sind sehr weit vom Block entfernt. Dies gilt insbesondere dann, wenn Sie die Bildschirmunterteilung berücksichtigen - wenn Sie einigermaßen nah beieinander sind, wird der gesamte Stapel für einen bestimmten Kern möglicherweise demselben Texel zugeordnet: Eine einfachere DA-GPU funktioniert wahrscheinlich besser für eine solche Texturierung mit niedriger Auflösung - vermute ich Viel Aufwand wird für Optimierungen aufgewendet, die Minecraft nichts nützen.
Luaan
1
Randnotiz: Die Angabe "verwendet die gleiche Anzahl von Bytes pro Pixel" ist der eigentliche Schlüssel für einige der von Grafikcode verwendeten Geschwindigkeits-Hacks. Wenn Sie versuchen würden, PNG intern oder sogar UTF-8 mit variabler Pixelgröße zu verwenden, um auf das ndritte Pixel zuzugreifen, müssten Sie jedes einzelne Pixel vorher durchgehen. Bei einer konstanten Pixelbyte Breite ist, ist es einfach start_of_buffer + width * n, das ist viel schneller, vor allem für große n.
Fund Monica's Lawsuit
@Luaan Ich meine, auch wenn Sie weit vom Block entfernt sind, sollte er, wenn er ein Texel abruft (je nachdem, welches zuerst ist), einige benachbarte auch in den Cache ziehen.
user253751
4
Das ist der Fall, über den ich oben mit Mipmapping gesprochen habe. Um zu vermeiden, dass unsere Samples die gesamte Textur überspringen und große Lücken bei geringer bis gar keiner Wiederverwendung des Cache lassen, speichern wir eine 512x512-Version und eine 256x256-Version und ... manchmal bis hinunter zu 1x1. Wenn Sie also die 1024x1024-Textur mit 16x16 zeichnen, werden die meisten Spiele tatsächlich vom 16x16-Mip lesen, und die Cache-Effizienz ist mit der des 16x16-Minecraft-Falls vergleichbar. Dies reduziert auch funkelnde Aliasing-Artefakte beim Downsampling.
DMGregory
1

Zusammen mit der hervorragenden Antwort von DMGregory gibt es vielleicht einen Fall, in dem die Komplexität einer "Textur" die Renderleistung beeinflussen kann und in dem die Ergebnisse eines vorherigen Renderings als Quelle für ein nachfolgendes verwendet werden, z. B. für Schattenkarten / reflexionen / umgebungskarten.

Einige moderne Hardwareprogramme können diese Puffer verlustfrei komprimieren: PowerVR verfügt beispielsweise über PVRIC , AMD, Delta Color Compression und ARM über ähnliche Funktionen. Das Ziel dieser Komprimierungstechniken ist es, die Gesamtbandbreite zu reduzieren, was wiederum die Renderleistung verbessern kann.

Je einfacher die Daten sind, sei es Tiefe oder Farbe (Ganzzahl oder Gleitkomma), desto besser funktionieren diese Schemata. Natürlich würde ich nicht vorschlagen, die Renderausgabe absichtlich zu vereinfachen, damit sie besser funktioniert. Unter bestimmten Umständen kann es jedoch hilfreich sein, keine verrauschten Daten zu verwenden.

Auch das sparsame Abtasten von Frame- / Tiefenpuffern, die diese Schemata verwenden, hilft nicht, da sie sehr wahrscheinlich blockbasiert sind.

Weiterhin könnten Sie diese zwei SE Computer Graphics Fragen und Antworten von Interesse finden:

Simon F
quelle