GLSL: Replace large uniform int array with buffer or texture

前端 未结 1 1454
醉梦人生
醉梦人生 2020-12-16 22:28

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];
相关标签:
1条回答
  • 2020-12-16 22:58

    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.

    Sample Fragment 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 am probably forgetting something, there is a reason I do not write tutorials. If you have any trouble implementing this, leave a comment.

    UPDATE:

    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.

    0 讨论(0)
提交回复
热议问题