OpenGL统一块语法

问题描述 投票:1回答:1

我问自己一个关于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];
};

这两种方式有什么区别?

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

opengl glsl shader
1个回答
0
投票

第一个

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

声明UBO缓冲区块本身的数组。这意味着,您可以为数组中的每个索引绑定不同的缓冲区对象,或者为不同的缓冲区范围绑定。请注意,在此示例中,您将使用从0到7的UBO绑定索引,GLSL spec明确声明:

如果绑定标识符与统一存储或着色器存储一起使用,实例化为数组的块,数组的第一个元素采用指定的块绑定,并且每个后续元素采用下一个连续的统一块绑定点。

这有两个含义:-您只能使用非常有限的数组大小,因为UBO绑定点的数量是有限的-您必须仅使用动态统一表达式为这些数组建立索引-您可以将相同的UBO和缓冲区范围绑定到数组的某些或全部个体索引(某些操作无法在块内使用数组)

总之,您实际上很少真正想要使用统一块的数组。特别是对于您的简单示例,您将使用后者:

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

仅声明一个统一块,其中包含aeeay。这意味着您必须为该数组提供一个连续的UBO缓冲区范围,因此您只消耗了宝贵的UBO绑定点之一,并且您可以使数组与实现的最大UBO大小一样大。

© www.soinside.com 2019 - 2024. All rights reserved.