Чи існує якась аналогія, про яку я можу згадати, порівнюючи ці різні типи, або як ці речі працюють?
Крім того, що означає уніфікація матриці?
Відповіді:
Скопійовано безпосередньо з http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ . Фактичний сайт має набагато більш детальну інформацію, і його варто було б перевірити.
Змінні кваліфікатори
Кваліфікатори надають змінному особливе значення. Доступні такі кваліфікації:
- const - Оголошення є константою часу компіляції.
- атрибут - Глобальні змінні, які можуть змінюватися для кожної вершини, які передаються із програми OpenGL вершинним шейдерам. Цей кваліфікатор можна використовувати лише у вершинних шейдерах. Для шейдера це змінна лише для читання. Див. Розділ Атрибут.
- уніформа - Глобальні змінні, які можуть змінюватися для примітиву [...], які передаються із програми OpenGL шейдерам. Цей класифікатор може бути використаний як у вершинних, так і у шейдерах фрагментів. Для шейдерів це змінна лише для читання. Див. Розділ "Уніформа".
- варіюючий - використовується для інтерпольованих даних між вершинним шейдером та фрагментним шейдером. Доступно для запису у вершинному шейдері та лише для читання у шейдері фрагментів. Див. Розділ «Змінюється».
Що стосується аналогії, const та uniform є як глобальні змінні в C / C ++, одна з них постійна, а інша може бути встановлена. Атрибут - це змінна, яка супроводжує вершину, наприклад, колір або координати текстури. Змінні змінні можуть бути змінені вершинним шейдером, але не шейдером фрагментів, тому по суті вони передають інформацію по конвеєру.
uniform
є первісними параметрами (постійними протягом усього виклику розіграшу);attribute
є параметрами для кожної вершини (зазвичай: положення, нормалі, кольори, ультрафіолетові промені, ...);varying
- параметри на фрагмент (або на піксель ): вони варіюються від пікселя до пікселя.Важливо зрозуміти, як varying
працює програмування власних шейдерів.
Скажімо, ви визначаєте змінний параметр v
для кожної вершини трикутника всередині вершинного шейдера . Коли цей мінливий параметр надсилається на шейдер фрагмента , його значення автоматично інтерполюється на основі положення пікселя для малювання.
На наступному зображенні червоний піксель отримав інтерпольоване значення варіюючого параметра v
. Тому ми називаємо їх "різними".
Для простоти наведений вище приклад використовує білінійну інтерполяцію , яка передбачає, що всі намальовані пікселі мають однакову відстань від камери. Для точного візуалізації в 3D графічні пристрої використовують інтерполяцію з коректною перспективою, яка враховує глибину пікселя.
noperspective
щоб отримати просту білінійну інтерполяцію, а не коректну в перспективі інтерполяцію (ідентифікується за замовчуванням:) smooth
. Див. Цей приклад .
У чому різниця між атрибутом, уніформою та змінною змінною в WebGL?
У OpenGL "програма" - це сукупність "шейдерів" (менших програм), які з'єднані між собою в конвеєр.
// "program" contains a shader pipeline:
// vertex shader -> other shaders -> fragment shader
//
const program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
Шейдери обробляють вершини (вершинний шейдер), геометрії (геометричний шейдер), тесселяцію (тесселяційний шейдер), фрагменти (піксельний шейдер) та інші завдання пакетного процесу (обчислювальний шейдер), необхідні для растеризації 3D-моделі.
Шейдери OpenGL (WebGL) написані на GLSL (текстова мова шейдерів, скомпільована на графічному процесорі).
// 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>
Шейдери можуть передавати дані наступному шейдеру в конвеєрі ( out
, inout
), а також можуть приймати дані із програми WebGL або попереднього шейдера ( in
).
Шейдери Vertex і Fragment (насправді будь-який шейдер) можуть використовувати uniform
змінну для отримання даних із програми 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 також може отримувати дані із програми WebGL із attribute
змінною, яку за необхідності можна вмикати або вимикати.
// 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 може передавати дані в Фрагментний шейдер за допомогою varying
змінної. Див. Код GLSL вище ( varying vec3 variableC;
).
Уніформа - це ще один спосіб передачі даних із нашої програми на центральному процесорі до шейдерів на графічному процесорі, але форма дещо відрізняється від атрибутів вершин. Перш за все, форма універсальна. Глобальний, що означає, що уніфікована змінна є унікальною для кожного об'єкта програми шейдерів, і до неї можна отримати доступ з будь-якого шейдера на будь-якому етапі програми шейдерів. По-друге, що б ви не встановили рівномірне значення, обмундирування зберігатиме свої значення, доки вони не будуть скинуті або оновлені
Мені подобається опис з https://learnopengl.com/Getting-started/Shaders , оскільки слово per-primitive не є інтуїтивним