创建一个 GLSL 制服数组?
Posted
技术标签:
【中文标题】创建一个 GLSL 制服数组?【英文标题】:Creating a GLSL Arrays of Uniforms? 【发布时间】:2011-11-11 21:06:05 【问题描述】:我想留下 OpenGL 的灯光并自己制作。 我希望我的着色器允许使用可变数量的灯光。
我们可以在 GLSL 着色器中声明一个制服数组吗? 如果是这样,我们将如何设置这些制服的价值?
【问题讨论】:
任何想要可变数量的灯的人,只需制作具有适当容量的阵列,并计算当前有多少灯处于活动状态。 GLSL 不允许可变大小的数组(所有数组大小必须是常量、硬编码值)。 【参考方案1】:是的,这是可能的。您声明统一数组的方式类似于您在 C 中的做法,例如
uniform float v[10];
然后你可以使用glUniform1,2,3,4f,iv
设置它们的值
GLfloat v[10] = ...;
glUniform1fv(glGetUniformLocation(program, "v"), 10, v);
【讨论】:
1、2、3、4指的是什么?这是否意味着我只能将数组的值设置为最多四个成员? 这是glUniform1fv
的一个非常聪明/扭曲的用法。有人会认为glUniform1fv
的第二个参数只是一种形式,它应该始终用作 1。
@bobobobo: "所以从技术上讲,你可以使用 glUniform1fv(uniformId, 4, v) 设置统一的 vec4;其中 v 是 4 个浮点数的数组。" 不,你不能。规范非常明确:尺寸和类型必须与制服的尺寸和类型相匹配(使用i
的布尔值和使用1i
的不透明对象除外)。如果你说1f
,那么制服必须是 1 个浮点数。否则,GL_INVALID_OPERATION
随之而来。
@MilesRufat-Latre 1234
在像glUniform
这样的函数中讲述了统一变量的类型。 1f 表示单个浮点数,2i 表示 ivec2 等等。这不应与函数采用的第二个count
参数相混淆,该参数是数组大小。所以要上传到uniform vec2 vecs[5];
,那就是glUniform2fv(loc, 5, data);
。
@Asad-ullahKhan:不,因为 C 数组到指针衰减。【参考方案2】:
是的,可以在 GLSL 着色器中声明一组制服。只需谷歌“glsl uniform array”获取一些示例(编辑:或查看 datenwolf 的示例)。然而,可以将多少制服发送到不同的显卡是有限制的(至少在旧显卡上,我不确定现在的显卡(尽管我想仍然会有)。
如果你决定走制服路线,我建议使用制服缓冲区。根据http://www.opengl.org/wiki/Uniform_Buffer_Object,“在统一缓冲区绑定之间切换通常比在程序中切换数十个统一更快”。
如果您有大量的灯光和参数,您也可以将数据作为浮点缓冲区发送。
【讨论】:
统一缓冲区对象仅从 GL 3.1 版开始可用。从 2.0 版开始需要 ARB_Uniform_Buffer_Object 扩展。 您可以在运行时查询 OpenGL 以获得最大的制服数量Glint result; glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, 0, &result);
以上是关于创建一个 GLSL 制服数组?的主要内容,如果未能解决你的问题,请参考以下文章