简体   繁体   中英

OpenGL uniform blocks syntax

I was asking myself a question about UBO and the way of accessing them in GLSL with uniform blocks.

Following the official documentation, if I want to design an array of lights, I will probably write :

layout(std140, binding = 0) uniform LightBlock
{
    vec4 position;
    vec4 direction;
    vec4 color;
    ...
} lights[8];

Now I see a lot of examples, where the uniform block is written that way :

struct LightStruct
{
    vec4 position;
    vec4 direction;
    vec4 color;
    ...
};

layout(std140, binding = 0) uniform LightBlock
{
    LightStruct lights[8];
};

What is the difference between the two ways ?

I guess it could help to reduce the number of uniform variables in use within a shader, but I'm not sure.

The first

layout(std140, binding = 0) uniform LightBlock { vec4 position; vec4 direction; vec4 color; ... } lights[8];

declares an array of UBO buffer blocks itself. That means, that you can bind a different buffer object for each index in your array, or a different buffer range. Note that in this example, you will consume the UBO binding indices from 0 to 7, the GLSL spec explicitly states:

If the binding identifier is used with a uniform or shader storage block instanced as an array, the first element of the array takes the specified block binding and each subsequent element takes the next consecutive uniform block binding point.

This has a couple of implications:

  • you can only use a very limited array size, because the number of UBO binding point is limited
  • you must index those arrays only with a dynamically uniform expression
  • you can bind the same UBO and buffer range to some or all of the indivudal indices of your array (something you could not do with an array inside the block)

In summary, you seldom really want to use an array of uniform blocks. Especially for your light example, you would use the latter:

 layout(std140, binding = 0) uniform LightBlock { LightStruct lights[8]; };

just declares one uniform block with an array in it. It means you have to provide one consecutive UBO buffer range for the array, so you consume only one of the precious UBO binding points, and you can have the array as big as the maximum UBO size of your implementation is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM