创建统一的GLSL数组?


75

我想离开OpenGL的灯,自己做。我希望我的着色器允许可变数量的灯光。

我们可以在GLSL着色器中声明统一数组吗?如果是这样,我们将如何设置这些制服的值?


4
任何想要可变数量的灯光的人,只要制造出具有不错容量的阵列,并计算当前有多少个活跃的灯光即可。GLSL不允许使用大小可变的数组(所有数组大小必须为恒定的硬编码值)。
2014年

Answers:


99

是的,这是可能的。您可以声明与C中类似的统一数组,例如

然后您可以使用 glUniform{1,2,3,4}{f,i}v


2
1、2、3、4是什么意思?这是否意味着我最多只能将一个数组的值设置为四个成员?
英里

这是对的非常巧妙/扭曲的用法glUniform1fv。有人会认为的第二个参数glUniform1fv仅仅是一种形式,应该始终将其用作
1。– bobobobo

因此,从技术上讲,您可以vec4使用glUniform1fv( uniformId, 4, v ) ;where设置v4个float数组来设置统一。
bobobobo

14
@bobobobo:“因此从技术上讲,您可以使用glUniform1fv(uniqueId,4,v)设置统一的vec4;其中v是4个浮点数的数组。 ”不,您不能。规格非常明确:尺寸和类型必须与制服的尺寸和类型匹配(使用的布尔值和使用的i不透明色除外1i)。如果您说1f,则制服必须为1个浮点数。否则,GL_INVALID_OPERATION随之而来。
Nicol Bolas 2013年

9
{1234}函数中的@ MilesRufat-LatreglUniform讲述了统一变量的类型。1f表示单个浮点数,2i表示ivec2,依此类推。这不应与count函数采用的第二个参数(即数组大小)相混淆。因此,要上传到uniform vec2 vecs[5];,这将会是glUniform2fv(loc, 5, data);
legends2k 2014年

7

是的,可以在GLSL着色器中声明一个统一数组。只是谷歌“ GLSL统一数组”的一些例子(编辑:或参见datenwolf的例子)。但是,可以发送多少张制服到不同的图形卡上有一些限制(至少在较旧的显卡上,我不确定当前的显卡(尽管我想还会有))。

如果您确实决定沿制服路线走,我建议您使用制服缓冲区。根据http://www.opengl.org/wiki/Uniform_Buffer_Object的说法,“在统一缓冲区绑定之间切换通常比在程序中切换数十个统一制服要快”。

如果您有大量的灯光和参数,则还可以将数据作为浮点缓冲区发送。


6
统一缓冲区对象仅从GL 3.1版开始可用。从2.0版开始,需要ARB_Uniform_Buffer_Object扩展。
Paul Wendler

97
谷歌搜索“ glsl统一数组”现在返回此页面作为第一个结果!我们现在干什么?
mlvljr

1
您可以在运行时查询OpenGL,以获取最大的制服数量Glint result; glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, 0, &result);
rwols

15
@mlvljr我们进入一个递归循环,直到堆栈溢出为止。(明白吗?)
米歇尔·约翰逊

@MichealJohnson Yeah :)
mlvljr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.