Gibt es eine Analogie, die mir beim Vergleich dieser verschiedenen Typen einfällt, oder wie diese Dinge funktionieren?
Was bedeutet es auch, eine Matrix zu vereinheitlichen?
Antworten:
Direkt von http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ kopiert . Die eigentliche Seite enthält viel detailliertere Informationen und es lohnt sich, sie sich anzusehen.
Variable Qualifikatoren
Qualifizierer geben der Variablen eine besondere Bedeutung. Folgende Qualifikanten stehen zur Verfügung:
- const - Die Deklaration ist eine Kompilierungszeitkonstante.
- Attribut - Globale Variablen, die sich pro Scheitelpunkt ändern können und von der OpenGL-Anwendung an Scheitelpunkt-Shader übergeben werden. Dieses Qualifikationsmerkmal kann nur in Vertex-Shadern verwendet werden. Für den Shader ist dies eine schreibgeschützte Variable. Siehe Abschnitt Attribut.
- uniform - Globale Variablen, die sich pro Grundelement ändern können [...] und von der OpenGL-Anwendung an die Shader übergeben werden. Dieses Qualifikationsmerkmal kann sowohl in Vertex- als auch in Fragment-Shadern verwendet werden. Für die Shader ist dies eine schreibgeschützte Variable. Siehe Abschnitt Uniform.
- Variieren - Wird für interpolierte Daten zwischen einem Vertex-Shader und einem Fragment-Shader verwendet. Verfügbar zum Schreiben im Vertex-Shader und schreibgeschützt in einem Fragment-Shader. Siehe Abschnitt Variieren.
In einer Analogie sind const und uniform wie globale Variablen in C / C ++, eine ist konstant und die andere kann gesetzt werden. Attribut ist eine Variable, die einen Scheitelpunkt wie Farb- oder Texturkoordinaten begleitet. Unterschiedliche Variablen können vom Vertex-Shader geändert werden, nicht jedoch vom Fragment-Shader. Daher leiten sie im Wesentlichen Informationen über die Pipeline weiter.
uniform
sind pro-primitive Parameter (konstant während eines gesamten Draw-Aufrufs);attribute
sind Per-Vertex- Parameter (normalerweise: Positionen, Normalen, Farben, UVs, ...);varying
sind Parameter pro Fragment (oder pro Pixel ): Sie variieren von Pixel zu Pixel.Es ist wichtig zu verstehen, wie Sie varying
Ihre eigenen Shader programmieren.
Angenommen, Sie definieren einen variierenden Parameter v
für jeden Scheitelpunkt eines Dreiecks im Scheitelpunkt-Shader . Wenn dieser variierende Parameter an den Fragment-Shader gesendet wird , wird sein Wert automatisch basierend auf der Position des zu zeichnenden Pixels interpoliert.
Im folgenden Bild erhielt das rote Pixel einen interpolierten Wert des variierenden Parameters v
. Deshalb nennen wir sie "variierend".
Der Einfachheit halber verwendet das oben angegebene Beispiel eine bilineare Interpolation , bei der davon ausgegangen wird , dass alle gezeichneten Pixel den gleichen Abstand von der Kamera haben. Für ein genaues 3D-Rendering verwenden Grafikgeräte eine perspektivisch korrekte Interpolation, die die Tiefe eines Pixels berücksichtigt.
noperspective
, um eine einfache bilineare Interpolation und keine perspektivisch korrekte Interpolation zu erhalten (gekennzeichnet durch das Standardqualifikationsmerkmal :) smooth
. Siehe dieses Beispiel .
Was sind in WebGL die Unterschiede zwischen einem Attribut, einer Uniform und einer variierenden Variablen?
In OpenGL ist ein "Programm" eine Sammlung von "Shadern" (kleineren Programmen), die in einer Pipeline miteinander verbunden sind.
// "program" contains a shader pipeline:
// vertex shader -> other shaders -> fragment shader
//
const program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
Shader verarbeiten Scheitelpunkte (Vertex-Shader), Geometrien (Geometrie-Shader), Tessellation (Tessellation-Shader), Fragmente (Pixel-Shader) und andere Stapelprozessaufgaben (Compute-Shader), die zum Rastern eines 3D-Modells erforderlich sind.
OpenGL (WebGL) -Shader sind in GLSL (einer auf der GPU kompilierten textbasierten Shader-Sprache) geschrieben.
// Note: As of 2017, WebGL only supports Vertex and Fragment shaders
<!-- Vertex Shader -->
<script id="shader-vs" type="x-shader/x-vertex">
// <-- Receive from WebGL application
uniform vec3 vertexVariableA;
// attribute is supported in Vertex Shader only
attribute vec3 vertexVariableB;
// --> Pass to Fragment Shader
varying vec3 variableC;
</script>
<!-- Fragment Shader -->
<script id="shader-fs" type="x-shader/x-fragment">
// <-- Receive from WebGL application
uniform vec3 fragmentVariableA;
// <-- Receive from Vertex Shader
varying vec3 variableC;
</script>
Shader können Daten an den nächsten Shader in der Pipeline übergeben ( out
, inout
) und sie können auch Daten aus der WebGL-Anwendung oder einem vorherigen Shader ( in
) akzeptieren .
Die Vertex- und Fragment-Shader (wirklich jeder Shader) können eine uniform
Variable verwenden, um Daten von der WebGL-Anwendung zu empfangen.
// Pass data from WebGL application to shader
const uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
Der Vertex Shader kann auch Daten von der WebGL-Anwendung mit der attribute
Variablen empfangen , die bei Bedarf aktiviert oder deaktiviert werden können.
// Pass data from WebGL application to Vertex Shader
const attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
gl.glEnableVertexAttribArray(attributeHandle);
gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
Der Vertex Shader kann mithilfe der varying
Variablen Daten an den Fragment Shader übergeben . Siehe GLSL-Code oben ( varying vec3 variableC;
).
Uniformen sind eine weitere Möglichkeit, Daten aus unserer Anwendung auf der CPU an die Shader auf der GPU zu übergeben. Uniformen unterscheiden sich jedoch geringfügig von Vertex-Attributen. Erstens sind Uniformen global. Global, was bedeutet, dass eine einheitliche Variable pro Shader-Programmobjekt eindeutig ist und von jedem Shader zu jedem Zeitpunkt im Shader-Programm aus aufgerufen werden kann. Zweitens behalten Uniformen ihre Werte bei, bis sie entweder zurückgesetzt oder aktualisiert werden
Ich mag die Beschreibung von https://learnopengl.com/Getting-started/Shaders , weil das Wort pro Primitiv nicht intuitiv ist