目录
UniformBuffer
本篇文档是通过 Uniform Buffer 的使用进一步加深对 DescriptorSet 的理解
Vulkan 中,描述符是一种在着色器中访问资源(比如缓冲区,图像,采样器等)的机制或者协议
每个描述符(Descriptor)对应一个资源,代表 GPU 内存中的资源,比如 Uniform Buffer, storage Buffer, Texture,Sampler等
Vulkan 描述符集(VkDescriptorSet)表示着色器可以与之交互的资源的集合,着色器是通过描述符读取和解析资源中的数据,着色器中的绑定点和相应的描述符集中的绑定点必须一一对应

DescriptorSetLayout 和 VkBuffer
现在我们已经可以传递顶点的属性(坐标和颜色等)给到顶点着色器,对于一些所有顶点都共享的属性,比如顶点的变换矩阵,将其作为顶点属性为每一个顶点都传递一份显然是很低效的
Vulkan 提供了资源描述符(resource descriptor)来解决这个问题,资源描述符是用来在着色器中访问缓冲和图像数据的一种方式,我们可以将变换矩阵存储在一个缓冲中,然后通过描述符在着色器中访问它,使用描述符需要进行下面三部分的设置:
- 在管线(
pipeline Creation)创建时指定描述符布局(DescriptorSetLayout) - 从描述符池(
DescriptorSet Pool)中份分配描述符集(DescriptorSet) - 渲染时绑定描述符集(
update DescriptorSet)
描述符布局(DescriptorSetLayout)用于指定可以被管线访问的资源类型,类似于渲染流程指定可以被访问的附着类型
描述符集指定要绑定到描述符上的缓冲和图像资源,类似于帧缓存指定绑定到渲染流程附着上的图像视图
(just like a framebuffer specifies the actual image views to bind to render pass attachments)
Note: 本质上是一种定义资源如何访问的机制或者协议
最后将描述符集绑定到绘制的指令上,类似绑定顶点缓冲和帧缓存到绘制指令上
有多种类型的描述符,在这里, 只使用到了 Uniform 缓冲对象(UBO), 也有其他类型的描述符,它们的使用方式和 Uniform 缓冲对象类似
我们先用结构体定义我们在着色器中使用的 Uniform 的数据:
struct UniformBufferObject {
glm::mat4 model;
glm::mat4 view;
glm::mat4 proj;
}
我们将要使用的 uniform 数据复制到 VkBuffer 中,然后通过一个 uniform 缓冲对象描述符(DescriptorSet)在顶点着色器中访问它:
layout(binding = 0) uniform UniformBufferObejct {
mat4 model;
mat4 view;
mat4 proj;
}
void main() {
gl_Position = ubo.proj * ubo.view *ubo.model*
vec4(inPostion, 0.0, 1.0)
fragColor = inColor;
}
在现在的 demo 中,我们在每一帧更新模型(Model),视图(View),投影矩阵(Projection),可以让矩阵在三维空间内进行旋转
顶点着色器定义
#version 450
#extension GL_ARB_separate_shader_object :enable
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
}
layout(location = 0) in vec2 inPostion;
layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor
out gl_PerVertex {
vec4 gl_Postion;
}
void main() {
gl_Position = ubo.proj + ubo.view + ubo.model * vec4(inPostion, 0,0, 1.0);
fragColor = inColor;
}
uniform,in 和 out 定义在着色器中出现的顺序可以是任意的,任意代码中 binding 修饰符类似于我们对顶点属性使用的 location 修饰符,我们会在描述符布局引用这个 binding 值
gl_Position 使用变换矩阵最终得到矩形在三维空间内的裁剪坐标
描述符布局(DescriptorSetLayout)
我们需要在管线创建的时候提供着色器使用的每一个描述符绑定信息,
首先需要使用 createDescriptorSetLayout 的函数,并在管线创建前调用
void initVulkan() {
createDecriptorSetLayout()

最低0.47元/天 解锁文章
1593

被折叠的 条评论
为什么被折叠?



