GLSL: replace large uniform int array with buffer or texture

Now I'm trying to pass an ints array to the fragment shader, and am doing this through a uniform array:

uniform int myArray[300]; 

And filling it outside the shader glUniform1iv .

Unfortunately, unified arrays in excess of ~400 fail. I understand that I can use a “uniform buffer” instead, but I cannot find a complete example of passing a large 1D array to a fragment shader with buffers or otherwise.

Can someone provide such an example?

+6
source share
1 answer

This should get you started using the Uniform Buffer Object to store the array. Note that GL requires that UBOs have a minimum capacity of 16 KiB, a maximum capacity can be requested through GL_MAX_UNIFORM_BLOCK_SIZE .

An example of a fragmented shader (UBOs require OpenGL 3.1):

 #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 Code

 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 probably forgot something, there is a reason why I do not write textbooks. If you have any problems with this, leave a comment.

UPDATE:

Note that 0 used in glUniformBlockBinding (...) and glBindBufferBase (...) is the global identifier of the anchor point. When used in conjunction with the std140 layout std140 this means that you can use this UBO in any GLSL program where you bind one of your uniform blocks to this anchor point ( 0 ). This is great when you want to share something like your ModelView and Projection matrices between dozens of different GLSL programs.

+8
source

All Articles