Shader - Shader

Shader werden am häufigsten verwendet, um beleuchtete und schattierte Bereiche beim Rendern von 3D-Modellen zu erzeugen . Die Phong-Schattierung (rechts) ist eine Verbesserung der Gouraud-Schattierung und war eines der ersten Computer-Schattierungsmodelle, die jemals nach dem grundlegenden Flat-Shader (links) entwickelt wurden und das Erscheinungsbild gekrümmter Oberflächen in Renderings erheblich verbessert.
Eine andere Verwendung von Shadern ist für Spezialeffekte, auch bei 2D-Bildern, zB einem Foto von einer Webcam . Das unveränderte, nicht schattierte Bild befindet sich auf der linken Seite, und auf das gleiche Bild wurde rechts ein Shader angewendet. Dieser Shader ersetzt alle hellen Bereiche des Bildes durch Weiß und alle dunklen Bereiche durch eine bunte Textur.

In der Computergrafik ist ein Shader eine Art Computerprogramm, das ursprünglich für die Schattierung in 3D-Szenen verwendet wurde (die Erzeugung geeigneter Licht- , Dunkelheits- und Farbstufen in einem gerenderten Bild). Sie führen jetzt eine Vielzahl von spezialisierten Funktionen in verschiedenen Bereichen innerhalb der Kategorie der Computergrafik- Spezialeffekte durch oder führen eine Video-Nachbearbeitung ohne Bezug zur Schattierung durch oder führen sogar Funktionen aus, die nicht mit Grafiken in Zusammenhang stehen .

Herkömmliche Shader berechnen Rendering- Effekte auf Grafikhardware mit hoher Flexibilität. Die meisten Shader sind für eine Grafikverarbeitungseinheit (GPU) codiert (und laufen darauf ), obwohl dies keine strikte Anforderung ist. Shading-Sprachen werden verwendet, um die Rendering-Pipeline der GPU zu programmieren , die größtenteils die Fixed-Function-Pipeline der Vergangenheit abgelöst hat, die nur gängige Geometrietransformations- und Pixel-Shading- Funktionen zuließ ; mit Shadern können benutzerdefinierte Effekte verwendet werden. Die Position und Farbe ( Farbton , Sättigung , Helligkeit und Kontrast ) aller Pixel , Scheitelpunkte und/oder Texturen, die zum Erstellen eines endgültig gerenderten Bildes verwendet werden, können mit in einem Shader definierten Algorithmen geändert und durch externe Variablen oder Texturen modifiziert werden durch das Computerprogramm eingeführt, das den Shader aufruft.

Shader werden häufig in der Nachbearbeitung von Kinos , computergenerierten Bildern und Videospielen verwendet , um eine Reihe von Effekten zu erzeugen. Neben einfachen Beleuchtungsmodellen umfassen komplexere Anwendungen von Shadern: Ändern des Farbtons , der Sättigung , der Helligkeit ( HSL/HSV ) oder des Kontrasts eines Bildes; Unschärfe erzeugen , Light Bloom , volumetrische Beleuchtung , Normal Mapping (für Tiefeneffekte), Bokeh , Cel Shading , Posterization , Bump Mapping , Distortion , Chroma Keying (für sogenannte "Bluescreen/ Greenscreen " Effekte), Kanten- und Bewegungserkennung , as sowie psychedelische Effekte, wie sie in der Demoszene zu sehen sind .

Geschichte

Diese Verwendung des Begriffs "Shader" wurde von Pixar mit der Version 3.0 ihrer RenderMan Interface Specification, die ursprünglich im Mai 1988 veröffentlicht wurde, der Öffentlichkeit vorgestellt .

Als Grafikprozessoren Grafiken entwickelt, wichtige Softwarebibliotheken wie OpenGL und Direct3D begann Unterstützung Shadern. Die ersten Shader-fähigen GPUs unterstützten nur Pixel-Shading , aber Vertex-Shader wurden schnell eingeführt, als die Entwickler die Leistungsfähigkeit von Shadern erkannten. Die erste Grafikkarte mit einem programmierbaren Pixel-Shader war die 2001 veröffentlichte Nvidia GeForce 3 (NV20). Geometrie-Shader wurden mit Direct3D 10 und OpenGL 3.2 eingeführt. Schließlich entwickelte sich die Grafikhardware zu einem einheitlichen Shader-Modell .

Entwurf

