Данные атрибута вершины, передаваемые в геометрический шейдер, установлены неправильно

Вот код:

Вершинный шейдер:

#version 330

layout(std140) uniform;


layout(location = 6) in vec4 worldPosition;
layout(location = 7) in int FIndex;


flat out int[] passFIndex;


uniform Projection
{
    mat4 view;
    mat4 projection;
};

uniform mat3[6] FMatrix;
void main()
{
    gl_Position = worldPosition;
    passFIndex = int[](FIndex);
}

геометрический шейдер:

#version 330

layout(std140) uniform;

layout(points) in;
layout(triangle_strip, max_vertices = 136) out;

flat in int[] passFIndex;

uniform Projection
{
    mat4 view;
    mat4 projection;
};

uniform mat3[6] FMatrix;

void main()
{

    vec3 newPos = FMatrix[passFIndex[0]] * vec3(-0.5f, -0.5f, 0.5f);
...

Итак, проблема в том, что passFIndex не устанавливается должным образом, когда я устанавливаю его равным массиву, состоящему только из атрибута вершины в местоположении 7. Проблема в том, что он всегда установлен в 0. Однако я ЗНАЮ базовые данные вершины для FIndex не равно 0, потому что я могу использовать другую шейдерную программу (без GS), и FIndex меняется соответствующим образом.

Я могу заменить «passFIndex = int [] (FIndex)» на «passFIndex = int [] (2)» или какую-то другую константу там, и это работает для создания массива с ненулевым значением, и он индексируется, как и ожидалось, в шейдер геометрии. Кажется, это говорит мне, что что-то не так в вершинном шейдере, но я не могу представить, что это такое.


person Thomas    schedule 03.02.2014    source источник


Ответы (1)


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

Входные данные шейдера геометрии всегда имеют форму массива, потому что они используют несколько преобразованных вершин для построения примитивов. Однако вывод в вершинном шейдере, как правило, не является массивом. Если бы вы хотели вывести массив в вершинном шейдере, вы бы создали ситуацию, когда шейдеру геометрии нужен 2D-массив для соответствия интерфейсу — это не поддерживается.

Спецификация GLSL 3.304 переменных и типа – стр. 30

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

Если выходные данные вершинного шейдера сами по себе являются массивом, используемым геометрическим шейдером, то он должен появиться в выходном блоке (см. блоки интерфейса ниже) в вершинном шейдере и во входном блоке в геометрическом шейдере с экземпляром блока. имя объявлено как массив. Это требуется для выходных массивов из вершинного шейдера, поскольку двумерные массивы не поддерживаются.


Я бы подумал о переписывании ваших шейдеров:

Вершинный шейдер:

#version 330

layout(std140) uniform;


layout(location = 6) in vec4 worldPosition;
layout(location = 7) in int FIndex;


flat out int passFIndex;


uniform Projection
{
    mat4 view;
    mat4 projection;
};

uniform mat3 FMatrix [6];

void main()
{
    gl_Position = worldPosition;
    passFIndex  = FIndex;
}

Геометрический шейдер:

#version 330

layout(std140) uniform;

layout(points) in;
layout(triangle_strip, max_vertices = 136) out;

flat in int passFIndex [];

uniform Projection
{
    mat4 view;
    mat4 projection;
};

uniform mat3 FMatrix [6];

void main()
{

    vec3 newPos = FMatrix[passFIndex[0]] * vec3(-0.5f, -0.5f, 0.5f);
...
person Andon M. Coleman    schedule 03.02.2014