Czy istnieje analogia, o której mogę pomyśleć, porównując te różne typy lub jak te rzeczy działają?
Co oznacza ujednolicenie macierzy?
Odpowiedzi:
Skopiowano bezpośrednio z http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ . Rzeczywista strona zawiera znacznie bardziej szczegółowe informacje i warto byłoby je sprawdzić.
Zmienne kwalifikatory
Kwalifikatory nadają zmiennej specjalne znaczenie. Dostępne są następujące kwalifikatory:
- const - Deklaracja jest stałą czasu kompilacji.
- atrybut - zmienne globalne, które mogą się zmieniać w zależności od wierzchołka, które są przekazywane z aplikacji OpenGL do programów do cieniowania wierzchołków. Tego kwalifikatora można używać tylko w programach do cieniowania wierzchołków. W przypadku modułu cieniującego jest to zmienna tylko do odczytu. Zobacz sekcję Atrybut.
- uniform - zmienne globalne, które mogą się zmieniać w zależności od [...] prymitywu, które są przekazywane z aplikacji OpenGL do modułów cieniujących. Ten kwalifikator może być używany zarówno w Vertex Shader, jak i Fragment Shader. W przypadku shaderów jest to zmienna tylko do odczytu. Zobacz sekcję Uniform.
- zmienny - używany do interpolowanych danych między Vertex Shaderem a Fragment Shaderem. Dostępne do zapisu w Vertex Shader i tylko do odczytu w Fragment Shader. Zobacz sekcję Różne.
Jeśli chodzi o analogię, const i uniform są jak zmienne globalne w C / C ++, jedna jest stała, a druga może być ustawiona. Atrybut to zmienna towarzysząca wierzchołkowi, na przykład współrzędne koloru lub tekstury. Różne zmienne mogą być zmieniane przez Vertex Shader, ale nie przez Fragment Shader, więc zasadniczo przekazują informacje w dół potoku.
uniform
są parametrami na prymityw (stałe podczas całego wywołania remisu);attribute
są parametrami na wierzchołek (zazwyczaj: pozycje, normalne, kolory, UV, ...);varying
są parametrami na fragment (lub piksel ): różnią się one w zależności od pikseli.Ważne jest, aby zrozumieć, jak varying
działa programowanie własnych shaderów.
Powiedzmy, że definiujesz zmienny parametr v
dla każdego wierzchołka trójkąta wewnątrz Vertex Shader . Kiedy ten zmienny parametr jest wysyłany do Fragment Shader , jego wartość jest automatycznie interpolowana na podstawie położenia piksela do narysowania.
Na poniższym obrazku czerwony piksel otrzymał interpolowaną wartość zmieniającego się parametru v
. Dlatego nazywamy je „zmiennymi”.
Dla uproszczenia w powyższym przykładzie zastosowano interpolację bilinearną , która zakłada, że wszystkie narysowane piksele znajdują się w tej samej odległości od aparatu. Aby uzyskać dokładne renderowanie 3D, urządzenia graficzne wykorzystują interpolację z poprawną perspektywą, która uwzględnia głębokość piksela.
noperspective
aby uzyskać prostą interpolację dwuliniową, a nie interpolację z poprawną perspektywą (identyfikowaną przez domyślny kwalifikator:) smooth
. Zobacz ten przykład .
Jakie są różnice między atrybutem, uniformem i zmienną zmienną w WebGL?
W OpenGL „program” to zbiór „shaderów” (mniejszych programów), które są połączone ze sobą w potoku.
// "program" contains a shader pipeline:
// vertex shader -> other shaders -> fragment shader
//
const program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
Shadery przetwarzają wierzchołki (Vertex Shader), geometrie (Geometry Shader), Teselację (Tessellation Shader), fragmenty (Pixel Shader) i inne zadania przetwarzania wsadowego (Compute Shader) potrzebne do rasteryzacji modelu 3D.
Moduły cieniujące OpenGL (WebGL) są napisane w GLSL (tekstowym języku shaderów skompilowanym na GPU).
// 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>
Moduły cieniujące mogą przekazywać dane do następnego modułu cieniującego w potoku ( out
, inout
), a także mogą akceptować dane z aplikacji WebGL lub poprzedniego modułu cieniującego ( in
).
Moduły cieniujące Vertex i Fragment (tak naprawdę każdy moduł cieniujący) mogą używać uniform
zmiennej do odbierania danych z aplikacji WebGL.
// 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);
Vertex Shader może również odbierać dane z aplikacji WebGL ze attribute
zmienną, którą można włączyć lub wyłączyć w razie potrzeby.
// 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);
Vertex Shader może przekazywać dane do Fragment Shader za pomocą varying
zmiennej. Zobacz kod GLSL powyżej ( varying vec3 variableC;
).
Mundury to kolejny sposób przekazywania danych z naszej aplikacji na CPU do shaderów na GPU, ale uniformy są nieco inne w porównaniu do atrybutów wierzchołków. Przede wszystkim mundury są globalne. Globalna, co oznacza, że zmienna uniform jest unikalna dla każdego obiektu programu modułu cieniującego i można uzyskać do niej dostęp z dowolnego modułu cieniującego na dowolnym etapie programu modułu cieniującego. Po drugie, niezależnie od ustawienia wartości uniform, uniformy zachowają swoje wartości, dopóki nie zostaną zresetowane lub zaktualizowane
Podoba mi się opis z https://learnopengl.com/Getting-started/Shaders , ponieważ słowo per-prymitywne nie jest intuicyjne