Das Ende von Rendering-Pipelines mit fester Funktion (und wie man weitergeht)

Fixed-Function-Pipelines haben auf unseren Grafikkarten nichts mehr zu suchen. Hier erfahren Sie, was Sie über sie wissen müssen - und wie Sie von ihnen wechseln können, wenn Sie dies noch nicht getan haben.

Am Anfang: Der Aufstieg der Grafikhardware

Es war einmal, als sich die Spieleentwicklung (oder alles, was mit Echtzeitgrafiken zu tun hat, wirklich codiert) darauf beschränkt war, in eine relativ kleine Matrix von Farbintensitäten zu schreiben (die Bildspeicher, Framebuffer) und an Hardware senden, können Sie damit alles machen, was Sie wollten. Sie könnten ein, zehn oder hundert Mal auf das Bild zeichnen. Sie könnten den Frame-Puffer erneut durchlaufen, um ordentliche FX-Effekte zu erzielen. Kurz gesagt, was auch immer Ihr Prozessor tun kann, Sie können es mit dem Bild tun, das an den Monitor gesendet wird. Dies ermöglichte es Ihnen, wirklich großartige und kreative Sachen zu machen, aber die Leute haben es nie (oder selten) in diesem Ausmaß verwendet. Aber warum?

Die Antwort: weil es langsam war. Ein 640 × 480px-Bild (damals übliche Auflösung) enthält 307.200 Pixel. Und die CPUs waren damals so viel langsamer, dass Sie in der kurzen Zeit, die Sie zum Zeichnen dieses Rahmens hatten, nicht viel tun konnten. Wenn Sie weiterhin bei 30FPS zeichnen möchten, haben Sie nur etwa 30 ms, um Ihre Spielelogik zu aktualisieren und auf dem Bildschirm zu rendern. Dazu gehört auch der Aufwand für die Interkommunikation mit der Hardware. Es war nicht viel.

Dann kamen die coolen GPUs mit Rendering-Pipelines. Sie, der Entwickler, würden sich darum kümmern, die Spielelogik zu aktualisieren und Ihre Texturen und Dreiecke an die GPU zu senden, und dies würde das harte Anheben und die Anzahl der Zahlen an sich bewirken. Diese waren Pipelines mit fester Funktion (FFPs): bedeutet, dass Sie das nicht konfigurieren konnten Funktionen Sie performten. Man könnte ihnen sagen "mach den Nebel dunkelgrau" oder "mach das Licht nicht für mich!" und Sie könnten viele andere konfigurieren Parameter, aber die Funktionen selbst blieb. 

Die Hardware war verkabelt und eng spezialisiert, so dass einige Standardvorgänge für Ihre Daten ausgeführt wurden. Und weil es so verkabelt war, war es viel schneller als mit Ihrem Prozessor. Ein Nachteil war jedoch, dass Sie für diese Geschwindigkeit viel bezahlt haben: Sie haben flexibel bezahlt. Wenn Sie jemals etwas komplexes zeichnen wollten, war die CPU einfach nicht schnell genug, und die Vertices an die GPU zu senden, war die einzige Wahl.

In etwa funktioniert die Pipeline mit fester Funktion. Das Bild ist nicht als genaue Darstellung gedacht, sondern soll Ihnen einen Hinweis darauf geben, wie es funktioniert.

Die Forderungen nach besserem Realismus

Die Grafikwelt veränderte sich immer noch schnell. Wie alle kreativen und talentierten Menschen lieben Spieleentwickler Herausforderungen und Herausforderungen das Die Herausforderungen für sie waren (und werden es auch bleiben), um immer besser aussehende, realistischere Bilder zu rendern. 

In der Pipeline mit fester Funktion wurden einige nützliche Funktionen bereitgestellt, z. B. mehrere Mischmodi, Gouraud-Schattierungen pro Scheitelpunkt, Nebeleffekte, Schablonenpuffer (für Schattenvolumen) usw., sodass die Entwickler das nutzten, was sie konnten. Bald gab es einige wirklich beeindruckende Effekte, die alle durch realistische Phänomene simuliert wurden, die mit ein paar billigen Tricks simuliert wurden.. 

Dies lief alles sehr gut, war aber immer noch durch die Anzahl der Funktionen begrenzt, die die feste Pipeline ausführen konnte. Schließlich gibt es in der realen Welt so viele verschiedene Materialien, und um sie zu simulieren, durften sie nur einige Mischmodi ändern, Texturen hinzufügen oder die Lichtreflexionsfarben anpassen.

Dann passierte es: Die ersten programmierbaren GPUs kamen hinzu. Natürlich kamen sie nicht über Nacht, und sie würden eines Tages eintreffen, aber das sorgte trotzdem für Aufregung. Diese GPUs hatten das, was als a bezeichnet wurde Programmierbare Rendering-Pipeline: Sie könnten jetzt Programme schreiben, aufgerufen Shader, in einer begrenzten Assemblersprache, und lassen Sie sie für jeden Scheitelpunkt oder Fragment ausführen, auf der Grafikkarte. Dies war ein großer Fortschritt und es wurde gerade besser. 

