У чому різниця між атрибутом, уніформою та змінною змінною в WebGL?


83

Чи існує якась аналогія, про яку я можу згадати, порівнюючи ці різні типи, або як ці речі працюють?

Крім того, що означає уніфікація матриці?

Відповіді:


90

Скопійовано безпосередньо з http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ . Фактичний сайт має набагато більш детальну інформацію, і його варто було б перевірити.

Змінні кваліфікатори

Кваліфікатори надають змінному особливе значення. Доступні такі кваліфікації:

  • const - Оголошення є константою часу компіляції.
  • атрибут - Глобальні змінні, які можуть змінюватися для кожної вершини, які передаються із програми OpenGL вершинним шейдерам. Цей кваліфікатор можна використовувати лише у вершинних шейдерах. Для шейдера це змінна лише для читання. Див. Розділ Атрибут.
  • уніформа - Глобальні змінні, які можуть змінюватися для примітиву [...], які передаються із програми OpenGL шейдерам. Цей класифікатор може бути використаний як у вершинних, так і у шейдерах фрагментів. Для шейдерів це змінна лише для читання. Див. Розділ "Уніформа".
  • варіюючий - використовується для інтерпольованих даних між вершинним шейдером та фрагментним шейдером. Доступно для запису у вершинному шейдері та лише для читання у шейдері фрагментів. Див. Розділ «Змінюється».

Що стосується аналогії, const та uniform є як глобальні змінні в C / C ++, одна з них постійна, а інша може бути встановлена. Атрибут - це змінна, яка супроводжує вершину, наприклад, колір або координати текстури. Змінні змінні можуть бути змінені вершинним шейдером, але не шейдером фрагментів, тому по суті вони передають інформацію по конвеєру.


1
Просто щоб трохи розширити атрибути: атрибут не повинен бути атрибутом масиву (атрибут масиву необхідний, якщо значення може бути різним для кожної вершини). Це також може бути постійним атрибутом вершини, і в цьому випадку значення поділяється між усіма вершинами. Насправді атрибут масиву повинен бути активно включений gl.enableVertexAttribArray.
Роберт Монфера,

Добре мати текст тут, тому що веб-сайт мертвий
ziyuang

Просто щоб бути "тим хлопцем", але на сайті я не бачу нічого, що б свідчило про те, що правомірне копіювання цього тут
gman

66
  • uniformє первісними параметрами (постійними протягом усього виклику розіграшу);
  • attributeє параметрами для кожної вершини (зазвичай: положення, нормалі, кольори, ультрафіолетові промені, ...);
  • varying- параметри на фрагмент (або на піксель ): вони варіюються від пікселя до пікселя.

Важливо зрозуміти, як varyingпрацює програмування власних шейдерів.
Скажімо, ви визначаєте змінний параметр vдля кожної вершини трикутника всередині вершинного шейдера . Коли цей мінливий параметр надсилається на шейдер фрагмента , його значення автоматично інтерполюється на основі положення пікселя для малювання.

На наступному зображенні червоний піксель отримав інтерпольоване значення варіюючого параметра v. Тому ми називаємо їх "різними".

змінний параметр, який дволінійно інтерполюється

Для простоти наведений вище приклад використовує білінійну інтерполяцію , яка передбачає, що всі намальовані пікселі мають однакову відстань від камери. Для точного візуалізації в 3D графічні пристрої використовують інтерполяцію з коректною перспективою, яка враховує глибину пікселя.


2
Дух відповіді правильний, але пам’ятайте, що для варіації інтерполяція за замовчуванням називається інтерполяцією з точки зору перспективи, а не просто білінійною інтерполяцією. Звичайно, це можна змінити за допомогою кваліфікатора інтерполяції, noperspective щоб отримати просту білінійну інтерполяцію, а не коректну в перспективі інтерполяцію (ідентифікується за замовчуванням:) smooth. Див. Цей приклад .
legends2k

Дякую, я додаю примітку про це.
ні

11

У чому різниця між атрибутом, уніформою та змінною змінною в 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;).


1

Уніформа - це ще один спосіб передачі даних із нашої програми на центральному процесорі до шейдерів на графічному процесорі, але форма дещо відрізняється від атрибутів вершин. Перш за все, форма універсальна. Глобальний, що означає, що уніфікована змінна є унікальною для кожного об'єкта програми шейдерів, і до неї можна отримати доступ з будь-якого шейдера на будь-якому етапі програми шейдерів. По-друге, що б ви не встановили рівномірне значення, обмундирування зберігатиме свої значення, доки вони не будуть скинуті або оновлені

Мені подобається опис з https://learnopengl.com/Getting-started/Shaders , оскільки слово per-primitive не є інтуїтивним

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.