我最近重写了一些在OpenGL中使用Shader存储缓冲区对象的代码,将动态大小的数组发送到GLSL中,在绘制许多程序生成的对象时大大提高了性能。
我所拥有的是几千点,并且每一点我都会渲染一个程序生成的圆形广告牌。每一个都可以具有不同的颜色和半径,以及一些其他特征(表示为bool或enums)
我用这些位置填充矢量,用半径和颜色打包在一起。然后我将其作为具有动态大小的着色器存储缓冲区对象上载。我创建了一个包含0个vbos的虚拟VAO,但是使用与我相同数量的点调用draw命令。 在着色器内部,然后使用gl_VertexID遍历此数组,并为每个点生成带纹理坐标的四边形(两个三角形)。
我正在寻找一种在Vulkan中做同样事情的方法。在Vulkan中有一些方法可以将动态大小的数组传递到着色器吗?在Graham Seller的Vulkan书中读到Shader Storage Buffer对象,它只提到它们是读写的,但不能用于动态大小的数组。
编辑:基于Sasha Willems粒子示例,似乎存储缓冲区 实际上能够处理动态大小的数组。有没有办法通过制服做同样的事情?
答案 0 :(得分:2)
我可能误解了你的问题。 SSBO在两个API之间具有相同的行为和功能。这就是为什么他们命名相同的。存储块末尾的无界数组将根据您提供的数据在运行时定义其长度。
缓冲区描述符的大小未硬编码到描述符集布局中;这是你用VkWriteDescriptorSet
设置的东西。现在与偏移量不同,您无法在不更改描述符本身的情况下更改描述符集的大小。也就是说,您没有等同于vkCmdBindDescriptorSets
的{{1}}字段。因此,您必须实际更新原型描述符以更改长度。
但这只需要对您的描述符集进行双缓冲;这应该不是问题。
有没有办法通过制服做同样的事情?
同样,对于Vulkan和OpenGL,答案是相同的:没有。