Подтвердить что ты не робот

В WebGL каковы различия между атрибутом, униформой и переменной?

Есть ли аналогия, которую я могу придумать при сравнении этих разных типов или как это работает?

Кроме того, что означает унифицирование матрицы?

4b9b3361

Ответ 1

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

Переменные квалификаторы

Квалификаторы дают особое значение переменной. Следующие доступны квалификаторы:

  • const - объявление имеет постоянную времени компиляции.
  • attribute - глобальные переменные, которые могут меняться на вершину, которые передаются из приложения OpenGL в вершинные шейдеры. Этот определитель может использоваться только в вершинных шейдерах. Для шейдера это переменная только для чтения. См. Раздел "Атрибут".
  • uniform - глобальные переменные, которые могут изменяться на примитив [...], которые передаются из OpenGL приложение к шейдерам. Этот определитель может использоваться в обеих вершинах и фрагментарные шейдеры. Для шейдеров это переменная только для чтения. См. Раздел "Униформа".
  • variable - используется для интерполированных данных между вершинным шейдером и шейдером фрагментов. Доступно для записи в вершинном шейдере и только для чтения в шейдере фрагментов. См. Раздел Varying.

Что касается аналогии, const и равномерность подобны глобальным переменным в C/С++, одна константа, а другая может быть задана. Атрибут - это переменная, которая сопровождает вершину, например, цветные или текстурные координаты. Переменные переменных могут быть изменены вершинным шейдером, но не фрагментарным шейдером, поэтому по сути они передают информацию по конвейеру.

Ответ 2

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

Важно понять, как varying работает для программирования ваших собственных шейдеров.
Допустим, вы определяете переменный параметр v для каждой вершины треangularьника внутри вершинного шейдера. Когда этот изменяемый параметр отправляется фрагментному шейдеру, его значение автоматически интерполируется в зависимости от положения пикселя для рисования.

На следующем изображении красный пиксель получил интерполированное значение переменного параметра v. Вот почему мы называем их "разными".

varying parameter being bilinearly interpolated

Для простоты в приведенном выше примере используется билинейная интерполяция, которая предполагает, что все нарисованные пиксели имеют одинаковое расстояние от камеры. Для точного 3D-рендеринга графические устройства используют корректную в перспективе интерполяцию, которая учитывает глубину пикселя.

Ответ 3

В OpenGL "программа" представляет собой набор "шейдеров" (меньших программ), которые связаны друг с другом в конвейере.

// "program" contains a shader pipeline:
//   vertex shader -> other shaders -> fragment shader
//
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);

Вершины процесса шейдеров (вершинный шейдер), геометрия (геометрический шейдер), тесселяция (тесселяционный шейдер), фрагменты (пиксельный шейдер) и другие задачи пакетного процесса (вычислительный шейдер), необходимые для растеризации трехмерной модели.

Шиндеры OpenGL (WebGL) записываются в GLSL (текстовый шейдерный язык, скомпилированный на 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>

Помня об этих понятиях:

Шейдеры могут передавать данные в следующий шейдер в конвейере (out, inout), а также могут принимать данные из приложения WebGL или предыдущего шейдера (in).

  • Шейдеры Vertex и Fragment (любой шейдер действительно) могут использовать переменную uniform для приема данных из приложения WebGL.

    // Pass data from WebGL application to shader
    var uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
    gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
    
  • Vertex Shader также может получать данные из приложения WebGL с помощью переменной attribute, которая может быть включена или отключена по мере необходимости.

    // Pass data from WebGL application to Vertex Shader
    var attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
    gl.glEnableVertexAttribArray(attributeHandle);
    gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
    
  • Vertex Shader может передавать данные в шейдер фрагмента с использованием переменной varying. См. Выше код GLSL (varying vec3 variableC;).

Ответ 4

  Униформы - это еще один способ передачи данных из нашего приложения на ЦП в шейдеры на GPU, но униформы немного отличаются по сравнению с атрибутами вершин. Прежде всего, униформа носит глобальный характер. Глобальный, означающий, что единообразная переменная является уникальной для каждого объекта программы шейдера и может быть доступна из любого шейдера на любом этапе программы шейдера. Во-вторых, независимо от того, что вы установили для унифицированного значения, униформы будут сохранять свои значения, пока они не будут сброшены или обновлены

Мне нравится описание из https://learnopengl.com/Getting-started/Shaders, потому что слово per-примитив не является интуитивным