Shader ist keine Magie. Shader in Unity schreiben. Einleitung

Hallo allerseits! Mein Name ist Grigory Dyadichenko und ich bin der Gründer und CTO von Foxsys Studios. Heute möchte ich über Shader sprechen. Die Fähigkeit, Shader zu schreiben (und im Allgemeinen mit dem Rendering zu arbeiten), ist bei der Entwicklung für mobile Plattformen oder AR / VR sehr wichtig, wenn Sie coole Grafiken erzielen möchten. Viele Entwickler halten Shader für magisch. Dass es wenig gute Informationen über sie gibt und dass man, um sie zu schreiben, mindestens den Titel eines Wissenschaftskandidaten haben muss. Ja, die Entwicklung von Shadern nach ihren Prinzipien unterscheidet sich stark von der Kundenentwicklung. Die Hauptsache ist jedoch, die Grundprinzipien der Shader zu verstehen und ihre Essenz zu kennen, damit es nichts Magisches gibt und die Suche nach Informationen zu diesem Thema eine einfache Aufgabe war. Diese Artikelserie ist für Anfänger gedacht. Wenn Sie also gut darin sind, Shader zu programmieren, ist diese Serie für Sie nicht von Interesse. Wer dieses Thema verstehen will - willkommen unter dem Schnitt!



Dies ist ein einführender Artikel, in dem ich die allgemeinen Prinzipien des Schreibens von Shadern beschreiben werde. Wenn das Thema interessant ist, werden wir es in separaten Artikeln genauer analysieren: Vertex-Shader, geometrische Shader, Fragment- / Pixel-Shader, triplanare Shader, Screenspace-Effekte und Computer-Shader (OpenCL, CUDA usw.). Und im Allgemeinen all die Magie, die auf der GPU ausgeführt werden kann. Dies wird im Kontext der Unity-Standardpipeline geregelt. LWRP und HDRP scheinen mir bisher etwas feucht zu sein.

Was ist ein Shader?



Quelle: www.shadertoy.com/view/MsGSRd

Tatsächlich ist dies ein Programm, das auf der GPU ausgeführt wird und dessen Ausgabe unterschiedliche Informationen enthält. In Vertex-Shadern sind dies die Parameter der Mesh-Vertices. Pixel-Shader werden Pixel für Pixel ausgeführt.

Um zu verstehen, wie Shader funktionieren, müssen Sie angeben, was eine Grafikpipeline ist. Sehr oft sprechen die Leute in ziemlich komplizierten Worten über dieses Thema, aber wir werden es ein wenig leichter verständlich machen. Nehmen Sie das Beispiel von OpenGL. In dieser Hinsicht mag ich dieses Bild wirklich.



Wenn Sie Teile im Zusammenhang mit Beleuchtung usw. weglassen. Im Allgemeinen ist das Wesentliche vom Schreiben der gleichen nicht beleuchteten Shader auf hlsl wie folgt. Wir haben einen Shader

#pragma vertex vert #pragma fragment frag 

Dabei bestimmen wir, dass der Scheitelpunktteil des Shaders in die Vert-Funktion und der Fragmentteil in die Frag-Funktion geschrieben wird.

Die Strukturen, die wir im Shader beschreiben, bestimmen, welche Daten aus dem Netz und nach der Verarbeitung mit dem Vertex-Shader entnommen werden, die an unseren MeshRenderer- und MeshFilter-Objekten hängen.

  struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; 

Als nächstes berechnet der Vertex-Shader, indem er die AppData-Daten als Eingabe empfängt, und gibt das Ergebnis in Form einer v2f-Struktur aus, die dann an den Fragment-Shader geht. Was wiederum bereits die Farbe des Pixels berechnet. Da v2f-Informationen nur in die Scheitelpunkte geschrieben werden (die kleiner als Pixel sind), werden die Daten im Fragmentteil interpoliert. All dies kann als die Tatsache dargestellt werden, dass vert in jedem Scheitelpunkt unabhängig betrachtet wird. Dann wird das Ergebnis auf den Fragmentteil übertragen, wo frag für jedes Pixel als unabhängig betrachtet wird. Da die Berechnungen parallel durchgeführt werden, gibt es in diesen Teilen keine Informationen über die Nachbarn (wenn Sie sie nicht irgendwie geschickt übertragen).

Ausführlicher werden alle Nuancen sowie viele Beispiele in der Dokumentation von Unity docs.unity3d.com/Manual/SL-Reference.html beschrieben

Shader-Programmiersprachen



Quelle: www.shadertoy.com/view/WsS3Dc

