VulkanTutorial(14·descriptor,uniform buffer)

Uniform buffers

Descriptor layout and buffer

我们将继续学习3D图形,这需要一个模型-视图-投影矩阵,因此我们要更改向vertex shader传输的数据,也就是通过vertex buffer
但是当实时渲染,每一帧这些数据都有可能变化,都需要更新顶点缓冲区,会造成内存浪费

uniform buffer是一块存储在GPU上的内存区域,它可以在多个着色器(甚至多个着色器阶段)之间共享一致的数据
在Vulkan中解决此问题的正确方法是使用资源描述符Descriptor,

描述符是一种数据结构,可以包括uniform buffer、采样器(Sampler)、图像(Image)等

描述符是着色器自由访问buffer的一种方式,描述符的使用包括三个部分:

  • 在pipeline创建期间指定descriptorLayout(指定pipeline将要访问的资源类型,)
  • 从descriptorPool分配descriptorSet(指定将绑定到描述符的实际缓冲区或图像资源)
  • 在rendering期间bind descriptorSet(将uniform buffer数据传给shader)

Vertex shader

修改vertex shader,让gl_Position每个顶点位置都应用这几个变化矩阵

layout(binding = 0) uniform UniformBufferObject {mat4 model;mat4 view;mat4 proj;
} ubo;

DescriptorSetLayout

在程序创建UniformBufferObject结构体

添加createDescriptorSetLayout();函数,包括VkDescriptorSetLayoutBinding,VkDescriptorSetLayoutCreateInfo,vkCreateDescriptorSetLayout一个VkDescriptorSetLayout,vkDestroyDescriptorSetLayout

前两个字段指定着色器中使用的绑定(binding = 0)和描述符的类型VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,我们还需要指定描述符将被引用的着色器阶段VK_SHADER_STAGE_VERTEX_BIT,pImmutableSamplers字段只与图像采样相关的描述符(可选)

另外我们需要在管道创建期间指定DescriptorSetLayout

Uniform buffer

我们需要首先创建Uniform buffer,我们将在每一帧中将新数据复制到统一缓冲区,我们应该设置为vector,因为有多个帧在并发执行

添加新的createUniformBuffers函数,我们在创建后立即使用vkMapMemory映射缓冲区,且不会vkUnmapMemory,在应用程序的整个生命周期中都保持映射到此指针,这会提高性能

Updating uniform data

在drawFrame每帧渲染中,添加新函数updateUniformBuffer更新缓冲区的数据,以便计算transformations

glm/gtc/matrix_transform.hpp头部公开了可用于生成模型转换(如glm::rotate)、视图转换(如glm::lookAt)和投影转换(如glm::perspective)的函数

还有有#define GLM_FORCE_RADIANS以确保像glm::rotate这样的函数使用弧度作为参数,以避免任何可能的混淆

chrono标准库公开了执行精确计时的函数,让我们的数据随着时间变化

GLM最初是为OpenGL设计的,其中剪辑坐标的Y坐标是反转的。最简单的补偿方法是翻转投影矩阵中Y轴的缩放因子上的符号。如果你不这样做,那么图像将被颠倒渲染

依旧通过memcpy可以将临时的uniform buffer对象中的数据复制到当前uniformBuffer中

memcpy

void * memcpy ( void * destination, const void * source, size_t num );

(指向要在其中复制内容的目标数组的指针,指向要复制的数据源的指针,要复制的字节数)

Descriptor pool

我们将为每个VkBuffer资源创建一个descriptorSet,以将其绑定到Uniform buffer描述符

描述符集不能直接创建,必须从描述符池中分配,定义新函数createDescriptorPool

VkDescriptorPoolSize描述描述符集将包含哪些描述符类型以及它们的数量(为每个帧都分配),

VkDescriptorPoolCreateInfo,除了可用的单个描述符的最大数量外,我们还需要指定可以分配的描述符集的最大数量

vkCreateDescriptorPool,vkDestroyDescriptorPool

Descriptor set

我们现在可以分配描述符集本身,添加新的createDescriptorSets函数

描述符集分配通过VkDescriptorSetAllocateInfo,需要指定要分配的描述符池、要分配的描述符集的数量(为每个帧都分配)以及它们所基于的描述符布局

vkAllocateDescriptorSets,不需要显式地清理描述符集,因为当描述符池被销毁时