Shader sind einfache Programme, die die Eigenschaften eines Vertex oder eines Pixels beschreiben . Vertex-Shader beschreiben die Attribute (Position, Texturkoordinaten , Farben usw.) eines Vertex, während Pixel-Shader die Eigenschaften (Farbe, Z-Tiefe und Alpha- Wert) eines Pixels beschreiben. Ein Vertex-Shader wird für jeden Vertex in einem Primitiv aufgerufen (möglicherweise nach der Tesselation ); also ein Scheitel rein, ein (aktualisierter) Scheitel raus. Jeder Scheitelpunkt wird dann als eine Reihe von Pixeln auf eine Oberfläche (Speicherblock) gerendert, die schließlich an den Bildschirm gesendet wird.

Shader ersetzen einen Abschnitt der Grafikhardware, der normalerweise als Fixed Function Pipeline (FFP) bezeichnet wird und so genannt wird, weil er Beleuchtungs- und Textur-Mapping auf hartcodierte Weise durchführt. Shader bieten eine programmierbare Alternative zu diesem hartcodierten Ansatz.

Die grundlegende Grafikpipeline sieht wie folgt aus:

  • Die CPU sendet Anweisungen (kompilierte Shading-Sprachprogramme ) und Geometriedaten an die Grafikverarbeitungseinheit, die sich auf der Grafikkarte befindet.
  • Innerhalb des Vertex-Shaders wird die Geometrie transformiert.
  • Wenn ein Geometrie-Shader in der Grafikverarbeitungseinheit und aktiv ist, werden einige Änderungen der Geometrien in der Szene durchgeführt.
  • Wenn ein Tessellation-Shader in der Grafikverarbeitungseinheit und aktiv ist, können die Geometrien in der Szene unterteilt werden .
  • Die berechnete Geometrie wird trianguliert (unterteilt in Dreiecke).
  • Dreiecke werden in Fragment-Quads zerlegt (ein Fragment-Quad ist ein 2 × 2-Fragment-Primitive).
  • Fragment-Quads werden gemäß dem Fragment-Shader modifiziert.
  • Der Tiefentest wird durchgeführt; Fragmente , die übergeben werden , werden auf den Bildschirm geschrieben und werden möglicherweise in den Bildpuffer eingeblendet .

Die Grafikpipeline verwendet diese Schritte, um dreidimensionale (oder zweidimensionale) Daten in nützliche zweidimensionale Daten zum Anzeigen umzuwandeln. Im Allgemeinen ist dies eine große Pixelmatrix oder ein „ Framebuffer “.

Typen

Es gibt drei gängige Shader-Typen (Pixel-, Vertex- und Geometrie-Shader), von denen einige erst kürzlich hinzugefügt wurden. Während ältere Grafikkarten für jeden Shader-Typ separate Verarbeitungseinheiten verwenden, verfügen neuere Karten über einheitliche Shader, die in der Lage sind, jeden Shader-Typ auszuführen. Dadurch können Grafikkarten die Rechenleistung effizienter nutzen.

2D-Shader

2D-Shader wirken auf digitale Bilder , im Bereich der Computergrafik auch Texturen genannt . Sie ändern die Attribute von Pixeln . 2D-Shader können am Rendern von 3D-Geometrie beteiligt sein . Derzeit ist der einzige Typ von 2D-Shadern ein Pixel-Shader.

Pixel-Shader

Pixel - Shadern, auch bekannt als Fragment Shadern, compute Farbe und andere Attribute jedes „Fragment“: eine Arbeitseinheit Rendering höchstens einem einzigen Ausgang zu beeinflussen Pixels . Die einfachsten Arten von Pixel - Shader - Ausgang einen Bildschirm - Pixel als ein Farbwert; komplexere Shader mit mehreren Ein-/Ausgängen sind ebenfalls möglich. Pixel-Shader reichen von der einfachen Ausgabe immer derselben Farbe über das Anwenden eines Beleuchtungswerts bis hin zu Bump-Mapping , Schatten , Glanzlichtern , Transluzenz und anderen Phänomenen. Sie können die Tiefe des Fragments ändern (für Z-Puffer ) oder mehr als eine Farbe ausgeben, wenn mehrere Renderziele aktiv sind. In 3D-Grafiken kann ein Pixel-Shader allein keine komplexen Effekte erzeugen, da er nur an einem einzelnen Fragment arbeitet, ohne die Geometrie einer Szene (dh Vertex-Daten) zu kennen. Pixelshader kennen jedoch die gezeichneten Bildschirmkoordinaten und können den Bildschirm und benachbarte Pixel abtasten, wenn der Inhalt des gesamten Bildschirms als Textur an den Shader übergeben wird. Diese Technik kann eine Vielzahl von zweidimensionalen Nachbearbeitungseffekten wie Unschärfe oder Kantenerkennung /Verbesserung für Cartoon/Cel-Shader ermöglichen . Pixel-Shader können auch in Zwischenstufen auf beliebige zweidimensionale Bilder – Sprites oder Texturen – in der Pipeline angewendet werden , während Vertex-Shader immer eine 3D-Szene erfordern. Ein Pixel-Shader ist beispielsweise die einzige Art von Shader, die als Postprozessor oder Filter für einen Videostream fungieren kann, nachdem dieser gerastert wurde .

