10

我将一个统一数组传递给几何着色器,并希望使用变量对其进行索引。我可以使用具有固定数字(数字常量)的可变长度数组和索引,或者我可以使用变量定义固定长度数组和索引。但是我不能使用变量索引到可变长度数组。

下面是几何着色器的伪代码,其中包含有效的案例和无效的案例

这有效:

    uniform vec2 dimensions[2];
    // some code which computes index which is an int
    float dimX = dimensions[index].x;

这有效:

    uniform vec2 dimensions[];
    // some code which computes index which is an int
    float dimX = dimensions[0].x;

这不起作用:

    uniform vec2 dimensions[];
    // some code which computes index which is an int
    float dimX = dimensions[index].x; 

有可能做这样的事情吗?

4

1 回答 1

17

可悲的是,不,这是不可能的。您没有包含您所针对的 GLSL 版本,但确实提到了几何着色器,因此我包含了 GLSL 1.5 规范的相关部分。以下:

GLSL 规范(1.5 版) - 4.1.9 数组 - 第 25 页。

相同类型的变量可以通过声明一个名称后跟括号 ( [ ] ) 包含可选大小来聚合到数组中。在声明中指定数组大小时,它必须是大于零的整数常量表达式(请参见第 4.3.3 节“常量表达式”)。如果数组使用不是整型常量表达式的表达式进行索引,或者如果数组作为参数传递给函数,则必须在任何此类使用之前声明其大小。

虽然桌面 GLSL 在使用非常量表达式索引数组时比 GLSL ES 更宽容,但您仍然需要在一些限制范围内工作。与纹理查找通常用于克服 OpenGL ES 中的非常量数组索引的方式相同,您可以通过在几何着色器中使用 1D 纹理查找来解决此问题。我不得不怀疑你是否真的那么需要这个功能

无论如何,为您的统一数组定义一个上限是个好主意,因为 GLSL 规范。只需要实现在几何着色器阶段提供 1024 个统一组件(例如 1024、256、64或float每个组件的某种组合)。如果您的数组在编译时具有已知的最大大小,您可以避免以后在不知不觉中超出此限制相关的麻烦。vec4mat4

更新:

既然您提到了 GLSL 4.x,我想指出 OpenGL 中的一个新功能,称为Shader Storage Buffer Objects。使用 SSBO,可以在运行时使用具有动态长度的数组来满足您的目的。您可以在着色器中使用查询 SSBO 的长度.length (),并自己处理范围验证。但是,我认为这可能是矫枉过正,但值得一提。

于 2013-11-08T21:43:57.093 回答