Bald wurden die Assembler-Sprachen immer komplexer und ausdrucksstärker, und es entwickelten sich Hochsprachen für die GPU-Programmierung wie HLSL, GLSL und später Cg. Heute gibt es Geometrieshader, mit denen sogar neue Scheitelpunkte übertragen werden können, oder Schattierer, die die Tessellierung und die dreieckigen Dreiecke dynamisch steuern. In ihnen können wir eine Menge Texturen ausprobieren, sich dynamisch verzweigen und alle möglichen verrückten Berechnungen der Eingabewerte durchführen.

Wenn Sie Entwicklern diese Vorteile geben, werden sie wild. Bald haben sie Shader für alle möglichen Dinge geschrieben: Parallax-Mapping, benutzerdefinierte Beleuchtungsmodelle, Refraktion, Sie nennen es. Später entwickelten sich sogar vollständig benutzerdefinierte Beleuchtungssysteme, wie verzögerte Schattierung und Lichtvorpass, und Sie konnten komplexe Nachbearbeitungseffekte wie den Raumraum-Okklusionsraum und den Horizont-basierten Umgebungsverschluss sehen. Einige "missbrauchten" sogar Shader, um sich wiederholende, mathematisch anspruchsvolle Aufgaben zu erledigen, wie statistische Verarbeitung oder das Brechen von String-Hashes. (Dies war, bevor das Universal Computing für GPUs Mainstream-Support erhielt.) 

Kurz gesagt, die Computergrafik explodierte mit der Einführung von Shadern, und das aus gutem Grund: Die Möglichkeit, zu programmieren, was genau mit Scheitelpunkten, Fragmenten, Texturen usw. geschehen ist, und dies zu tun schnell, fast unbegrenzte Möglichkeiten.

Eine vereinfachte Darstellung der programmierbaren Pipeline. Beachten Sie, wie die spezifischen Transformations-, Schattierungs- oder Texturstufen durch spezialisierte Shader ersetzt wurden. (Tessellation wurde aus Gründen der Übersichtlichkeit weggelassen.)

Der komplette Schalter

Bald waren feste Funktionspipelines zumindest für Spieleentwickler obsolet. Warum sollten Sie sich um solche ummauerten Gärten kümmern, wenn Sie genau programmieren können, was mit Ihren Daten geschieht? In einigen Anwendungen, in denen der Realismus keine Rolle spielte, beispielsweise für CAD, blieben sie noch lange in Gebrauch. Aber im Großen und Ganzen wurden sie ignoriert. 

OpenGL ES 2.0, das 2007 veröffentlicht wurde, wurde zugunsten einer programmierbaren Pipeline abgelehnt oder entfernt. In OpenGL 3.2 wurde bereits im Jahr 2009 der Begriff der festen Funktion für die Verarbeitung von Scheitelpunkten und Fragmenten endgültig beseitigt Kompatibilitätsprofil). Es ist klar, dass es heute wenig Sinn macht, mit der begrenzten Pipeline zu arbeiten, wenn Sie über leistungsstarke GPUs verfügen, die in der Lage sind, großartige Dinge zu erledigen.

Da diese APIs Sie zwingen, Shader zu verwenden (dazu zählt auch DirectX, das zwar nicht explizit die Funktionalität entfernt, jedoch Tools enthält, die den alten Ansatz unterstützen, und praktisch keine neue Dokumentation zum FFP enthalten), sind sie nur schwer zu finden für einen Anfänger Wenn Sie nur als Anfänger in 3D-Programmierung anfangen, ist es viel einfacher, der API Ihre Matrizen, Beleuchtungsparameter und was nicht zu sagen, und alles für Sie erledigen zu lassen. 

Auf lange Sicht wird es jedoch viel mehr von Vorteil sein, wenn Sie lernen, Programme zu schreiben, die den Prozess genau beschreiben. Sie verstehen genau, was unter der Haube vor sich geht, verstehen einige sehr wichtige Konzepte, die das FFP nicht erfordert, und Sie sind in der Lage, Ihre Materialien sehr leicht zu verändern, um etwas zu tun, das die fixierte Funktion niemals für Sie tun kann (und es ist nützlich auch zum debuggen!).

Ich habe OpenGL ES erwähnt, und ich möchte darauf näher eingehen. Da das Spielen auf dem Handy immer beliebter wird, ist es sinnvoll, virtuelle Welten zu erstellen, die immer komplexer werden. Die meisten Aufrufe von Funktionen mit fester Funktion wurden in ES 2.0 entfernt (was natürlich bedeutet, dass sie auch in nachfolgenden Versionen nicht vorhanden sind). Dies bedeutet im Wesentlichen, dass Sie zur Verwendung von Funktionen nach ES 1.1 Shader verwenden müssen. 

