【问题标题】:OpenGL uniform blocks syntaxOpenGL 统一块语法
【发布时间】:2021-06-27 02:22:43
【问题描述】:

我在问自己一个关于 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】:

    第一个

    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]; 
    };
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多