Shader (historisch)
Inhaltsverzeichnis
Shader
Konzept
Die traditionelle Funktionspipeline der OpenGL ist eine feste Pipeline, auf die man nur beschränkt Einfluß nehmen kann (durch Statechanges), man hat also an sehr vielen Stellen starre Vorgaben die nur minimal anpassbar sind. So sind z.B. Farbberechnungen oder die Beleuchtung fest definiert und nur wenige ihrer Attribute können variiert werden. Zurückzuführen war/ist dieser Umstand v.a. darauf dass Grafikkarten bis vor kurzem nur feste Berechnungseinheiten besaßen, die man auch nicht programmieren konnte. (siehe z.B. die fest verdrahtete T&L-Einheit der ersten nVidia GeForce-Karten)
Allerdings haben vor einigen Jahren Grafikkarten mit teilweise programmierbaren Einheiten (erst waren dies recht eingeschränkt programmierbare Vertexeinheiten, inzwischen sind selbst die Fragmentprozessoren recht frei programmierbar, siehe z.B. VS/PS3.0) Einzug in den Consumermarkt gefunden, und so war es nötig OpenGL auch um programmierbare Pipeline-Teile zu erweitern, und die neuste Inkarnation sind dabei Shader.
Seit neuestem gibt es neben den herstellerabhängigen Funktionen zum Programmieren der Vertex- und Fragmentprozessoren auch standardisierte Erweiterungen. Zuerst waren dies GL_VERTEX_PROGRAM_ARB/GL_FRAGMENT_PROGRAM_ARB, mit denen man diese beiden Prozessoren (sofern auf der Grafikkarte vorhanden) in einer an Assembler (recht primitiv, mit nur wenigen Befehlen, alle auf Grafikprogrammierung ausgelegt) angelehnten Sprache programmieren konnte. Man schreibt dazu also ein Programm dass den entsprechenden Teil der festen Funktionspipeline ersetzt und führt dieses dann auf der Grafikkarte aus. So kann man für Vertices und Fragmente komplett eigene Berechnungen durchführen. Allerdings ist eine solche Assemblersprache nicht nur recht eingeschränkt, sondern auch recht kryptisch und daher nicht zuletzt (besonders bei großen Programmen) schlecht zu warten. Also hat OpenGL hier genau wie die normalen Programmiersprachen als nächste Iteration (OpenGL 2.0) für programmierbare Teile der Pipeline eine Hochsprache verpasst bekommen, namentlich als GlSlang bekannt.
Hiessen die Programme unter der Assemblersprache noch Vertexprogramm bzw. Fragmentprogramm, so hat man sich unter GlSlang etwas angepasst (an D3D) und nennt diese nun Vertexshader bzw. Fragmentshader (Shader bedeutet "schattieren", stimmt also nicht 100%ig).
Diese Shader kann man wie angesprochen nun in einer an C angelehnten Hochsprache schreiben, was zur Folge hat dass sich die Programmierung der entsprechenden Grafikprozessoren reichlich vereinfacht hat, und ausserdem hat man glSlang um recht viele Dinge erweitert die in der Assemblersprache nicht (oder nicht gerade einfach) möglich waren. Darunter Schleifen, Funktionen, uvm.
Voraussetzungen
Shader sind ein recht neues Konzept unter OpenGL und mit glSlang wollte man eine reichlich zukunftsorientierte Hochsprache für Shader schaffen. Deshalb hat man gleich auf alte Shaderversionen verzichtet und setzt Vertexshader und Pixelshader in der Version 2.0 voraus, die bei ATI ab der Radeon 9500 und bei NVidia ab der Geforce FX zur Verfügung stehen.
Momentan stellt glSlang eine Erweiterung zur OpenGL-Version 1.5 dar, also benötigt man neben der oben erwähnten Hardware auch noch passende Treiber und OpenGL-Header. Für Delphi bietet die DGL einen eigenen Header an, der diese Funktionalität mitbringt (Download).
Extensions
- GL_ARB_Shader_Objects
- GL_ARB_Vertex_Shader
- GL_ARB_Fragment_Shader
- GL_ARB_Shading_Language_100
Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind.
Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu.
Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu.
Gibt die unterstützte Version von glSlang an, momentan 1.00.
Alternativen
Vertex- und Fragmentprogramme
Die Erweiterungen GL_ARB_vertex_program und GL_ARB_fragment_program ermöglichen die Programmierung von Programmen ("andere" Bezeichnung für Shader) auf VS/PS2.0-Hardware in einer Assembler-Sprache. Die Erweiterungen sind herstellerunabhängig, werden aber wohl aufgrund von glSlang nicht mehr (oder nur marginal) weiterentwickelt.
Vertex- und Fragmentprogramme (NVidia)
Ähnlich wie oben erwähnte, herstellerunabhängige, Erweiterungen für Vertex- und Fragmentprogramme bietet NVidia ein Äquivalent (auch Assembler, aber mit anderen Mnemonics, Befehlen und Syntax) dazu an. Diese Erweiterungen werden mit jeder neuen Hardwaregeneration weiterentwickelt, um deren Shaderfähigkeiten nutzbar machen zu können, ohne dabei auf eine vom ARB abgesegnete Erweiterung warten zu müssen. Je nach Hardware stehen dann GL_NV_vertex_program, GL_NV_vertex_program1_1, GL_NV_vertex_program2 und GL_NV_vertex_program3 bzw. GL_NV_fragment_program und GL_NV_fragment_program2 zur Verfügung.
Vertex- und Fragmentshader (ATI)
Mit Einführung der Radeon 8500-Reihe, die Pixelshader und Vertexshader in Version 1.4 beherschte, führte ATI (in Ermangelung passender GL-Funktionalität) eigene Erweiterungen ein mit denen man (jedoch recht undynamisch) VS/PS1.4 in OpenGL nutzen kann, und zwar in Form von GL_ATI_vertex_shader, GL_ATI_fragment_shader und GL_ATI_text_fragment_shader. Trotz der Namensverwandschaft haben diese Extensions in Sachen Programmierung so gut wie nichts mit glSlang gemein.
Registercombiner und Textureshader (NVidia)
Seit der GeForce2-Reihe gibt es von NVidia sog. Registercombiner und Textureshader, die man in etwa mit recht eingeschränkten Shadern vergleichen kann. Da neure NVidia Hardware VS/PS2.0+ kann, werden diese Erweiterungen nicht mehr weiterentwickelt. Je nach verwendeter Hardware sind die nutzbaren Erweiterungen GL_NV_register_combiners und GL_NV_register_combiners2 bzw. GL_NV_texture_shader, GL_NV_texture_shader2 und GL_NV_texture_shader3.
Funktionen
- glAttachObjectARB
- glBindAttribLocationARB
- glCompileShaderARB
- glCreateProgramObjectARB
- glCreateShaderObjectARB
- glDeleteObjectARB
- glDetachObjectARB
- glEnableVertexAttribArrayARB
- glGetActiveAttribARB
- glGetActiveUniformARB
- glGetAttachedObjectsARB
- glGetAttribLocationARB
- glGetHandleARB
- glGetInfoLogARB
- glGetObjectParameterARB
- glGetShaderSourceARB
- glGetUniformARB
- glGetUniformLocationARB
- glGetVertexAttribARB
- glGetVertexAttribPointervARB
- glLinkProgramARB
- glShaderSourceARB
- glUniformARB
- glUseProgramObjectARB
- glValidateProgramARB
- glVertexAttribARB
- glVertexAttribPointerARB
Ressourcen
Informationen
- Official OpenGL 2.0 Specifications (Englisch)
- Offizielle GlSlang-Dokumentation (Englisch)
- Offizielle OpenGL2/OpenGL HLSL-Seiten (Englisch)
- OpenGL-Header für Delphi (mit GlSlang-Extensions)
- GlSlang-Tutorial auf DGL (Deutsch)
- GlSlang Tutorials (Englisch)
- ShaderTech - GPU Programming (Englisch)
- NeHe GLSL Introduction (Englisch)
- Cg Pixel Shaders in OpenGL (Englisch)
Programme/Tools
- OpenGL-Shaderdesigner von Typhoon Labs
- Shader Ninja von Weesel Software
- ATis RenderMonkey (OpenGL-Version momentan noch nicht öffentlich zugänglich)
- nVidias SDK (Beinhaltet diverse GlSlang-Beispielanwendungen/Shader)
- GPGPU - General-Purpose Computation Using Graphics Hardware