ES 2.0 wird von iPhones seit 3GS, iPads seit der ersten Version und iPod Touch-Geräten der Generation 3 und höher unterstützt. Qualcomm Snapdragon, ein in der Android-Telefonproduktion weit verbreiteter Chip, unterstützt auch OpenGL ES 2.0. Das ist sehr weit Support, weil ES 2.0 nicht gerade "neu" ist: Es ist jetzt über 7 Jahre alt. Um das Beste aus diesen Architekturen zu machen, Sie müssen die Pipeline mit fester Funktion loslassen

Ich nehme an, die meisten von euch haben das schon lange vor langer Zeit gemacht, aber ich kann mir nicht so schwer vorstellen, einige 2D-Grafik-Engines oder ältere Spiele vorzustellen, die immer noch Fixed-Funktionen verwenden (da es keine Notwendigkeit mehr gibt). Dies ist alles in Ordnung, aber die Verwendung für neue Projekte oder die Schulung von Programmierern darin erscheint wie Zeitverschwendung. Dies wird durch die Tatsache verstärkt, dass viele Tutorials, die Sie im Internet finden können, weitgehend veraltet sind und Ihnen zeigen, wie Sie das FFP von Anfang an verwenden - und bevor Sie überhaupt erkennen, was los ist, sind Sie tief drin.

Mein erster Pinsel mit 3D-Grafiken war ein uraltes DirectX 7-Tutorial, das in Visual Basic geschrieben wurde. Zu diesem Zeitpunkt war die Verwendung der Pipeline mit fester Funktion im Allgemeinen sinnvoll, da die Hardware nicht so weit fortgeschritten war, dass dieselbe Funktionalität mit Shader mit der gleichen Geschwindigkeit erzielt werden konnte. Heutzutage sehen wir jedoch, dass Grafik-APIs damit beginnen, ihre Unterstützung einzustellen oder stark zu veralten, und es wird wirklich nur noch ein Artefakt der Vergangenheit. Es ist ein gutes und nützliches Artefakt, das uns nostalgisch macht, aber wir sollten uns davon fernhalten. Es ist alt und wird nicht mehr benutzt.

Diese süßen Fresnelreflexionen und -reflexionen, die von einer Demo von OGRE (Open-Source Graphics Rendering Engine) erzeugt wurden, wären niemals möglich gewesen, wenn Sie sich an die von DirectX 8 oder OpenGL 1.1 empfohlenen Anleitungen halten würden.

Fazit

Wenn Sie sich ernsthaft mit der Entwicklung von Spielen beschäftigen, ist das Festhalten an der Pipeline mit fester Funktion ein Überbleibsel vergangener Tage. Wenn Sie sich mit 3D-Grafik beschäftigen möchten, sollten Sie dies einfach vermeiden. 

Wenn Sie die Übergabe von Beleuchtungspositionen an die Grafik-API (nicht als Shader-Parameter) oder API-Funktionsaufrufe wie sehen glFogv, laufe wie der Wind und schau nicht zurück. Es gibt dort eine schöne neue Welt programmierbarer GPUs, und es ist schon lange her. Alles andere verschwendet wahrscheinlich nur Ihre Zeit.

Selbst wenn Sie sich nur mit 2D-Grafiken beschäftigen, ist es immer noch eine gute Idee, sich nicht mehr auf das FFP zu verlassen. (Natürlich ist dies solange erlaubt, dass Sie keine alten Hardware unterstützen.) Shader können Sie mit großartigen, blitzschnellen Effekten versehen. Das Verwischen von Bildern, das Schärfen, Verzerrungen, das Rendern von Vektoren und die Simulation großer Partikel- oder Physik-Simulationen können auf der GPU durchgeführt werden. Sie können sowohl 2D- als auch 3D-Spiele unterstützen. 

Daher ist es mein Rat, auch wenn Sie sich nicht explizit mit der Entwicklung von 3D-Spielen beschäftigen, Shader schreiben zu lernen. Es macht Spaß, damit zu arbeiten, und ich garantiere Ihnen, dass Sie viele lustige Stunden damit verbringen, einen coolen Shader-Effekt zu perfektionieren: eine dynamische Skybox, Autolack oder Parallel-Split-Schatten-Mapping oder was auch immer Ihr Herz begehrt. Zumindest ist mir das passiert: Sobald Sie sich aus Einschränkungen mit der festen Pipeline beschäftigt haben (da ich früher gezwungen wurde, eine akzeptable Leistung auf meinem 5200FX zu erhalten), ist das Programmieren der GPU eine viel Spaß und jede Menge Spaß.

Ich hoffe, ich habe denen erklärt, für die unklar war, wie 3D-Grafiken vor langer Zeit funktionierten und wie es jetzt funktioniert, und ich hoffe, ich habe die wenigen von Ihnen überzeugt, die kurz davor waren, NeHe- oder Swiftless-Tutorials zu folgen ansonsten und schau dir etwas moderneres an. Wie immer habe ich vielleicht einige Fehler gemacht. Fühlen Sie sich bitte in den Kommentaren darauf. Bis zum nächsten Mal!