3D-Shader

3D-Shader wirken auf 3D-Modelle oder andere Geometrien, können aber auch auf die Farben und Texturen zugreifen, die zum Zeichnen des Modells oder Netzes verwendet werden . Vertex-Shader sind die älteste Art von 3D-Shadern, die im Allgemeinen Änderungen pro Vertex vornehmen. Neuere Geometrie-Shader können neue Scheitelpunkte aus dem Shader heraus generieren. Tessellation-Shader sind die neuesten 3D-Shader; Sie wirken auf Stapel von Scheitelpunkten auf einmal, um Details hinzuzufügen – wie zum Beispiel das Unterteilen eines Modells in kleinere Gruppen von Dreiecken oder anderen Grundelementen zur Laufzeit, um Dinge wie Kurven und Erhebungen zu verbessern oder andere Attribute zu ändern.

Vertex-Shader

Vertex-Shader sind die etabliertesten und gebräuchlichsten 3D-Shader und werden einmal für jeden an den Grafikprozessor übergebenen Vertex ausgeführt . Der Zweck besteht darin, die 3D-Position jedes Scheitelpunkts im virtuellen Raum in die 2D-Koordinate zu transformieren, an der er auf dem Bildschirm erscheint (sowie einen Tiefenwert für den Z-Puffer). Vertex-Shader können Eigenschaften wie Position, Farbe und Texturkoordinaten manipulieren, aber keine neuen Vertices erstellen. Die Ausgabe des Vertex-Shaders geht an die nächste Stufe in der Pipeline, bei der es sich entweder um einen Geometrie-Shader, falls vorhanden, oder um den Rasterizer handelt . Vertex-Shader können eine leistungsstarke Kontrolle über die Details von Position, Bewegung, Beleuchtung und Farbe in jeder Szene mit 3D-Modellen ermöglichen .

Geometrie-Shader

Geometrie-Shader wurden in Direct3D 10 und OpenGL 3.2 eingeführt; früher verfügbar in OpenGL 2.0+ mit der Verwendung von Erweiterungen. Dieser Shader-Typ kann neue Grafikprimitive wie Punkte, Linien und Dreiecke aus den an den Anfang der Grafikpipeline gesendeten Primitiven generieren .

Geometrie-Shader-Programme werden nach Vertex-Shadern ausgeführt. Sie nehmen als Eingabe ein ganzes Primitiv, möglicherweise mit Nachbarschaftsinformationen. Wenn Sie beispielsweise mit Dreiecken arbeiten, sind die drei Scheitelpunkte die Eingabe des Geometrie-Shaders. Der Shader kann dann null oder mehr Primitive emittieren, die gerastert und ihre Fragmente schließlich an einen Pixelshader übergeben werden .

Zu den typischen Anwendungen eines Geometrie-Shaders gehören die Punkt-Sprite-Generierung, die Geometrie- Tessellation , die Extrusion von Schattenvolumen und das Rendern in einem Durchgang zu einer Cube-Map . Ein typisches Praxisbeispiel für die Vorteile von Geometrie-Shadern wäre die automatische Änderung der Netzkomplexität. Eine Reihe von Linienstreifen, die Kontrollpunkte für eine Kurve darstellen, werden an den Geometrie-Shader übergeben und je nach der erforderlichen Komplexität kann der Shader automatisch zusätzliche Linien erzeugen, von denen jede eine bessere Annäherung an eine Kurve bietet.

Tessellation-Shader

Ab OpenGL 4.0 und Direct3D 11 wurde eine neue Shader-Klasse namens Tessellation-Shader hinzugefügt. Es fügt dem traditionellen Modell zwei neue Shader-Stufen hinzu: Tessellation Control Shader (auch bekannt als Hull-Shader) und Tessellation Evaluation Shader (auch bekannt als Domain Shader), die zusammen eine Unterteilung einfacherer Netze in feinere Netze zur Laufzeit ermöglichen zu einer mathematischen Funktion. Die Funktion kann mit einer Vielzahl von Variablen in Beziehung gesetzt werden, insbesondere dem Abstand von der Betrachtungskamera, um eine aktive Detailskalierung zu ermöglichen . Auf diese Weise können Objekte in der Nähe der Kamera feine Details aufweisen, während weiter entfernte Objekte grobere Maschen aufweisen können, jedoch in der Qualität vergleichbar erscheinen. Es kann auch die erforderliche Mesh-Bandbreite drastisch reduzieren, indem es ermöglicht, dass Meshes einmal innerhalb der Shader-Einheiten verfeinert werden, anstatt sehr komplexe aus dem Speicher herunterzurechnen. Einige Algorithmen können jedes beliebige Mesh upsampling, während andere "Hinting" in Meshes erlauben, um die charakteristischsten Scheitelpunkte und Kanten zu bestimmen.

