如何将一组均匀缓冲区对象加载到着色器中?

时间:2017-06-19 16:06:23

标签: c++ glsl vulkan

着色器代码:

// UBO for MVP matrices   
layout (binding = 0) uniform UniformBufferObject {
        mat4 model;
        mat4 view;
        mat4 proj;
} ubo;

这很好用,因为它只有一个结构,我可以将VkWriteDescriptorSet.descriptorCount设置为1.但是如何创建这些结构的数组呢?

// Want to do something like this
// for lighting calculations
layout (binding = 2) uniform Light {
    vec3 position;
    vec3 color;
} lights[4];

我拥有存储在一个缓冲区中的所有四个灯的数据。当我将VkWriteDescriptorSet.descriptorCount设置为4时, 我是否必须创建四个VkDescriptorBufferInfo?如果是这样,我不知道要放入偏移和范围。

1 个答案:

答案 0 :(得分:2)

统一缓冲区数组中的所有块都位于同一个描述符中。但是,它们仍然是不同的块;他们得到一个不同的VkDescriptorBufferInfo信息对象。因此,这些区块不必来自连续的存储区域。

注意:KHR_vulkan_glsl扩展程序gets this wrong,如果你看起来密切关注。它指出,不透明类型的数组应该进入单个描述符,但接口块的数组不应该。实际的glslangValidator编译器(以及SPIR-V和Vulkan)会像我描述的那样处理它。

但是,除了动态统一表达式之外,您无法访问接口块数组的元素。甚至 要求具有某种功能;如果没有该功能,则只能使用常量表达式访问数组。

您可能需要的是块中的数组,而不是 块的数组

struct Light
{
  vec4 position; //(NEVER use `vec3` in blocks)
  vec4 color;
};

layout (set = 0, binding = 2, std140) uniform Lights {
  Light lights[4];
};

这意味着在绑定槽2中有一个描述符(descriptorCount为1)。缓冲区的数据应该是4个连续的结构。