- Unified Shader
-
Shader, auch als Schattierer bezeichnet, sind Hardware- oder Softwaremodule, die bestimmte Renderingeffekte bei der 3D-Computergrafik implementieren. Aus technischer Sicht bezeichnet „Shader“ denjenigen Teil eines Renderers, der für die Ermittlung der Farbe eines Objektes zuständig ist – im Gegensatz zu dem Teil, der die Sichtbarkeit des Objektes ermittelt. Shader wurden ursprünglich für das Shading, also die Beleuchtungs-Berechnung, entwickelt, werden aber mittlerweile auch für andere Dinge verwendet.
Der Begriff „Shader“ wird sowohl für die Hardware-Shader als auch für die darauf laufenden Programme selbst verwendet.
Inhaltsverzeichnis
Hardware-Shader
Hardware-Shader (auch: Shadereinheiten, Shader Units) sind kleine Recheneinheiten in aktuellen Grafikchips (unter Windows seit DirectX-Version 8, plattformunabhängig seit OpenGL 2.0 ansprechbar). Traditionell wird zwischen zwei Typen unterschieden, den Pixel- und den Vertex-Shadern. Shader können zur Erzeugung von 3D-Effekten programmiert werden. Während Pixel-Shader die Bildpunkte verändern und auch die Pixelfarbe berechnen können, dienen Vertex-Shader geometrischen Berechnungen und dynamischen Veränderungen von Objekten. So erzeugen z.B. beide Shader kombiniert den Wassereffekt im Computerspiel Far Cry. Sie können auch zur Berechnung von Lava, Lack, Fell usw. eingesetzt werden. Seit DirectX 10 ist als dritter Shader-Typ der Geometry-Shader hinzugekommen, der die vom Vertex-Shader ausgegebenen Polygondaten erhält und diese noch weit flexibler bearbeiten kann, sogar weitere Geometrie zur Szene hinzufügen kann (der Vertex-Shader kann nur bestehende Geometrie manipulieren).
Pixel-, Vertex- und Geometry-Shadereinheiten dürfen nicht als vom Rest getrennte Recheneinheiten (wie bspw. Koprozessoren) verstanden werden, sondern als fester Teil des Grafikchips innerhalb seiner Rendering-Pipelines. So ist der Vertex-Shader lediglich eine programmierbare T&L-Einheit, der Pixel-Shader entstand historisch aus dem Combiner – der genaue Aufbau der Shader-Hardware ist geheim. Konformität dieser Shader-Einheiten zu den Standards DirectX und OpenGL wird über den Grafiktreiber hergestellt.
Da sich der Funktionsumfang von Vertex- und Pixel-Shadern mit der Zeit immer weiter erhöhte, wurde letztlich das Konzept der Unified Shader entwickelt, bei dem der hardwareseitige Unterschied zwischen Vertex-, Pixel- und Geometry-Shader verschwindet. Hierbei können alle Shader-Einheiten des Grafikchips nun dieselben Operationen ausführen, womit eine feste Trennung zwischen den drei Shader-Typen nicht mehr sinnvoll ist. In Folge dessen kann nun der Grafiktreiber selbst entscheiden, welche Shader-Einheit zu welchem Zeitpunkt als Vertex-, als Pixel- oder als Geometry-Shader eingesetzt wird, was potenziell eine bessere Leistungsausbeute als bei Grafikkarten mit fest eingeteilten Shader-Typen bedeutet. Aktuelle Versionen von OpenGL und DirectX unterstützen das Unified Shader-Konzept bereits und ab der Nvidia-GeForce-8-Serie und ATI-Radeon-HD-2000-Serie gibt es auch schon Grafikkarten, die es unterstützen.
Verarbeitungskette
- CPU sendet Steuerbefehle und Geometrie-Daten an die Grafikkarte.
- Im Vertex-Shader wird die Geometrie transformiert, außerdem werden bestimmte Licht-Berechnungen ausgeführt.
- Ist ein Geometry-Shader auf dem Grafikchip vorhanden, durchlaufen die Geometriedaten nun diesen, hierbei werden weitere Veränderungen an der Szene vorgenommen.
- Die fertigtransformierte Geometrie gelangt in das Triangle Setup. Dreiecke werden in Quads zerlegt (ein Quad besteht aus 2 × 2 Pixeln.)
- Die erste Stufe des Pixel-Shaders ist der Interpolator. Hier werden bestimmte, nur pro Eckpunkt (Vertex) vorliegende Informationen über die Dreiecksfläche interpoliert.
- Im Pixel-Shader gibt es arithmetische Rechenwerke (Shader Units) und Textur-Einheiten (Texture Mapping Units, TMUs).
- Nachdem die Pixelberechnung abgeschlossen ist, wird der Test auf Sichtbarkeit (Z-Test) ausgeführt. Bei Sichtbarkeit findet ein Schreibvorgang in den Framebuffer statt.
Programmierung
Shader werden in speziell dafür vorgesehenen Sprachen geschrieben (Assemblersprache, Cg, GLSL, HLSL) und zur Laufzeit der 3D-Anwendung vom Grafikkartentreiber in einen für die Grafikkarte verständlichen Maschinencode übersetzt, der dann in den Shadereinheiten ausgeführt wird. Bei Lowcost-Grafikchips werden die Shadereinheiten aber häufig weggelassen, wodurch die Shader mit Hilfe der CPU berechnet werden müssen, was wesentlich langsamer ist.
Damit die Funktionalität der Shader auch einheitlich von Anwendungen genutzt werden kann, bieten sowohl DirectX als auch OpenGL Schnittstellen für ihre Anwendung. Im Laufe der Zeit haben Funktionsumfang und Leistungsfähigkeit der anfangs noch ziemlich einfachen Shadereinheiten stark zugenommen; heute ist ihre Programmierbarkeit so weit fortgeschritten, dass man mit ihnen viele Berechnungen erledigen kann, die bisher nur CPUs ausführen konnten, oftmals sogar wesentlich schneller.
Problematik mit verschiedenen Versionen
Die ersten Hardware-Shader waren relativ einfach konzipiert, daher musste eine Softwareschnittstelle entsprechend wenig bieten. Da aber mit der Zeit die Funktionalität der Shader wuchs, mussten auch die Schnittstellen entsprechend erweitert werden, was insbesondere bei DirectX oftmals in Absprache mit den Grafikkartenherstellern geschah. In Folge dessen unterstützt nicht jeder Grafikchip jede Shaderversion, es ist keine Aufwärtskompatibilität gegeben. Das bedeutet, dass man bei der Programmierung von 3D-Grafikanwendungen mit Shadern darauf achten muss, dass eine Ausweichlösung für ältere Grafikkarten existiert, die die eigentlich angestrebte Shaderversion nicht unterstützen, ansonsten können sie die Grafik gar nicht oder nur stark verändert darstellen. Wenn eine Anwendung mehrere Shader-Lösungen für verschiedene Shaderversionen bzw. verschiedene Grafikkarten enthält, nennt man diese Lösungen Renderpfade (engl. rendering path). Gerade in den Phasen, in denen die damaligen Grafikkarten-Hauptkonkurrenten ATI und Nvidia eigene spezielle Shader-Versionen veröffentlichten, war es häufig nötig und daher gängig, zwei (oder auch mehr) Renderpfade in Anwendungen einzubauen: einen ATI-optimierten und einen Nvidia-optimierten, ggf. auch noch weitere.
DirectX
Unter Direct3D, der 3D-Grafikschnittstelle von DirectX, werden Shader in der Sprache HLSL programmiert, wobei je nach DirectX-Version verschiedene Shader-Versionen angeboten werden. Die folgende Tabelle zeigt den Zusammenhang zwischen den einzelnen DirectX- und Shader-Versionen:
DirectX-Version Pixel-Shader Vertex-Shader Bemerkungen 8.0 1.0 1.0 war für den 3dfx Rampage vorgesehen, der jedoch nie auf den Markt kam 1.1 1.0 kleinster gemeinsamer Nenner für alle DirectX-8-Grafikchips 8.0a 1.2 1.0 speziell von den 3DLabs-Grafikchips P9 und P10 unterstützt 1.3 speziell von der Nvidia-GeForce-4-Ti-Serie, der Matrox Parhelia und dem SiS Mirage 2[1] unterstützt 8.1 1.4 speziell von der Radeon-8000-Serie und der XGI-Volari-V3-Serie unterstützt 9.0 2.0 2.0 kleinster gemeinsamer Nenner für alle DirectX-9-Grafikchips 9.0a 2_A 2.x speziell von der Nvidia-GeForce-FX-Serie unterstützt 9.0b 2_B speziell von der ATI Radeon X7xx und X8xx unterstützt 9.0c 3.0 3.0 gemeinsamer Nenner für modernere DirectX-9-Grafikchips 10.0 4.0 4.0 Unified Shader Model 10.1 4.1 4.1 11 5 OpenGL
In OpenGL ist seit Version 2.0 eine eigene C-ähnliche Shader-Sprache integriert, die OpenGL Shading Language, kurz GLSL.[2] Zuvor war Shaderprogrammierung nur durch herstellerabhängige Schnittstellen möglich. Durch den Einsatz von GLSL ist man nicht mehr auf die Verwendung proprietärer Technologie sowie den Einsatz auf der Windows-Plattform beschränkt und kann Shader nun auf unterschiedlichsten Plattformen wie Mac OS X oder Linux benutzen.
Weblinks
Literatur
- Uli Theuerjahr: Direct3D Realtime Rendering für Computerspiele, 1. Auflage. Roulio Press, 2007, ISBN 9783000223402
Einzelnachweise
- ↑ AnandTech: A Place for SiS; New Athlon64, P4 and Integrated Graphics Chipsets, Artikel vom 27. Juli 2004 (englisch)
- ↑ OpenGL.org: OpenGL Shading Language, Dokumentation zur GLSL
Wikimedia Foundation.