Могу ли я использовать массив из 6 int из Vertex Shader в Geometry Shader? - PullRequest
1 голос
/ 06 апреля 2020

Я пытаюсь сгенерировать примитивы OpenGL из 6-ти целочисленной вершины. IE целочисленное значение 6 сгенерирует 4 пользовательских line_strip.

Сначала я пытаюсь переместить массив из 6 целых чисел из Vertex в Shader, и для этого я делаю простой тест следующим образом.

Это код для вершинного шейдера:

#version 330

layout (location = 0) in int inVertex[6];
out int outVertex[6];

void main()
{
    outVertex = inVertex;
}

и для геометрического шейдера, который жестко кодирует сегмент:

#version 330

in int vertex[6];
layout (line_strip, max_vertices = 2) out;

void main()
{

    gl_Position = vec4(-0.2, -0.2, 0.0, 1.0); 
    EmitVertex();    
    gl_Position = vec4(-0.2 +0.4, -0.2, 0.0, 1.0); 
    EmitVertex();    
    EndPrimitive();

}

Но я получаю пустой экран.

enter image description here

Если я изменю шейдер Vertex на это:

#version 330

layout (location = 0) in int inVertex[6];
out int outVertex[6];

void main()
{   
    //outVertex = inVertex;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
}

и шейдер геометрии на это:

#version 330

//in int candle[6];
layout (points) in;
layout (line_strip, max_vertices = 2) out;

void main()
{

    gl_Position = vec4(-0.2, -0.2, 0.0, 1.0); 
    EmitVertex();    
    gl_Position = vec4(-0.2 +0.4, -0.2, 0.0, 1.0); 
    EmitVertex();    
    EndPrimitive();

}

Затем я получаю сегмент на экране:

enter image description here

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

Ответы [ 2 ]

3 голосов
/ 06 апреля 2020

Вершинные шейдеры работают на вершинах (как ни странно). Они имеют соответствие 1: 1 с данными вершин: для каждой вершины в операции рендеринга вы получаете одну выходную вершину.

Геометрические шейдеры работают с примитивами . Они имеют отношение 1: много со своими входными примитивами. GS получает один примитив и выдает 0 или более примитивов с различными ограничениями.

Примитив состоит из одной или более вершин. Таким образом, GS должен иметь возможность получать несколько частей входных данных, сгенерированных VS, которые выполнялись для генерации примитива, который обрабатывает GS. Таким образом, все входы GS имеют массив . То есть для любого типа T, который выводит VS, GS принимает T[] (или эквивалентный). Это верно, даже если тип входного примитива вашего GS равен points.

Так что, если VS имеет это как выход out int outVertex[6];, то соответствующий GS должен быть in int outVertex[][6];. Обратите внимание, что индексы массивов массивов читаются слева направо, поэтому это массив элементов с примитивным числом, где каждый элемент представляет собой массив из 6 int с. Также обратите внимание, что имена должны соответствовать . Вы должны были получить ошибку компоновщика для несоответствия имени.

В качестве альтернативы, вы можете использовать интерфейсный блок, чтобы сделать массив немного проще:

//VS:
out Prim
{
    int data[6];
};

//GS:
in Prim
{
    int data[6];
} vsData[];

//Access with vsData[primIx].data[X];
1 голос
/ 06 апреля 2020

Вершинный шейдер выполняется для каждой вершины, поэтому входы и выходы не являются массивами, они являются одним атрибутом:

#version 330

layout (location = 0) in vec3 inVertex;
out vec3 vertex;

void main()
{
    vertex = inVertex;
}

Вход для Геометрический шейдер является примитивный. Все выходные данные вершинного шейдера, которые образуют примитив, составлены. Таким образом, входными данными геометрического шейдера являются массивы.
Размер входного массива зависит от типа входного примитива для геометрического шейдера. например, для строки размер входного массива равен 2:

#version 330

layout (lines) in;
layout (line_strip, max_vertices = 4) out;

in vec3 vertex[];

void main()
{
    // [...]
}
...