描述符集现在已经分配完毕,但是仍然需要配置其中的描述符。我们现在将添加一个for循环来填充每个描述符

VkDescriptorBufferInfo,指定缓冲区以及其中包含描述符数据的区域

VkWriteDescriptorSet,

前两个字段指定要更新的描述符集和绑定,我们需要再次指定描述符的类型,descriptorCount可以一次更新数组中的多个描述符

pBufferInfo字段用于引用缓冲区数据的描述符,pImageInfo用于引用图像数据的描述符,pTexelBufferView用于引用缓冲区视图的描述符。

vkUpdateDescriptorSets

Using descriptor sets

需要更新recordCommandBuffer函数,通过vkCmdBindDescriptorSets将描述符集绑定到渲染管线的相应阶段,这样着色器就可以通过描述符来访问uniform buffer中的数据了,就像vertex buffer那样

参数是描述符所基于的布局。接下来的三个参数指定第一个描述符集的索引、要绑定的集的数量以及要绑定的集的数组

如果你现在运行你的程序,什么都看不到,由于我们在投影矩阵中做了Y翻转,现在顶点是按逆时针顺序绘制的,而不是顺时针顺序。这将导致背面剔除

VkGraphicsPipeline函数并修改VkPipelineRasterizationStatesInfo中的frontFace以更正此错误

Alignment requirements

vulkan要求结构中的数据以特定的方式在内存中对齐

  • 标量必须按N(= 4字节给定32位浮点数)对齐。

  • •vec2必须对齐2N(= 8字节)

  • •vec3或vec4必须对齐4N(= 16字节)

  • •嵌套结构必须按其成员的基本对齐方式对齐

  • 四舍五入到16的倍数。

  • •mat4矩阵必须与vec4具有相同的对齐方式。

比如在UniformBufferObject结构体加入glm::vec2 foo,它是8字节,而mat4是64字节

为了解决这个问题,我们可以使用C++11中引入的alignas说明符:例如alignas(16)表示偏移量为16的倍数

还有一种简单的方式,#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES,它会自动帮助我们对齐,(注意:对于嵌套结构不会正确计算,必须自己计算)

Multiple descriptor sets

实际上可以同时绑定多个描述符集。在创建管道布局时,您需要为每个描述符集指定一个描述符布局

然后通过这样的形式

layout(set = 0, binding = 0) uniform UniformBufferObject { ... }在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1575.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka存储机制大揭秘:从日志结构到清理策略的全面解析

文章目录 一、前言二、日志存储结构1.日志文件结构2.topic3.partition4.segment索引文件5.message结构6.message查找过程 三、存储策略1.顺序写2.页缓存3.零拷贝4.缓存机制 四、日志格式演变1.V0 版本2.V1 版本3.V0/V1消息集合4.V2 版本消息格式5.V2版本消息集合 五、偏移量维护…

基于OSS搭建在线教育视频课程分享网站

OSS对象存储服务是海量、安全、低成本、高持久的存储服务。适合于存储大规模非结构化数据,如图片、视频、备份文件和容器/虚拟机镜像等。 安装nginx wget https://nginx.org/download/nginx-1.20.2.tar.gz yum -y install zlib zlib-devel gcc-c pcre-devel open…

HCIA笔记整合

第一部分: OSI七层模型 应用层:人机交互 抽象语言--------编码 表示层:编码------二进制 会话层:提供会话号 传输层:TCP/UDP 分段(收到MTU值的限制) MTU:最大传输单元&#xff…

如何选择到印尼的海运代理

如何选择到印尼的海运代理 选择合适的海运代理的重要性 海运代理负责安排货物从发货地到目的地的整个运输过程,包括装运、清关、仓储等服务。一个可靠的海运代理能确保货物安全准时到达,并帮助企业节省时间和成本。 选择海运代理需考虑的主要因素 公司…

RK3588的QT交叉编译环境搭建

主要参考为RK3568或RK3288开发板创建交叉编译环境{采用amd64的ubuntu系统配置交叉编译arm64开发环境}(保姆级包括安装QT)超详细记录版_rk3568交叉编译-CSDN博客 先说一下,使用的Ubuntu20.04.5版本,qt源码用的5.14.2版本,交叉编译器使用RK3588…

【Linux】一些Shell脚本编程基础题

