现在我正在尝试将一个int数组传递给片段着色器,并通过一个统一的数组执行此操作:
uniform int myArray[300];
使用glUniform1iv
将其填充到着色器外部。
不幸的是,大于~400
的统一数组失败了。我理解我可以使用“统一缓冲区”,但似乎无法找到将大型1D数组传递到带缓冲区的片段着色器的完整示例。
有人可以提供这样的例子吗?
答案 0 :(得分:9)
这应该让您开始使用Uniform Buffer Object来存储数组。请注意,GL要求UBO的最小容量为16 KiB,可以通过GL_MAX_UNIFORM_BLOCK_SIZE
查询最大容量。
#version 140 // GL 3.1
// Arrays in a UBO must use a constant expression for their size.
const int MY_ARRAY_SIZE = 512;
// The name of the block is used for finding the index location only
layout (std140) uniform myArrayBlock {
int myArray [MY_ARRAY_SIZE]; // This is the important name (in the shader).
};
void main (void) {
gl_FragColor = vec4 ((float)myArray [0] * 0.1, vec3 (1.0));
}
const int MY_ARRAY_SIZE = 512;
GLuint myArrayUBO;
glGenBuffers (1, &myArrayUBO);
// Allocate storage for the UBO
glBindBuffer (GL_UNIFORM_BUFFER, myArrayUBO);
glBufferData (GL_UNIFORM_BUFFER, sizeof (GLint) * MY_ARRAY_SIZE,
NULL, GL_DYNAMIC_DRAW);
[...]
// When you want to update the data in your UBO, you do it like you would any
// other buffer object.
glBufferSubData (GL_UNIFORM_BUFFER, ...);
[...]
GLuint myArrayBlockIdx = glGetUniformBlockIndex (GLSLProgramID, "myArrayBlock");
glUniformBlockBinding (GLSLProgramID, myArrayBlockIdx, 0);
glBindBufferBase (GL_UNIFORM_BUFFER, 0, myArrayUBO);
我可能忘了什么,有理由我不写教程。如果您在执行此操作时遇到任何问题,请发表评论。
请注意,glUniformBlockBinding (...)
和glBindBufferBase (...)
中使用的 0 是绑定点的全局标识符。当与std140
布局结合使用时,这意味着您可以在任何GLSL程序中使用此UBO,在该程序中将其统一块之一绑定到该绑定位置( 0 )。当你想在几十个不同的GLSL程序之间共享类似你的ModelView和Projection矩阵时,这实际上非常方便。