Was sonst noch wichtig ist, nicht zu vergessen. Die Tatsache, dass Shader jetzt in drei Programmiersprachen geschrieben sind, die nichts mit Einheit zu tun haben. CG, GLSL und HLSL. Der einfachste Weg, Shader in eine Einheit zu schreiben, ist HLSL, da hier Shader-Dateien mit der Berechtigung .shader geschrieben werden. Und wenn es im Kontext einer Einheit vergleichsweise wenig Informationen zu Shadern gibt, dann sind die Informationen zu HLSL, GLSL und CG nur Tonnen. In der Dokumentation für die Shader wird beschrieben, wie Sie das, was in diesen Sprachen geschrieben ist, an Unity übertragen. Daher stellt sich heraus, dass fast alle Informationen über diese Programmiersprachen im Allgemeinen gültig sind. Alle drei Sprachen sind C sehr ähnlich, aber jede hat ihre eigenen Eigenschaften.

Unter dem Gesichtspunkt des Studierens von Shadern können Sie außerdem sehen, welche Möglichkeiten "UnityCG.cginc" und andere von Unity geschriebene Bibliotheken an sich bieten, um ihre Arbeit zu vereinfachen, wenn diese Sprachen keine Fragen mehr aufwerfen.

Warum, wenn in Shadern schlecht ist?



Quelle: www.shadertoy.com/view/Md3cWr

Es ist wichtig zu verstehen, wie Shader auf Eisenebene ausgeführt werden und warum sie so schnell sind, dass sie Millionen von Operationen ohne Anstrengung ausführen können.

Die Hauptidee von GPUs ist die maximale Parallelität der Berechnungen. Hier ist es notwendig, ein solches Konzept als „Wellenfront“ einzuführen. Tatsächlich ist es ganz einfach, dass die Wellenfront eine Gruppe von Shadern ist, die dieselbe Abfolge von Operationen ausführen. Das heißt, aus Sicht der GPU ist die beste Option, wenn dieselben Anweisungen zur gleichen Zeit ausgeführt werden. Der einzige Unterschied in der Ausführung ist die Eingabe. Das Problem der Verzweigung besteht darin, dass eine Situation auftreten kann, wenn in einer einzelnen Gruppe von Shadern Shader unterschiedliche Operationen aufrufen müssen. Dies führt wiederum zur Schaffung einer neuen Wellenfront, zum Kopieren von Daten usw. Und es ist sehr teuer.

Es gibt Nuancen und Ausnahmen, aber um sicher zu schreiben, ob, müssen Sie verstehen, wie es sich auf der Zielversion der Grafik-API verhält. Da die gleichen OpenGL ES 2 oder DX11 in dieser Hinsicht sehr unterschiedlich sind.

Warum muss ich das wissen, weil es Knoteneditoren gibt?




Es ist wichtig zu verstehen, dass Node-Editoren in erster Linie ein Werkzeug für technische Künstler sind. Dies sind Spezialisten mit mathematischem Fachwissen, aber mehr Designern. Shader vom Drahtgittertyp (bei denen das Verständnis der Schwerpunktkoordinaten erforderlich ist) oder die Transformation in kartesische Koordinaten, die für knifflige Projektionen verwendet wird, sind mit Code um ein Vielfaches einfacher, wie viele mathematische Modelle physikalischer Materialien. Gleichzeitig erstellen Sie aus Sicht eines Shader-Programmierers im Wesentlichen benutzerdefinierte Knoten und Werkzeuge für technische Künstler, um echte Magie zu erzeugen. Knoteneditoren haben unter diesem Gesichtspunkt eine eingeschränkte Funktionalität. Daher ist es wichtig, Shader in Sprachen wie hlsl schreiben zu können. Verstehen Sie, wie das Rendern usw. funktioniert.

Nützliche Ressourcen zum Lernen



Quelle: www.shadertoy.com/view/4tlcWj

In Bezug auf das Erlernen der Shader-Programmierung ist es eine gute Übung, Shader von www.shadertoy.com oder glslsandbox.com neu zu schreiben. Darüber hinaus gibt es ein cooles Profil eines Spezialisten von Unity, in dem Sie viele interessante github.com/keijiro sehen können

Alles andere ist Mathematik und ein Verständnis der Physik der Effekte. Dies ähnelt dem Mischen der Inhaltsstoffe, wenn das spezifische Problem der physikalischen Modellierung nicht gelöst ist. Viele interessante Dinge können durch Mischen von Rauschen, Brechung, Streuung von Licht unter der Oberfläche, Ätzmitteln, Fresneleffekt, Diffusionsreaktion und anderen physikalischen Eigenschaften von Objekten erreicht werden. Im Allgemeinen ist die Shader-Programmierung sicherlich nicht elementar, und es gibt Möglichkeiten, sich eingehend mit dem Thema zu befassen.

Wenn das Thema Shader interessant ist, werde ich versuchen, eine Reihe von Artikeln zu diesem Thema zu veröffentlichen, die bereits spezifische Beispiele und Tutorials zum Thema Erstellen verschiedener Effekte enthalten. Schlagen Sie in den Kommentaren vor, was Sie lesen möchten und welche Themen Sie studieren möchten. Vielen Dank für Ihre Aufmerksamkeit!

Alle Effekte in diesem Artikel sind eine Aufzeichnung von Shader-Effekten mit Shadertoy.

Source: https://habr.com/ru/post/de473638/


All Articles