目录 一、比较两个数的大小 二、求1-100的素数和 三、编写shell脚本,输入一个数字n并计算1~n的和,同时要求如果输入的数字小于1,则重新输入,直到输入正确的数字为止。 四、编写一个shell脚本用来进行成绩等级评定,…

数据的表现形式(2)

汉字字形码 字形码也叫字模或汉字输出码。字形码是表示汉字字型信息的编码,用来实现计 算机对汉字的输出 如一个16*16点阵的字形码就需要16*16/8个字节的存储空间 二进制的运算 在定点二进制运算中,减法运算一般通过【补码运算的二进制加法器】 进制三要…

Vision - 开源视觉分割算法框架 Grounded SAM2 配置与推理 教程 (1)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/143388189 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Ground…

深度学习基础—语言模型和序列生成

引言 深度学习基础—循环神经网络(RNN)https://blog.csdn.net/sniper_fandc/article/details/143417972?fromshareblogdetail&sharetypeblogdetail&sharerId143417972&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 上…

leetcode-3-无重复字符的最长子串

题解: 1、初始化一个字典dic_hash{}。 2、初始化左指针i-1,右指针j为s的索引。 #3、初始化变量res1用3 2Q#来 |} 】、 代码:

readhat虚拟机基本操作

1.用cat显示/etc/passwd,并显示行号 2.在当前目录下创建空文件夹/web/test1 3.查看当前工作目录的命令 4.显示环境变量$PATH 5. 查看/tmp/目录的使用空间 6. 删除空目录old 要删除old,要先建立old目录---mkdir old,然后ls查看是否建立成功,再…

Java面试经典 150 题.P80. 删除有序数组中的重复项 II(004)

本题来自:力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解: class Solution {public int removeDuplicates(int[] nums)…

基尼指数(Gini Impurity)的理解和计算

基尼不纯度简介 - Gini Impurity - 吕汉鸿 - 博客园 先看上面这个博文!!!然后再看下面的,下面这个原博文有一点问题。已修正,修正后的完整内容如下 一、基尼指数的概念 基尼指数(Gini不纯度)…

《股市行情预测软件:开发之路的探索与挑战》

《股市行情预测软件:开发之路的探索与挑战》 一、股市行情预测软件的重要性二、开发所需技术(一)数据收集与处理技术(二)数据分析技术(三)算法选择与应用(四)编程语言与开…

整合全文检索引擎 Lucene 添加站内搜索子模块

整合全文检索引擎 Lucene: 添加站内搜索子模块 1. 什么是 Lucene ? 有啥优势? Lucene 是一个开源的全文检索引擎库,由 Apache 基金会维护,官网地址:https://lucene.apache.org/ 。它提供了丰富的文本处理和搜索功能&#xff0c…

OceanBase详解及如何通过MySQL的lib库进行连接

OceanBase详解及如何通过MySQL的lib库进行连接 一、引言二、OceanBase概述1. 起源与发展2. 核心技术特点3. 应用场景三、OceanBase架构解析1. 系统架构2. 存储引擎3. 分布式架构四、如何使用MySQL的lib库连接OceanBase1. 前提条件2. 安装MySQL Connector/C3. 编写连接代码4. 编…

104. UE5 GAS RPG 实现技能火焰爆炸

这一篇文章我们再实现一个技能火焰爆炸,由于我们之前已经实现了三个玩家技能,这一个技能有一些总结的味道,对于创建技能相同的部分,长话短说,我们过一遍。 准备工作 我们需要一个技能类,继承于伤害技能基…

【力扣打卡系列】验证二叉搜索树

坚持按题型打卡&刷&梳理力扣算法题系列,语言为go,Day17 验证二叉搜索树 题目描述 解题思路 前序遍历:先访问节点值,再访问左右子树有效二叉搜索树的定义 节点的左子树只包含小于当前节点的数节点的右子树只包含大于当前节…

Swarm-LIO: Decentralized Swarm LiDAR-inertial Odometry论文翻译

文章目录 前言一、介绍二、相关工作三、方法A. 问题表述B. 框架概述C. 群体系统的初始化D. 去中心化激光雷达-惯性状态估计 四. 实验A. 室内飞行B. 退化环境飞行C. 去中心化部署 五. 结论和未来工作 前言 原文:原文 准确的自我状态和相对状态估计是完成群体任务的关…

京东毫秒级热key探测框架JD-hotkey

前言 对任意突发性的,无法预先感知的热点数据,包括热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,一瞬间打到我们的服…