OpenGL统一块语法

4

我在思考有关UBO和用统一块在GLSL中访问它们的问题。

根据官方文档,如果我想设计一个灯光数组,我可能会写:

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

现在我看到很多例子,统一块的写法是这样的:
struct LightStruct
{
    vec4 position;
    vec4 direction;
    vec4 color;
    ...
};

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

这两种方式有什么不同?

我猜可能有助于减少着色器中使用的统一变量的数量,但我不确定。

1个回答

6

首先

layout(std140, binding = 0) uniform LightBlock
{
    vec4 position;
    vec4 direction;
    vec4 color;
    ...
} lights[8];
声明一个UBO缓冲块数组本身。这意味着,您可以为数组中的每个索引绑定不同的缓冲对象,或者不同的缓冲范围。请注意,在此示例中,您将使用UBO绑定索引从0到7,GLSL规范 明确指出:
如果绑定标识符用于作为数组的实例化的统一块或着色器存储块,则数组的第一个元素使用指定的块绑定,并且每个后续元素都使用下一个连续的统一块绑定点。
这有一些影响:
- 您只能使用非常有限的数组大小,因为UBO绑定点的数量是有限制的 - 您必须仅使用动态统一表达式对这些数组进行索引 - 您可以将相同的UBO和缓冲区范围绑定到数组的一些或所有单独索引中(在块内部使用数组时无法做到这一点)
总之,您很少真正想要使用统一块数组。特别是对于您的光照示例,您会使用后者。
layout(std140, binding = 0) uniform LightBlock
{
    LightStruct lights[8]; 
};

这段代码定义了一个包含数组的统一块。这意味着你需要为数组提供一个连续的UBO缓冲区范围,因此只消耗一个宝贵的UBO绑定点,而且可以使数组大小达到实现的最大UBO大小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接