问题描述
现在我正在尝试将一个整数数组传递到片段着色器中,并通过一个统一数组执行此操作:
Right now I am trying to pass an array of ints into the fragment shader, and am doing this through a uniform array:
uniform int myArray[300];
并在着色器外用 glUniform1iv
填充它.
And filling it outside the shader with glUniform1iv
.
不幸的是,大于 ~400
的统一数组失败了.我知道我可以使用统一缓冲区"代替,但似乎无法找到将大型一维数组传递到带有缓冲区或其他方式的片段着色器的完整示例.
Unfortunately, uniform arrays larger than ~400
fail. I understand that I can use a "uniform buffer" instead, but can't seem to a find a full example of passing a large 1D array into a fragment shader with buffers or otherwise.
谁能提供这样的例子?
推荐答案
这应该会让您开始使用统一缓冲区对象来存储数组.注意GL要求UBO的最小容量为16 KiB,最大容量可以通过GL_MAX_UNIFORM_BLOCK_SIZE
查询.
This should get you started using a Uniform Buffer Object to store an array. Note that GL requires UBOs to have a minimum capacity of 16 KiB, the maximum capacity can be queried through 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));
}
OpenGL 代码
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);
我可能忘记了一些东西,我不写教程是有原因的.如果您在执行此操作时遇到任何问题,请发表评论.
I am probably forgetting something, there is a reason I do not write tutorials. If you have any trouble implementing this, leave a comment.
注意glUniformBlockBinding(...)
和glBindBufferBase(...)
中使用的0是绑定的全局标识符观点.当与 std140
布局结合使用时,这意味着您可以在任何 GLSL 程序中使用此 UBO,在该程序中您将其统一块之一绑定到该绑定位置 (0).当您想在几十个不同的 GLSL 程序之间共享诸如 ModelView 和 Projection 矩阵之类的东西时,这实际上非常方便.
Note that the 0 used in glUniformBlockBinding (...)
and glBindBufferBase (...)
is a global identifier for the binding point. When used in conjunction with the std140
layout, this means that you can use this UBO in any GLSL program where you bind one of its uniform blocks to that binding location (0). This is actually extremely handy when you want to share something like your ModelView and Projection matrices between dozens of different GLSL programs.
这篇关于GLSL:用缓冲区或纹理替换大型统一整数数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!