Primitive und Mesh-Shader

Circa 2017 fügte die AMD Vega- Mikroarchitektur Unterstützung für eine neue Shader-Stufe hinzu – primitive Shader – ähnlich den Compute-Shadern mit Zugriff auf die zum Verarbeiten der Geometrie erforderlichen Daten. Ebenso führte Nvidia 2018 mit seiner Turing-Mikroarchitektur Mesh- und Task-Shader ein, die eine ähnliche Funktionalität bieten und wie die primitiven Shader von AMD auch Compute-Shadern nachempfunden sind.

Im Jahr 2020 haben AMD und Nvidia die Mikroarchitekturen RDNA 2 und Ampere veröffentlicht, die beide Mesh-Shading durch DirectX 12 Ultimate unterstützen . Diese Mesh-Shader ermöglichen es der GPU, komplexere Algorithmen zu verarbeiten, mehr Arbeit von der CPU auf die GPU zu verlagern und bei algorithmenintensivem Rendering die Bildrate oder Anzahl der Dreiecke in einer Szene um eine Größenordnung zu erhöhen. Intel gab bekannt, dass Intel Arc Alchemist GPUs, die im ersten Quartal 2022 ausgeliefert werden, Mesh-Shader unterstützen werden.

Raytracing-Shader

Raytracing- Shader werden von Microsoft über DirectX Raytracing , von der Khronos Group über Vulkan , GLSL und SPIR-V sowie von Apple über Metal unterstützt .

Computing-Shader

Computing-Shader sind nicht auf Grafikanwendungen beschränkt, sondern verwenden dieselben Ausführungsressourcen für GPGPU . Sie können in Grafikpipelines verwendet werden, zB für zusätzliche Stufen in Animations- oder Beleuchtungsalgorithmen (zB Tiled Forward Rendering ). Einige Rendering-APIs ermöglichen Compute-Shadern die einfache gemeinsame Nutzung von Datenressourcen mit der Grafikpipeline.

Parallelverarbeitung

Shader werden geschrieben, um Transformationen auf einen großen Satz von Elementen gleichzeitig anzuwenden, beispielsweise auf jedes Pixel in einem Bereich des Bildschirms oder auf jeden Scheitelpunkt eines Modells. Dies ist gut für die parallele Verarbeitung geeignet , und die meisten modernen GPUs verfügen über mehrere Shader- Pipelines , um dies zu erleichtern, wodurch der Rechendurchsatz erheblich verbessert wird.

Ein Programmiermodell mit Shadern ähnelt einer Funktion höherer Ordnung zum Rendern, wobei die Shader als Argumente verwendet werden und ein spezifischer Datenfluss zwischen Zwischenergebnissen bereitgestellt wird, wodurch sowohl Datenparallelität (über Pixel, Vertices usw.) als auch Pipeline-Parallelität (zwischen Stufen) ermöglicht wird. (siehe auch Karte verkleinern ).

Programmierung

Die Sprache, in der Shader programmiert werden, hängt von der Zielumgebung ab. Die offizielle Shading-Sprache von OpenGL und OpenGL ES ist OpenGL Shading Language , auch bekannt als GLSL, und die offizielle Direct3D-Shading-Sprache ist High Level Shader Language , auch bekannt als HLSL. Cg , eine Shading-Sprache eines Drittanbieters, die sowohl OpenGL- als auch Direct3D-Shader ausgibt, wurde von Nvidia entwickelt ; seit 2012 ist es jedoch veraltet. Apple hat seine eigene Shading-Sprache namens Metal Shading Language als Teil des Metal-Frameworks veröffentlicht .

GUI-Shader-Editoren

Moderne Videospiel- Entwicklungsplattformen wie Unity und Unreal Engine enthalten zunehmend knotenbasierte Editoren , die Shader erstellen können, ohne dass tatsächlicher Code erforderlich ist. dem Benutzer wird stattdessen ein gerichteter Graph verbundener Knoten präsentiert, der es dem Benutzer ermöglicht, verschiedene Texturen, Karten und mathematische Funktionen in Ausgabewerte wie die diffuse Farbe, die spiegelnde Farbe und Intensität, Rauheit/Metallität, Höhe, Normale usw. umzuleiten . Die automatische Kompilierung verwandelt den Graphen dann in einen tatsächlichen, kompilierten Shader.

Siehe auch

Verweise

Weiterlesen

Externe Links