传递给几何着色器的顶点属性数据未正确设置

时间:2014-02-03 06:32:12

标签: opengl graphics glsl vertex-shader geometry-shader

以下是代码:

顶点着色器:

#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位的顶点属性的数组时,passFIndex没有正确设置。问题是,它总是设置为0.但是,我知道底层顶点FIndex的数据不是0,因为我可以使用不同的着色器程序(没有GS的程序)和FIndex适当变化。

我可以将“passFIndex = int [](FIndex)”替换为“passFIndex = int [](2)”或其中的一些其他常量,并且可以创建一个非零的数组,并且它可以索引正如预期的几何着色器一样。这似乎告诉我顶点着色器中出现了问题,但我无法想象它是什么。

1 个答案:

答案 0 :(得分:4)

您尝试在顶点着色器中输出数组令人困惑。这应该在您的GLSL程序中生成链接错误,因为顶点着色器和几何着色器之间的接口不匹配。

几何着色器输入始终采用数组的形式,因为它们采用多个变换顶点来构造基元。但是,顶点着色器中的输出通常不是数组。如果要在顶点着色器中输出数组,则会创建一种情况,其中几何着色器需要一个2D数组来匹配接口 - 这是不受支持的。

GLSL 3.30 Specification - 4变量和类型 - 第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);
...