Verwenden von Shadern in Direct3D 9

Kompilieren eines Shaders für bestimmte Hardware

Shader wurden zuerst Microsoft DirectX in DirectX 8.0 hinzugefügt. Zu dieser Zeit wurden mehrere virtuelle Shadercomputer definiert, die jeweils ungefähr einem bestimmten Grafikprozessor entsprechen, der von den führenden 3D-Grafikanbietern produziert wurde. Für jeden dieser virtuellen Shadercomputer wurde eine Assemblysprache entwickelt. Programme, die in die Shadermodelle geschrieben wurden (Namen vs_1_1 und ps_1_1 - ps_1_4) waren relativ kurz und wurden in der Regel von Entwicklern direkt in der entsprechenden Assemblysprache geschrieben. Die Anwendung übergibt diesen für Menschen lesbaren Assemblysprachencode mithilfe von D3DXAssembleShader an die D3DX-Bibliothek und erhält eine binäre Darstellung des Shaders, die wiederum mit CreateVertexShader oder CreatePixelShader übergeben würde. Weitere Informationen finden Sie im Software Development Kit (SDK).

Die Situation in Direct3D 9 ist ähnlich. Eine Anwendung übergibt einen HLSL-Shader mithilfe von D3DXCompileShader an D3DX und ruft eine binäre Darstellung des kompilierten Shaders zurück, die wiederum mit CreatePixelShader oder CreateVertexShader an Microsoft Direct3D übergeben wird. Die Runtime weiß nichts über HLSL, nur die binären Assembly-Shadermodelle. Dies ist schön, da es bedeutet, dass der HLSL-Compiler unabhängig von der Direct3D-Runtime aktualisiert werden kann. Sie können Shader auch offline mit fxc kompilieren.

Zusätzlich zur Entwicklung des HLSL-Compilers hat Direct3D 9 auch die Shadermodelle auf Assemblyebene eingeführt, um die Funktionalität der neuesten Generation von Grafikhardware verfügbar zu machen. Anwendungsentwickler können in der Assembly für diese neuen Modelle (vs_2_0, vs_3_0, ps_2_0, ps_3_0) arbeiten, aber wir erwarten, dass die meisten Entwickler zur Shaderentwicklung zu HLSL wechseln.

Natürlich ermöglicht die Möglichkeit, ein HLSL-Programm zu schreiben, um einen bestimmten Schattierungsalgorithmus auszudrücken, es nicht automatisch auf einer bestimmten Hardware auszuführen. Eine Anwendung ruft D3DX auf, um einen Shader mit D3DXCompileShader in binären Assemblycode zu kompilieren. Eine der Einschränkungen bei diesem Einstiegspunkt ist ein Parameter, der definiert, welche der Modelle auf Assemblyebene (oder Kompilierungsziele) der HLSL-Compiler verwenden soll, um den endgültigen Shadercode auszudrücken. Wenn eine Anwendung zur Laufzeit eine HLSL-Shaderkompilierung durchführt (im Gegensatz zur Kompilierzeit oder offline), kann die Anwendung die Funktionen des Direct3D-Geräts untersuchen und das Kompilierungsziel auswählen, das übereinstimmen soll. Wenn der im HLSL-Shader ausgedrückte Algorithmus zu komplex für die Ausführung auf dem ausgewählten Kompilierungsziel ist, schlägt die Kompilierung fehl. Dies bedeutet, dass HLSL zwar ein großer Vorteil für die Shaderentwicklung ist, entwickler aber nicht von den Realitäten des Versands von Spielen an eine Zielgruppe mit Grafikgeräten mit unterschiedlichen Funktionen befreit. Als Spieleentwickler müssen Sie immer noch einen mehrstufigen Ansatz für Ihre Visuals verwalten. Dies bedeutet, bessere Shader für leistungsfähigere Grafikkarten zu schreiben und mehr Basisversionen für ältere Karten zu schreiben. Mit gut geschriebenen HLSL kann diese Belastung jedoch deutlich gelockert werden.

Anstatt HLSL-Shader mithilfe von D3DX auf dem Computer des Kunden zur Anwendungsladezeit oder bei der ersten Verwendung zu kompilieren, entscheiden sich viele Entwickler, ihren Shader vor dem Versand von HLSL in binären Assemblycode zu kompilieren. Dies hält den HLSL-Quellcode vor neugierigen Blicken fern und stellt außerdem sicher, dass alle Shader, die ihre Anwendung jemals ausführen wird, ihren internen Qualitätssicherungsprozess durchlaufen haben. Ein praktisches Hilfsprogramm zum Offline-Kompilieren von Shadern ist fxc. Dieses Tool verfügt über eine Reihe von Optionen, mit denen Sie Code für das angegebene Kompilierungsziel kompilieren können. Das Studium der zerlegten Ausgabe kann während der Entwicklung sehr lehrreich sein, wenn Sie Ihre Shader optimieren oder einfach nur die Funktionen des virtuellen Shadercomputers auf einer detaillierteren Ebene kennenlernen möchten. Diese Optionen sind unten zusammengefasst:

Initialisieren von Shaderkonstanten

Shaderkonstanten sind in der Konstantentabelle enthalten. Darauf kann mit der ID3DXConstantTable-Schnittstelle zugegriffen werden. Globale Shadervariablen können im Shadercode initialisiert werden. Diese werden zur Laufzeit initialisiert, indem SetDefaults aufgerufen wird.

Binden eines Shaderparameters an ein bestimmtes Register

Der Compiler weist register automatisch globalen Variablen zu. Der Compiler würde dem Samplerregister s0 Umgebung zuweisen, SparkleNoise dem Samplerregister s1 und k_s dem Konstantenregister c0 (vorausgesetzt, dass bereits keine anderen Sampler- oder Konstantenregister zugewiesen wurden) für die folgenden drei globalen Variablen:

sampler Environment;
sampler SparkleNoise;
float4 k_s;

Es ist auch möglich, Variablen an ein bestimmtes Register zu binden. Verwenden Sie die folgende Syntax, um die Zuweisung zu einem bestimmten Register durch den Compiler zu erzwingen:

register(RegisterName)

wobei RegisterName der Name des spezifischen Registers ist. Die folgenden Beispiele veranschaulichen die spezifische Syntax der Registerzuweisung, bei der die Samplerumgebung an das Samplerregister s1, SparkleNoise an das Samplerregister s0 und k_s an das Konstantenregister c12 gebunden ist:

sampler Environment : register(s1);
sampler SparkleNoise : register(s0);
float4 k_s : register(c12);

Rendern eines programmierbaren Shaders

Ein Shader wird gerendert, indem der aktuelle Shader im Gerät festgelegt wird, die Shaderkonstanten initialisiert, dem Gerät mitgeteilt wird, von dem die unterschiedlichen Eingabedaten stammen, und schließlich die Grundtypen gerendert werden. Jede dieser Methoden kann durch Aufrufen der folgenden Methoden erreicht werden:

Debuggen von Shadern

Die DirectX-Erweiterung für Microsoft Visual Studio .NET stellt einen vollständig integrierten HLSL-Debugger innerhalb der integrierten Entwicklungsumgebung (Integrated Development Environment, IDE) von Visual Studio bereit. Um das Debuggen von Shadern vorzubereiten, müssen Sie die richtigen Tools auf Ihrem Computer installieren (siehe Debuggen von Shadern in Visual Studio (Direct3D 9)).

Programmieranleitung für HLSL